感兴趣的朋友可以去我的语雀平台进行查看更多的知识。
https://www.yuque.com/books/share/ffbf2b86-52af-4a4f-b144-507a890fb8dc?# 《木子Teng的计算机知识库》
7. webpack的使用
此次的vue搭建—创建一个基于webpack模板的vue应用程序—Vue2版本
7.1 安装
WebPack是一款模块加载器兼打包工具, 它能把各种资源, 如JS、JSX、ES 6、SASS、LESS、图片等都作为模块来处理和使用
npm install webpack -g
npm install webpack-cli -g
测试安装成功:
webpack -v
webpack-cli -v
配置:
- entry:入口文件, 指定Web Pack用哪个文件作为项目的入口
- output:输出, 指定WebPack把处理完成的文件放置到指定路径
- module:模块, 用于处理各种类型的文件
- plugins:插件, 如:热更新、代码重用等
- resolve:设置路径指向
- watch:监听, 用于设置文件改动后直接打包
module.exports = {
entry:"",
output:{
path:"",
filename:""
},
module:{
loaders:[
{test:/\.js$/,;\loade:""}
]
},
plugins:{},
resolve:{},
watch:true
}
直接运行webpack
命令打包
7.2 使用
在workspace中创建文件夹webpack-study,然后用IDE打开
创建一个名为modules的目录,用于放置JS模块等资源文件
在modules下创建模块文件hello.js
//暴露一个方法:sayHi
exports.sayHi = function(){
document.write("<div>Hello Webpack</div>");
}
在modules下创建一个名为main.js的入口文件main.js,用于打包时设置entry属性
//require 导入一个模块,就可以调用这个模块中的方法了
var hello = require("./hello");
hello.sayHi();
在项目目录下创建webpack.config.js配置文件,使用webpack命令打包
module.exports = {
entry:"./modules/main.js",
output:{
filename:"./js/bundle.js"
}
}
打包:直接输入webpack
即可
在项目目录下创建HTML页面,如index.html,导入webpack打包后的JS文件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Java And Vue</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>
</html>
直接打开index.html
注意:
# 参数--watch 用于监听变化,如果要打包的东西有变化,就重新打包
webpack --watch
8. Vue vue-router路由
8.1 安装
基于第一个vue-cli
进行测试学习; 先查看node modules中是否存在vue-router, vue-router是一个插件包, 所以我们还是需要用n
pm/yarn来进行安装的。
npm install vue-router --save-dev
如果在一个模块化工程中使用它,必须要通过Vue.use()
明确地安装路由功能
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
8.2 测试路由
- 删除第一个vue-cli项目中的没用的东西
components
目录下存放我们自己编写的组件- 定义几个自己的组件 Content.vue 、Main.vue、Teng.vue
Content.vue
<template>
<div>
<h1>内容页</h1>
</div>
</template>
Main.vue
<template>
<div>
<h1>首页</h1>
</div>
</template>
Teng.vue
<template>
<div>
<h1>Teng</h1>
</div>
</template>
安装路由,在src目录下,新建一个文件夹:router
,专门存放路由,配置路由index.js
import Vue from 'vue';
// 导入路由组件
import Router from 'vue-router';
// 导入上面自定义的组件
import Content from '../components/Content'
import Main from "../components/Main";
import Teng from "../components/Teng";
// 安装路由
Vue.use(Router);
// 配置路由
export default new Router({
routes: [
{
// 路由路径
path: '/content',
// 路由名称
name: 'content',
// 跳转到组件
component: Content
},
{
path: '/main',
name: 'main',
component: Main
},
{
path: '/teng',
name: 'teng',
component: Teng
}
]
});
在main.js
中配置路由
import Vue from 'vue'
import App from './App'
// 自动扫描里面的路由配置
import router from "./router";
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {App},
template: '<App/>'
})
在App.vue
中使用路由
<template>
<div id="app">
<!--
router-link:默认会被渲染成一个<a>标签,to属性为指定链接
router-view:用于渲染路由匹配到的组件
-->
<h1>木子Teng</h1>
<router-link to="/main">首页</router-link>
<router-link to="/content">内容</router-link>
<router-link to="/teng">木子Teng</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
components: {}
}
</script>
运行npm run dev,然后浏览器访问localhost:8080
9. 实战案例
9.1 创建工程
创建一个名为my-vue的工程
vue init webpack my-vue
安装依赖, vue-router、element-ui、sass-loader和node-sass四个插件
#进入工程目录
cd hello-vue
#安装vue-routern
npm install vue-router --save-dev
#安装element-ui
npm i element-ui -S
#安装依赖
npm install
# 安装SASS加载器
cnpm install sass-loader node-sass --save-dev
#启功测试
npm run dev
npm命令说明
npm install moduleName:安装模块到项目目录下
npm install -g moduleName:-g的意思是将模块安装到全局,具体安装到磁盘哪个位置要看npm config prefix的位置
npm install -save moduleName:–save的意思是将模块安装到项目目录下, 并在package文件的dependencies节点写入依赖,-S为该命令的缩写
npm install -save-dev moduleName:–save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写
9.2 创建登录页面
- 先把删除没用的文件
- 项目结构如下
说明:
- assets:用于存放资源文件
- components:用于存放Vue功能组件
- views:用于存放Vue视图组件
- router:用于存放vue-router配置
在views目录下创建首页视图Main.vue组件
<template>
<div>
<h1>主页</h1>
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
在views目录下创建登录页面视图Login.vue组件
<template>
<div>
<el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item label="账号" prop="username">
<el-input type="text" placeholder="请输入账号" v-model="form.username"/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('loginForm')">登录</el-button>
</el-form-item>
</el-form>
<el-dialog title="温馨提示" :visible.sync="dialogVisiable" width="30%" :before-close="handleClose">
<span>请输入账号和密码</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
form: {
username: '',
password: ''
},
//表单验证,需要在 el-form-item 元素中增加prop属性
rules: {
username: [
{required: true, message: "账号不可为空", trigger: "blur"}
],
password: [
{required: true, message: "密码不可为空", tigger: "blur"}
]
},
//对话框显示和隐藏
dialogVisible: false
}
},
methods: {
onSubmit(formName) {
//为表单绑定验证功能
this.$refs[formName].validate((valid) => {
if (valid) {
//使用vue-router路由到指定界面,该方式称为编程式导航
this.$router.push('/main');
} else {
this.dialogVisible = true;
return false;
}
});
}
}
}
</script>
<style scoped>
.login-box {
border: 1px solid #DCDFE6;
width: 350px;
margin: 180px auto;
padding: 35px 35px 15px 35px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
.login-title {
text-align: center;
margin: 0 auto 40px auto;
color: #303133;
}
</style>
在router目录下创建一个名为index.js
的vue-router路由配置文件
import Vue from 'vue';
// 导入路由组件
import VueRouter from 'vue-router';
// 导入上面自定义的组件
import Main from "../views/Main";
import Login from "../views/Login";
// 安装路由
Vue.use(VueRouter);
// 配置路由
export default new VueRouter({
routes: [{
// 登录页
path: '/login', component: Login
}, {
// 首页
path: '/main', component: Main
}]
});
编写 APP.vue
<template>
<div id="app">
<!-- <router-link to="/login">登录页</router-link>-->
<!-- <router-link to="/main">主页</router-link>-->
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
在main.js
中配置路由
import Vue from 'vue'
import App from './App'
// 自动扫描里面的路由配置
import router from "./router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
render: h => h(App)
})
测试npm run dev
9.3 路由嵌套
嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成
- 创建用户信息组件,在 views/user 目录下创建一个名为 Profile.vue 的视图组件
<template>
<h1>个人信息</h1>
</template>
<script>
export default {
name: "Profile"
}
</script>
<style scoped>
</style>
- 在用户列表组件在 views/user 目录下创建一个名为 List.vue 的视图组件
<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "List"
}
</script>
<style scoped>
</style>
- 修改首页视图,我们修改Main.vue视图组件,此处使用了 ElementUI 布局容器组件
<template>
<div>
<el-container>
<el-aside width="200px">
<el-menu :default-openeds="['1']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<!--插入的地方-->
<router-link to="/user/profile">个人信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<!--插入的地方-->
<router-link to="/user/list">用户列表</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
<el-menu-item-group>
<el-menu-item index="2-1">分类管理</el-menu-item>
<el-menu-item index="2-2">内容列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-header>
<el-main>
<!--在这里展示视图-->
<router-view/>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
- 添加了组件,去router修改配置文件
import Vue from 'vue';
// 导入路由组件
import VueRouter from 'vue-router';
// 导入上面自定义的组件
import Main from "../views/Main";
import Login from "../views/Login";
import List from "../views/user/List";
import Profile from "../views/user/Profile";
// 安装路由
Vue.use(VueRouter);
// 配置路由
export default new VueRouter({
routes: [{
// 登录页
path: '/login', component: Login
}, {
// 首页
path: '/main', component: Main,
// 子路由
children: [
{
path: '/user/profile',
component: Profile
},
{
path: '/user/List',
component: List
}
]
},
]
});
运行测试
9.4 参数传递和重定向
9.4.1 参数传递
方法一
- 修改路由配置, 主要是router下的index.js中的 path 属性中增加了 :id 这样的占位符
{
path: '/user/profile/:id',
name: 'Profile',
component: Profile
}
- 视图层传递参数
<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name: 'Profile', params:{id:1}}">个人信息</router-link>
说明: 此时我们在Main.vue中的route-link位置处to 改为了 :to,是为了将这一属性当成对象使用,注意router-link中的 name属性名
称一定要和路由中的name属性名称匹配,因为这样Vue才能找到对应的路由路径。
- 接收参数
<template>
<!-- 所有的元素必须在根节点下-->
<div>
<h1>个人信息</h1>
{{$route.params.id}}
</div>
</template>
说明:所有的元素必须在根节点下面,否则会报错
测试
方法二 使用props 减少耦合
- 修改路由配置 , 主要在router下的index.js中的路由属性中增加了 props: true 属性
{
path: '/user/profile/:id',
name: 'Profile',
component: Profile,
props: true
}
- 传递参数和之前一样
- 在Profile.vue接收参数为目标组件增加 props 属性
<template>
<div>
<h1>个人信息---利用props</h1>
{{ id }}
</div>
</template>
<script>
export default {
name: "Profile",
props: ['id']
}
</script>
测试
9.4.2 重定向
Vue中的重定向是作用在路径不同但组件相同的情况
- 在router/index.js配置重定向路径
{
// 首页
path: '/main',
component: Main,
},
{
path: '/goHome',
// 重定向
redirect: '/main'
}
- 视图增加
<el-menu-item index="1-3">
<router-link to="/goHome">返回首页</router-link>
</el-menu-item>
9.5 路由模式、404和路由钩子
9.5.1 路由模式
路由模式有两种
- hash:路径带 # 符号,如 http://localhost/#/login
- history:路径不带 # 符号,如 http://localhost/login
修改路由配置
export default new VueRouter({
mode:'history',
routes: []
)}
测试:
9.5.2 404页面
- 创建一个NotFound.vue视图
<template>
<div>
<h1>404,你的页面走丢了</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
- 修改路由配置index.js
import NotFound from '../views/NotFound'
{
path: '*',
component: NotFound
}
测试
9.5.3 路由钩子
除了之前的钩子函数还存在两个钩子函数
beforeRouteEnter
:在进入路由前执行beforeRouteLeave
:在离开路由前执行
在Profile.vue使用
<script>
export default {
name: "Profile",
props: ['id'],
beforeRouteEnter: (to, from, next) => {
console.log("准备进入个人信息页");
next();
},
beforeRouteLeave: (to, from, next) => {
console.log("准备离开个人信息页");
next();
}
}
</script>
参数说明:
to:路由将要跳转的路径信息
from:路由跳转前的路径信息
next:路由的控制参数
next(): 跳入下一个页面
next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
next(false) 返回原来的页面
next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例
测试:
在钩子函数中进行异步请求
- 安装Axios
npm install --save vue-axios
- main.js引用 Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
- 准备数据
{
"name": "木子Teng",
"url": "https://blog.csdn.net/qq_45408390?spm=1001.2101.3001.5343",
"page": 1,
"isNonProfit": true,
"address": {
"street": "含光门",
"city": "河南郑州",
"country": "中国"
},
"links": [
{
"name": "bilibili",
"url": "https://bilibili.com"
},
{
"name": "木子Teng",
"url": "https://blog.csdn.net/qq_45408390?spm=1001.2101.3001.5343"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
说明: 只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下
- 在 beforeRouteEnter 中进行异步请求
<script>
export default {
name: "Profile",
props: ['id'],
beforeRouteEnter: (to, from, next) => {
console.log("准备进入个人信息页");
next(vm => {
// 进入路由之前执行getData()方法
vm.getData()
});
},
beforeRouteLeave: (to, from, next) => {
console.log("准备离开个人信息页");
next();
},
// axios
methods: {
getData: function () {
this.axios({
method: 'get',
url: 'http://localhost:8080/static/mock/data.json'
}).then(response => {
console.log(response)
})
}
}
}
</script>
测试