Vue知识点整理
一、Vue核心知识
(一)第一个vue网页
- 1.引包
- 确认已经下载了node,然后执行命令 npm install vue (如需下载自己要的版本在vue后面加上@版本号)
- 页面引入刚下载的包
<script type="text/javascript" src="vue.js"></script>
- 2.留坑 即留一个vue模板插入的地方或者是vue代码对其生效的地方
- 3.实例化 即启动Vue
启动: new Vue({el:目的地,template:模板内容});实例化传入的是一个对象options
options- 目的地 el 对应上面留坑的坑位,可通过id名,类名,标签名来查找 。方式和jq一样
- 内容 template
- 数据 data 值为函数形式也可是对象,但是都是用函数,因为用的函数最后也是return一个对象
- 4.插值表达式{{ }}
插值表达式内填入data里面的变量即可在页面取到变量值{{ data里的变量 }}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!-- 留坑 -->
<div id="app"></div>
<!-- 引包 -->
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
// 实例化启动vue
new Vue({
el:'#app',//目的的,可以识别类名、id名和标签名,如果做到极致优化可以直接用document.getElementById获取
template:`
<div>
<div>我这里是模板内容{{ msg }}</div>
<div>111</div>
</div>
`,//模板内容,根节点只能有一个
data:function(){
return {
msg:'Hello Vue!'
}
}
})
</script>
</body>
</html>
(二)常用指令
1.什么是指令
在vue中提供一些对于页面+数据的更为方便的操作,这些操作就叫做指令。
譬如在HTML页面中这样使用
<div v-xxx=''></div>
在vue中v-xxx就是vue的指令。指令就是以数据去驱动DOM行为的,简化DOM操作
2. 常用的指令有哪些,及怎么使用这些指令
- v-text 不可解析html标签
- v-html 可解析html标签
- v-if 做元素的插入(append)和移除(remove)操作
- v-else-if
- v-else
- v-show display:none 和display:block的切换
- v-for
数组 item,index
对象 value,key ,index
实例
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
template:`
<div>
<!--测试v-text-->
<div v-text='mytext'></div>
</hr>
<!--测试v-html-->
<div v-html='myhtml'></div>
<!--测试v-if v-else-if v-else-->
<button v-if='num==1'>测试v-if</button>
<button v-else-if='num==2'>测试v-else-if</button>
<button v-else>测试v-else</button>
<!--测试v-show-->
<div v-show='checkshow'>我是V-SHOW</div>
<!--循环数组-->
<ul>
<li v-for='(item,index) in arrayfor'>
{{ item }}-{{index}}
</li>
</ul>
<ul>
<!--循环对象-->
<li v-for='(oj,key) in ojfor'>
{{key}}:{{oj}}
</li>
</ul>
</div>
`,
data:function(){
return {
mytext:'<h1>我这里是v-text</h1>',
myhtml:'<h1>我这里是v-html</h1>',
checkvif:true,
num:6,
checkshow:true,
arrayfor:['篮球','足球','乒乓球'],
ojfor:{play:'篮球',people:'ming',age:'19'}
}
}
})
</script>
</body>
</html>
(三)vue单双向数据流及事件绑定
1. vue单向数据流绑定属性值 v-bind: (属性) 简写 :(属性)
例子:
< input v-bind:value="name" v-bind:class="name">
单向数据绑定 内存改变影响页面改变
v-bind就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染
2. vue双向数据流 v-model 只作用于有value属性的元素
例子:
<input v- model="name" v-bind:class="name">
双向数据绑定 页面对于input的value改变,能影响内存中name变量
内存js改变name的值,会影响页面重新渲染最新值
3. 事件绑定v-on:事件名=“表达式||函数名” 简写 @事件名="表达式||函数名"
事件名可以是原生也可以是自定义的
4. 总结
v-model 双向数据绑定
vue页面改变影响内存(js) 内存(js)改变影响vue页面
v-bind 单向数据绑定只是内存(js)改变影响vue页面
实例
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
console.log(this)
new Vue({
el:"#app",
template:`
<div>
单向数据绑定
<input type='text' v-bind:value="name" :class="name"><br>
双向数据绑定
<input type='text' v-model="name"></br>
{{ name }}
<button v-on:click="change">点击我改变name变量</button>
</div>
`,
data:function(){
return {
name:'hello'
}
},
methods:{
change:function(){
console.log(this)
this.name='我改变了,是在方法属性里面定义的方法'
},
}
})
</script>
</body>
</html>
(四)过滤器
- 过滤器就是可以对我们的数据进行添油加醋然后再显示
- 过滤器有全局过滤器和组件内的过滤器
- 全局过滤器Vue.filter(‘过滤器名’,过滤方式fn );
- 组件内的过滤器 filters:{ ‘过滤器名’,过滤方式fn }
- {{ msg | 过滤器名}}
- 最终都是在过滤方式fn里面return产出最终你需要的数据
- vue中的this是vue封装好给我们使用的,跟平常方法里面的this是不同的
实例
<!DOCTYPE html>
<html>
<head>
<title>过滤器</title>
</head>
<body>
<div id="app">
我输入的:<input type="text" name="" v-model='instring'></br>
我输出的:{{ instring }}</br>
{{ instring | reversal('翻转输出:')}}
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
console.log(this)
Vue.filter('reversal', function(val, arg2) {
return arg2 + val.split('').reverse().join('')
})
new Vue({
el: '#app',
data() {
return {
instring: ''
}
},
created() {
console.log(this, 'vue的')
}
// filters:{
// reversal(val,arg2){
// // 字符串转数组 翻转 数组转字符串
// return arg2+val.split('').reverse().join('')
// }
// }
})
</script>
</body>
</html>
(五)数据监听watch和计算属性computed
- watch监听单个,computed监听多个
思考业务场景:
1.类似淘宝,当我输入某个人名字时,我想触发某个效果
2.利用vue做一个简单的计算器 - 当watch监听的是复杂数据类型的时候需要做深度监听(写法如下)
watch:{
msg:{
handler(val){
if(val.text=='love'){
alert(val.text)
}
},
deep:true//开启深度监听
}
}
- computed 监视对象,写在了函数内部, 凡是函数内部有this.相关属性,改变都会触发当前函数
实例
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
<div>watch监听数据</div>
<input type="text" name="" v-model='msg.text'>
<div>computed计算属性</div>
(<input type="text" name="" v-model='n1'>+
<input type="text" name="" v-model='n2'>)*
<input type="text" name="" v-model='n3'>={{result}}
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
data(){
return {
msg:{text:''},
n1:'',
n2:'',
n3:'1'
}
},
computed:{
result(){
return (Number(this.n1)+Number(this.n2))*Number(this.n3)
}
},
watch:{
// msg(newval,oldval){
// if(newval.text=='love'){
// alert(newval.text)
// }
// }
msg:{
handler(newval,oldval){
if(newval.text=='love'){
alert(newval.text)
}
},
deep:true
}
}
})
</script>
</body>
</html>
二、组件化开发
(一)组件
创建组件的两种方式
- var Header = { template:‘模板’ , data是一个函数,methods:功能,components:子组件们 }//局部声明
- Vue.component(‘组件名’,组件对象);//全局注册 等于注册加声明了
组件类型
- 通用组件(例如表单、弹窗、布局类等)
- 业务组件(抽奖、机器分类)
- 页面组件(单页面开发程序的每个页面的都是一个组件、只完成功能、不复用)
组件开发三步曲:声明、注册、使用
实例
<!DOCTYPE html>
<html>
<head>
<title>组件化开发</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
var MyHeader={
template:`
<div>我是头部</div>
`,
}
var MyBody=Vue.extend({
template:`
<div>我是身体</div>
`
})
//这个是语法糖
// var MyBody={
// template:`
// <div>我是身体</div>
// `
// }
Vue.component('MyFooter',{
template:`
<div>我是尾部</div>
`
})
new Vue({
el:'#app',
//注册组件
components:{
MyHeader,
MyBody
},
template:`
<div>
<my-header></my-header>
<my-body></my-body>
<my-footer></my-footer>
</div>
`,
data(){
return{}
},
})
</script>
</body>
</html>
(二)slot插槽和ref、$parent
-
slot插槽
- slot就是子组件里给DOM留下的坑位
- <子组件>DOM</子组件>
- slot是动态的DOM
-
ref获取子组件实例
- 识别:在子组件或元素上使用属性ref=“xxxx”
- 获取:this.$refs.xxxx 获取元素
- $el 是拿其DOM
-
$ parent获取父组件实例(可在子组件直接使用this.$ parent即可)(需要把空格去掉,编辑器语法有冲突)
示例
<!DOCTYPE html>
<html>
<head>
<title>组件化开发</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
var Child = {
template: `
<div>我是子组件</div>
`,
data() {
return {
msg: "hello",
};
},
created() {
console.log(this.$parent);
},
};
var Parent = {
template: `
<div>
我是父组件
<slot name='hello'></slot>
<child ref='childs'></child>
</div>
`,
components: {
Child,
},
data() {
return {
parents: "我是父组件哈哈哈",
};
},
mounted() {
// console.log(this.$refs.childs)
},
};
new Vue({
el: "#app",
components: {
Parent,
},
template: `
<div>
<parent>
<div>我是插槽内容</div>
<div slot='hello'>我是插槽内容2</div>
</parent>
</div>
`,
data() {
return {};
},
});
</script>
</body>
</html>
(三)父子组件的通信
父传子
- 父用子的时候通过属性传递
- 子要声明props:[‘属性名’] 来接收
- 收到就是自己的了,随便你用
- 在template中直接用
- 在js中 this.属性名 用
子传父
- 子组件里通过$ emit(‘自定义事件名’,变量1,变量2)触发
- 父组件@自定义事件名=‘事件名’监听
- 子组件方法里 this.$emit(‘sendfather’,val1,val2)触发自定义事件 父组件里
<child @sendfather='mymethods'></child>
示例
<!DOCTYPE html>
<html>
<head>
<title>父子组件的通信</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
//子组件定义好了props直接用
var Child={
template:`
<div>
我是子组件{{sendchild}}
<button @click='sendparent'>我要反馈东西给父亲</button>
</div>
`,
props:['sendchild'],
methods:{
sendparent(){
this.$emit('baba','这是儿子组件给你的')
}
}
}
//父组件通过属性sendchild传递了数据给子组件
var Parent={
template:`
<div>
我是父组件{{ msg }}
<child sendchild='父亲给你的' @baba='reserve'></child>
</div>
`,
components:{
Child
},
data(){
return {
msg:''
}
},
methods:{
reserve(val){
this.msg=val
}
}
}
new Vue({
el:'#app',
components:{
Parent
},
template:`
<div>
<parent></parent>
</div>
`,
data(){
return {
}
},
})
</script>
</body>
</html>
(四)非父子组件之间的通信
- 创建一个空实例(bus中央事件总线也可以叫中间组件)
- 利用$ emit $ on的触发和监听事件实现非父子组件的通信
Vue.prototype.$ bus=new Vue()//在vue上面挂载一个$ bus作为中央处理组件
this.$ bus.$ emit(‘自定义事件名’,‘传递的数据’)//触发自定义事件传递数据
this.$ bus.$on(‘自定义事件名’,fn)//监听自定义事件获取数据 - 解决的方案还有vuex、provide/inject是解决同根往下派发、本地存储也可以进行非父子组 件之间的通信
示例
<!DOCTYPE html>
<html>
<head>
<title>非父子组件的通信</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
Vue.prototype.$bus=new Vue()
var MyHeader={
template:`
<div>
我是头部
{{ headermsg }}
</div>
`,
data(){
return {
headermsg:'我是头部的信息'
}
},
created(){
// var self=this
// self.$bus.$on('sending',function(val){
// self.headermsg=val
// })
this.$bus.$on('sending',val=>{
this.headermsg=val
})
}
}
var MyBody={
template:`
<div>我是身体</div>
`,
}
var MyFooter={
template:`
<div>我是底部<button @click='sendhead'>我要跟头部通信</button></div>
`,
methods:{
sendhead(){
this.$bus.$emit('sending','我是底部的数据')
}
}
}
new Vue({
el:'#app',
components:{
MyHeader,
MyBody,
MyFooter
},
template:`
<div>
<my-header></my-header><hr>
<my-body></my-body><hr>
<my-footer></my-footer>
</div>
`,
data(){
return {}
},
})
</script>
</body>
</html>
(五)生命周期
- 需要频繁的创建和销毁组件
比如页面中部分内容显示与隐藏,但是用的是v-if - 组件缓存
- 内置组件中
- 被其包裹的组件,在v-if=false的时候,不会销毁,而是停用
- v-if=“true” 不会创建,而是激活
- 避免频繁创建组件对象的性能损耗
- 成对比较
- activated 和 deactivated
组件的激活和停用 - created 和 beforeCreate
A 可以操作数据 B 数据没有初始化 - mounted 和 beforeMount
A 可以操作DOM B 还未生成DOM - updated 和 beforeUpdate
A 可以获取最终数据 B 可以二次修改 - destroyed 和 beforeDestroy
性能调优:频繁销毁创建的组件使用内置组件包裹
实例main.js文件
- activated 和 deactivated
// created 和 beforeCreate
// A 可以操作数据 B 数据没有初始化
// mounted 和 beforeMount
// A 可以操作DOM B 还未生成DOM
// updated 和 beforeUpdate
// A 可以获取最终数据 B 可以二次修改
// destroyed 和 beforeDestroy
var Test={
template:`
<div>我是Test组件{{ msg }}
<button @click="msg+='1'">msg+1</button>
</div>
`,
data(){
return{
msg:'HELLO VUE'
}
},
//组件创建前
beforeCreate(){
console.log('组件创建前')
console.log(this.msg)
},
//组件创建后
created(){
console.log('组件创建后')
console.log(this.msg)
},
//Dom挂载前
// beforeMount(){
// console.log('Dom挂载前')
// console.log(document.body.innerHTML)
// },
// //Dom挂载后
// mounted(){
// console.log('Dom挂载后')
// console.log(document.body.innerHTML)
// }
//基于数据更新前
beforeUpdate(){
console.log('数据更新前')
console.log(document.body.innerHTML)
},
//基于数据更新后
updated(){
console.log('数据更新后')
console.log(document.body.innerHTML)
},
//销毁前
beforeDestroy(){
console.log('销毁前')
},
//销毁后
destroyed(){
console.log('销毁后')
},
//组件停用
deactivated(){
console.log('组件停用')
},
//组件激活
activated (){
console.log('组件激活')
}
}
new Vue({
el:'#app',
components:{
Test
},
template:`
<div>
<keep-alive><test v-if='testshow'></test></keep-alive></br>
<button @click='clickbut'>销毁组件</button>
</div>
`,
data(){
return {
testshow:true
}
},
methods:{
clickbut(){
this.testshow=!this.testshow
}
}
})
三、Vue核心插件之路由
(一)路由的跳转原理
- 单页应用的路由模式有两种
哈希模式(利用hashchange 事件监听 url的hash 的改变)
history模式(使用此模式需要后台配合把接口都打到我们打包后的index.html上) - 哈希模式原理
window.addEventListener(‘hashchange’, function(e) { console.log(e)
}) - 核心是锚点值的改变,我们监听到锚点值改变了就去局部改变页面数据,不做跳转。跟传统开发模式url改变后立刻发起请求,响应整个页面,渲染整个页面比路由的跳转用户体验更好
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<a href="#/login">登录</a>
<a href="#/register">注册</a>
<div id="app"></div>
<script type="text/javascript">
var appdiv=document.getElementById('app')
window.addEventListener('hashchange', function(e) {
console.log(location.hash)
switch(location.hash){
case '#/login':
appdiv.innerHTML='我是登录页面';
break;
case '#/register':
appdiv.innerHTML='我是注册页面';
break;
}
})
</script>
</body>
</html>
(二)路由安装和使用
1:下载 npm i vue-router -S
2:安装插件
Vue.use(VueRouter);
3:创建路由对象 var router = new VueRouter();
4:配置路由规则 router.addRoutes([路由对象]);
路由对象
{path:‘锚点值’,component:要(填坑)显示的组件}
5:将配置好的路由对象交给Vue
在options中传递-> key叫做 router
6:留坑(使用组件)
<router-view></router-view>
示例
<!DOCTYPE html>
<html>
<head>
<title>路由的安装和使用</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<!-- 引入路由插件 -->
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript">
var Login={
template:`
<div>我是登录页面</div>
`,
}
//安装路由插件
Vue.use(VueRouter);
//创建路由对象
var router= new VueRouter({
//配置路由对象
routes:[
{path:'/login',name:'login',component:Login}
]
})
new Vue({
el:'#app',
router,
template:`
<div>
<p>请在链接上加上login测试路由功能</p>
<router-view></router-view>
</div>
`,
data(){
return {}
},
})
</script>
</body>
</html>
(三)路由的跳转
路由的跳转方式有:
- 通过标签:
<router-link to='/login'></router-link>
- 通过js控制跳转
this.$router.push({path:’/login’})
区别:
this.$ router.push() 跳转到指定的url,会向history插入新记录
this.$ router.replace() 同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,会跳转到上上一个页面。上一个记录是不存在的。
this.$router.go(-1) 常用来做返回,读history里面的记录后退一个
vue-router中的对象:
- $route 路由信息对象,只读对象
- $router 路由操作对象,只写对象
示例
<!DOCTYPE html>
<html>
<head>
<title>路由的跳转</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<!-- 引入路由插件 -->
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript">
var Login={
template:`
<div>我是登录页面</div>
`,
}
var Register={
template:`
<div>我是注册页面</div>
`,
}
var Buy={
template:`
<div>我要买东西</div>
`,
}
//安装路由插件
Vue.use(VueRouter);
//创建路由对象
var router= new VueRouter({
//配置路由对象
routes:[
{path:'/login',name:'login',component:Login},
{path:'/register',name:'register',component:Register},
{path:'/buy',name:'buy',component:Buy},
]
})
new Vue({
el:'#app',
router,
template:`
<div>
<router-link to='/login'>去登录</router-link>
|
<router-link to='/register'>去注册</router-link>
<div>
<button @click='goregister'>我要去买东西</button>
<button @click='back'>返回上一页</button>
</div>
<router-view></router-view>
</div>
`,
data(){
return {}
},
methods:{
goregister(){
//push跟replace是达到同样效果,但是replace是不会向history插入记录
// this.$router.push({path:'/register'})
this.$router.replace({path:'/buy'})
},
back(){
this.$router.go(-1)
}
}
})
</script>
</body>
</html>
(四)路由的传参和取参
1.查询参
- 配置(传参) :to="{name:‘login’,query:{id:loginid}}"
- 获取(取参) this.$route.query.id
2.路由参数 - 配置(传参) :to="{name:‘register’,params:{id:registerid} }"
- 配置路由的规则 { name:‘detail’,path:’/detail/:id’}
- 获取 this.$route.params.id
总结: - :to传参的属性里 params是和name配对的 query和name或path都可以
- 使用路由参数必须要配置路由规则里面配置好参数名,否则刷新页面参数会丢失
示例
<!DOCTYPE html>
<html>
<head>
<title>路由的跳转</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<!-- 引入路由插件 -->
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript">
var Login={
template:`
<div>我是登录页面
<span>这是我获取到的参数: {{ msg }}</span>
</div>
`,
data(){
return {
msg:''
}
},
created(){
this.msg=this.$route.query.id
}
}
var Restiger={
template:`
<div>我是注册页面
<span>这是我获取到的路由参数:{{ foo }}</span>
</div>
`,
props:['foo']
// data(){
// return {
// restigerfoo:''
// }
// },
// created(){
// this.restigerfoo=this.$route.params.foo
// }
}
//安装路由插件
Vue.use(VueRouter);
//创建路由对象
var router= new VueRouter({
//配置路由对象
routes:[
{path:'/login',name:'login',component:Login},
{path:'/restiger/:foo',name:'restiger',props:true, component:Restiger},
]
})
new Vue({
el:'#app',
router,
template:`
<div>
<router-link :to="{name:'login',query:{id:'123'}}">去登录</router-link>
|
<router-link :to="{name:'restiger',params:{foo:'bar'}}">去注册</router-link>
<button @click='jslink'>js跳转去登录</button>
<router-view :key="$route.fullPath"></router-view>
</div>
`,
data(){
return {}
},
methods:{
//js跳转传参是一样的
jslink(){
this.$router.push({name:'login',query:{id:'456'}})
}
}
})
</script>
</body>
</html>
(五)嵌套路由
补充知识点:js跳转路由传参和标签传参,路由相同而参数不同时页面不做刷新的问 题
解决方案:
<router-view :key="$route.fullPath"></router-view>
代码思想
1:router-view的细分
router-view第一层中,包含一个router-view
2:每一个坑挖好了,要对应单独的组件
路由配置
routes: [
{
path:’/nav’,
name:‘nav’,
component:Nav,
//路由嵌套增加此属性
children:[
//在这里配置嵌套的子路由
]
}
]
案例
进入首页下面会有导航,个人中心、首页、资讯、我的之类的
示例
<!DOCTYPE html>
<html>
<head>
<title>路由的跳转</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<!-- 引入路由插件 -->
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript">
var Nav={
template:`
<div>
<router-view></router-view>
<router-link :to="{name:'nav.index'}">首页</router-link>
|
<router-link :to="{name:'nav.pensonal'}">个人中心</router-link>
|
<router-link :to="{name:'nav.message'}">资讯</router-link>
|
<router-link :to="{name:'nav.mine'}">我的</router-link>
</div>
`,
}
var Index={
template:`
<div>首页</div>
`,
}
var Pensonal={
template:`
<div>个人中心</div>
`,
}
var Message={
template:`
<div>资讯</div>
`,
}
var Mine={
template:`
<div>我的</div>
`,
}
//安装路由插件
Vue.use(VueRouter);
//创建路由对象
var router= new VueRouter({
//配置路由对象
routes:[
{
path:'',
redirect:'/nav'
},
{
path:'/nav',
name:'nav',
component:Nav,
//嵌套路由增加这个属性
children:[
//配置我们的嵌套路由
{path:'',redirect:'/nav/index'},
{path:'index',name:'nav.index',component:Index},
{path:'pensonal',name:'nav.pensonal',component:Pensonal},
{path:'message',name:'nav.message',component:Message},
{path:'mine',name:'nav.mine',component:Mine},
]
}
]
})
new Vue({
el:'#app',
router,
template:`
<div>
<router-view></router-view>
</div>
`,
data(){
return {}
},
methods:{
}
})
</script>
</body>
</html>
(六)路由守卫
const router = new VueRouter({ … }
//前置的钩子函数 最后要执行next()才会跳转
router.beforeEach((to, from, next) => {
// …
})
//后置的钩子函数 已经跳转了不需要next router.afterEach((to, from) => {
// …
})
路由守卫主要用于检验是否登录了,没登录就跳转到登录页面不让他 在其他页面停留,但是现在这种处理主要的都用请求的全局拦截来做了。大致了解一下路由 守卫即可