一、初始Vue
引入Vue依赖
<script src="../js/vue.js"></script>
创建一个Vue实例,且要传入一个配置对象
new Vue({
//el用于指定当前Vue实例为哪个容器服务,但通常为css选择器字符串
el: '#root',
data: {
//data用于存储数据,供el指定的容器使用
name: 'MyCode'
}
})
构建一个容器,打开网页,页面展示Hello,MyCode
<div id="root">
<h1>Hello,{{name}}</h1>
</div>
注意
1.Vue实例和容器是一一对应的;
2.{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
3.一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
二、Vue模板语法
1.插值语法:
功能:用于解析标签体内容。
写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
<h1>你好,{{name}}</h1>
2.指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。
举例:v-bind:href="xxx" 或 简写为 :href="xxx",xxx同样要写js表达式,且可以直接读取到data中的所有属性。
<a v-bind:href="url">百度</a>
<!-- v-bind可以简写成冒号 -->
<a :href="url">百度1</a>
三、数据绑定
单向绑定(v-bind):数据只能从data流向页面
<input type="text" v-bind:value="name">
双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
<input type="text" v-model:value="name">
注意
1.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
2.双向绑定一般都应用在表单类元素上(如:input、select等)
3.v-model只能应用在表单类元素(输入类元素)上
四、el和data的写法
第一种el写法
new Vue({ el: '#root', data: { name: 'MyCode' } })
第二种el写法
new Vue({ data: { name: 'MyCode' } }).$mount('#root')
第一种data对象式写法
new Vue({ data: { name: 'MyCode' } }).$mount('#root')
第二种data函数式写法
new Vue({ data: function () { return { name: 'MyCode' } } }).$mount('#root')
//简写
new Vue({ data() { return { name: 'MyCode' } } }).$mount('#root')
注意
由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
五、MVVM模型
MVVM模型
1. M:模型(Model) :data中的数据
2. V:视图(View) :模板代码
3. VM:视图模型(ViewModel):Vue实例
观察发现:
1.data中所有的属性,最后都出现在了vm身上。
2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
六、数据代理
1.Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:更加方便的操作data中的数据
3.基本原理:通过Object.defineProperty()把data对象中所有属性添加到vm上。为每一个添加到vm上的属性,都指定一个getter/setter。在getter/setter内部去操作(读/写)data中对应的属性。
七、事件处理
7.1 事件的基本使用
使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
<button v-on:click="show">点我</button>
<button @click="show">点我</button>
事件的回调需要配置在methods对象中,最终会在vm上;
new Vue({ el: '#root', methods: { show() { alert('你好') } } })
@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参;
<button @click="show($event,66)">点我</button>
new Vue({ el: '#root', methods: { show(event, arg) { alert(arg) } } })
注意:methods中配置的函数,不要用箭头函数!否则this就不是vm了
7.2 事件修饰符
prevent:阻止默认事件(常用)
<a href="http://www.baidu.com" @click.prevent="show">点我</a>
new Vue({ el: '#root', methods: { show() { alert(66) } } })
stop:阻止事件冒泡(常用)
<div class="box" @click="show"><button @click.stop="show">点我</button></div>
once:事件只触发一次(常用)
<button @click.once="show">点我</button>
capture:使用事件的捕获模式;默认先从外到里捕获事件,在从里到外响应事件,使用这个属性可以在捕获阶段就响应事件,如例子,先box1事件,然后是box2事件
<div class="box1" @click.capture="show(1)">
<div class="box2" @click="show(2)"></div>
</div>
self:只有event.target是当前操作的元素时才触发事件
<div class="box1" @click.self="show">
<button @click="show">点我</button>
</div>
在没有self属性,当点击button由于冒泡,会触发两次button事件(第二次不是div事件);加self属性,只会触发一次
passive:事件的默认行为立即执行,无需等待事件回调执行完毕(了解)
事件也可以写多个
<button @click.passive.stop="show">点我</button>
7.3 键盘事件
Vue中常用的按键别名:
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用)
上 => up
下 => down
左 => left
右 => right系统修饰键(用法特殊):ctrl、alt、shift、meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
<input type="text" placeholder="按下回车提示输入" @keyup.enter="show">
new Vue({ el: '#root', methods: { show(e) { console.log(e.target.value) } } })
Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
<input type="text" placeholder="按下回车提示输入" @keyup.caps-lock="show">
可以使用keyCode去指定具体的按键(不推荐)
<input type="text" placeholder="按下回车提示输入" @keyup.13="show">
Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名(不推荐)
Vue.config.keyCodes.huiche = 13
<input type="text" placeholder="按下回车提示输入" @keyup.huiche="show">
技巧:按下ctrl+y才提示
<input type="text" placeholder="按下回车提示输入" @keyup.ctrl.y="show">
八、计算属性
get被调用的时机:1.初次读取fullName 2.所依赖的数据发生改变的时候
计算属性有缓存的
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三'
},
computed: {
fullName: {
//读取fullName,get会被调用,且返回值就作为fullName的值
get() {
return this.firstName + "-" + this.lastName
}
}
}
})
在标签读取值
<div id="root">
姓:<input type="text" v-model="firstName"> <br>
名:<input type="text" v-model="lastName"> <br>
姓名:<span>{{fullName}}</span>
</div>
修改计算属性,set不是必须写
computed: {
fullName: {
//读取fullName,get会被调用,且返回值就作为fullName的值
get() {
return this.firstName + "-" + this.lastName
},
//fullName被修改时调用
set(value) {
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
计算属性的简写(只考虑读取,不考虑修改)
computed: {
fullName() {
return this.firstName + '-' + this.lastName
}
}
九、监视属性
Vue监视属性的变化使用watch
watch: {isHot: {
//isHot发生改变时调用
handler(newValue, oldValue) {
console.log('isHot改变了', newValue, oldValue)
}
}
}
Vue监视的第二种写法
const vm = new Vue({ data: { isHot: true } })
vm.$watch('isHot', { handler(newValue, oldValue) { console.log('isHot改变了', newValue, oldValue) } })
Vue监视多级结构某个属性的改变
new Vue({data: { numbers: { a: 1, b: 2 } },
watch: {
'numbers.a': {
//isHot发生改变时调用
handler(newValue, oldValue) {
console.log('a改变了', newValue, oldValue)
}
}
}
})
Vue开启深度监视,默认不开启
new Vue({
data: { numbers: { a: 1, b: 2 } },
watch: {
numbers: {
deep: true,
handler(newValue, oldValue) {
console.log('a改变了', newValue, oldValue)
}
}
}
})
Vue监视的简写
new Vue({
data: { number: 1 },
watch: {
number(newValue, oldValue) {
console.log('number改变了', newValue, oldValue)
}
}
})
vm.$watch('isHot',function(newValue, oldValue){console.log('number改变了', newValue, oldValue)})
十、绑定样式
动态绑定class样式-字符串
<div id="box" class="basic" :class="mood"></div>
new Vue({ el: '#box', data: { mood: 'normal' } }) //normal为css类名
动态绑定class样式-数组,适用绑定样式个数不确定,名字也不确定
<div id="box" class="basic" :class="arr"></div>
new Vue({ el: '#box', data: { arr: ['normal', 'sad', 'happy'] } }) //arr为css类名数组
动态绑定class样式-对象写法,要绑定的样式个数和名字都确定,但要动态决定用不用,true代表用
<div id="box" class="basic" :class="classObj"></div>
new Vue({ el: '#box', data: { classObj: { normal: false, sad: false } } }) //classObj为css类名对象
动态绑定style属性
<div id="box" class="basic" :style="styleObj"></div>
new Vue({ el: '#box', data: { styleObj: { fontSize: '40px' } } })
十一、条件渲染
使用v-show做条件渲染,决定元素是否显示,结构还在
<div id="box" v-show="isShow">一心猿</div>
new Vue({ el: '#box', data: { isShow: false } })
使用v-if做条件渲染,元素隐藏时,结构也不在
<div id="box" v-if="isShow">一心猿</div>
使用v-else-if条件渲染,中间不允许打断
<div id="root">
<div v-if="isShow">一心猿</div>
<div v-else-if="isShow">一心猿</div>
<div v-else>一心猿1</div>
</div>
template只能与v-if结合,不影响结构
<template v-if="isShow">
<div>一心猿1</div>
<div>一心猿2</div>
<div>一心猿3</div>
</template>
十二、列表渲染
使用v-for来遍历列表
new Vue({ el: '#root', data: { items: [1, 2, 3] } })
<ul><li v-for="(p,index) in items">{{p}}-{{index}}</li></ul>
v-for的key的作用
<ul><li v-for="(p,index) in items" ::key="index">{{p}}-{{index}}</li></ul>
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,旧的虚拟BOM不需要重新生成数据。
开发中如何选择key:
1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
给页面增加属性
<h3>性别:{{student.sex}}</h3>
new Vue({data:{student:{}},methods:{addSex(){Vue.set(this.student, 'sex', '男')}}})
或者
new Vue({ data: { student: {} }, methods: { addSex() { this.$set(this.student, 'sex', '男') } } })
十三、监视数据
Vue监视数据的原理:
1. vue会监视data中所有层次的数据。2. 如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value) 或
vm.$set(target,propertyName/index,value)3. 如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1).调用原生对应的方法对数组进行更新。
(2).重新解析模板,进而更新页面。4.在Vue修改数组中的某个元素一定要用如下方法:
1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set() 或 vm.$set()特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!
十四、收集表单数据
收集表单数据:
若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
若:<input type="checkbox"/>
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)(2)v-model的初始值是数组,那么收集的的就是value组成的数组
备注:v-model的三个修饰符:lazy:失去焦点再收集数据,number:输入字符串转为有效的数字,trim:输入首尾空格过滤
十五、过滤器
注册局部过滤器
new Vue({filters:{timeFormater(value, str = 'YYYY-MM-DD HH:mm:ss') {return dayjs(value).format(str)}}})
注册全局过滤器,该过滤器所有的vm对象都可以使用
Vue.filter('timeFormater', function (value) { return dayjs(value).format('YYYY-MM-DD HH:mm:ss') })
使用过滤器
<h3>现在是(过滤器实现):{{time | timeFormater}}</h3>
<h3>现在是(过滤器实现):{{time | timeFormater('YYYY-MM-DD')}}</h3>
过滤器默认接收前面表达式的值,也可以传额外参数,多个过滤器可以串联,使用“|”分隔
<h3>现在是(过滤器实现):{{time | timeFormater('YYYY-MM-DD') | mySlice}}</h3>
十六、Vue其他内置指令
v-text指令:
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
<div v-text="name"></div>
v-html指令:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。
<div v-html="name"></div>
v-cloak指令(没有值):
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
<div v-cloak></div>
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
<div v-once>初始化n:{{n}}</div>
v-pre指令:
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
<div v-pre>初始化n:{{n}}</div>
十七、自定义指令
自定义指令第一种写法:new Vue({ directives:{指令名:回调函数} })
new Vue({ directives: { big(element, binding) { } } })
<span v-big="n"></span>
这种方式调用时机:1.指令与元素成功绑定时 2.指令所在模板被重新解析时
自定义指令第二种写法:new Vue({ directives: { 指令名:配置对象 } })
new Vue({ directives: { fbind:{ bind(element, binding){},inserted(element, binding){},update(element, binding){} }} })
指令与元素成功绑定时调用bind函数
指令所在元素被插入页面时调用inserted函数
指令所在模板被重新解析时update函数
定义全局指令:Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
Vue.directive('big',function(element, binding){})
注意:1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。3.指令的回调函数this指的是window
十八、生命周期
new Vue({
el: '#root',
beforeCreate() {
//初始化:生命周期、事件,但数据代理还未开始
//此时无法通过vm访问到data的数据、methods中方法
console.log('beforeCreate')
},
created() {
//数据监测、数据代理,可以访问vm的data和methods数据
console.log('created')
},
beforeMount() {
//页面呈现的是未经Vue编译的DOM结构。
//所有对DOM的操作,最终都不奏效
console.log('beforeMount')
},
mounted() {
//页面呈现的是经Vue编译的DOM结构。
//所有对DOM的操作,最终都奏效
//开启网络请求、订阅消息、绑定事件等
console.log('mounted')
},
beforeUpdate() {
//数据是新的,但是页面是旧的
console.log('beforeUpdate')
},
updated() {
//数据和页面都是最新的
console.log('updated')
},
beforeDestroy() {
//vm的data、methods等还可以用,但不会触发页面更新
//用于关闭定时器、取消订阅消息和解绑自定义事件
console.log('beforeDestroy')
},
destroyed() {
console.log('destroyed')
},
})
常用的生命周期钩子:
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
十九、组件
定义一个组件
const student = Vue.extend({
template: `
<div>
<h2>学校姓名:{{name}}</h2>
<h2>学校年龄:{{age}}</h2>
</div>`,
data() {
return {
name: 'ddd',
age: 12
}
}
})
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。3.const student = Vue.extend(options) 可简写为:const student = options
注册组件:局部注册
new Vue({el: '#root',components: {student}})
全局注册:Vue.component('组件名',组件)
Vue.component('student',student)
使用组件标签:<student></student>,可以·简写为<student/>,这种写法要在脚手架环境下
组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。每次调用Vue.extend,返回的都是一个全新的VueComponent
(1).组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
(2).new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototyp
二十、ref属性
- ref属性被用来给元素或子组件注册引用信息
- 应用在html标签上获取的真实DOM元素,应用在组件标签上是组件实例对象
打标识
<h1 v-text="msg" ref="title"></h1>
获取值
this.$refs.title
二十一、props属性
传递数据
<StudentVue name="xxx"/>
在组件内部接收数据第一种方法
props: ["name"]
在组件内部接收数据第二种方法
props: {name: String}
在组件内部接收数据第三种方法
props: {name: {type: String,required: true}}
注意:props是只读的,如果修改,vue会发生警告,在业务中,复制props的内容到data中一份,然后修改data的数据。
二十二、 混合
构建一个js文件 暴露一个属性
export const mixin = {
data() {
return {
}
},
methods: {
},
}
在组件内部引入
全局引入:Vue.mixin(xxx) 局部引入:mixins:[xxx]
二十三、插件
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个参数是插件使用者传入的参数。
定义一个插件:对象.install = function(Vue,options){....}
使用:Vue.use()
二十四、自定义事件
子组件给父组件传递消息方式一——通过回调函数
<Son :onCallback="onCallback"/>
export default {name: "parent",components: { Son },methods: { onCallback(param) {} },};
export default {name: "Son",props:["onCallback"],methods: { onCallback(param){}},};
子组件给父组件传递消息方式二——通过自定义事件
<Son v-on:touchEvent="onCallback" /> 简写 <Son @touchEvent="onCallback" />
在子组件触发自定义事件
this.$emit("touchEvent", this.name);
通过ref属性触发
<Son v-on:touchEvent="onCallback" ref="son" />
this.$refs.son.$on("touchEvent", this.onCallback);
如果仅触发一次
<Son @touchEvent.once="onCallback" />
this.$refs.student.$once("touchEvent", this.onCallback);
解绑事件
this.$off('xxx') //解绑一个自定义事件
this.$off(['x','y']); //解绑多个自定义事件
this.$off() //解绑所有自定义事件
组件绑定DOM事件
<student @click.native="onCallback" />
注意:通过this.$refs.xxx.$on('xxx',回调),回调函数要么配在methods,要么使用箭头函数
二十五、全局事件总线
在vm安装全局事件总线
new Vue({el: '#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this }})
定义事件
export default {
name: "School",
methods: {
onCallback(data) {},
},
mounted() {
this.$bus.$on("myDefineEvent", this.onCallback);
},
beforeDestroy() {
this.$bus.$off("myDefineEvent");
},
};
在其他组件调用
this.$bus.$emit("onCallback", this.data);
二十六、nextTick函数
语法:this.$nextTick(回调函数)
作用:在下一次DOM更新结束后执行其指定的回调。
二十七、过渡与动画
元素进入的样式:
- v-enter:进入的起点
- v-enter-active:进入过程中
- v-enter-to:进入的终点
元素离开的样式:
- v-leave:离开的起点
- v-leave-active:离开的过程中
- v-leave-to:离开的终点
使用 transition标签包裹单个元素
<transition name="hello" appear>
<h1 v-show="isShow" class="hello">你好test</h1>
</transition>
使用transition-group标签包裹多个元素
<transition-group>
...
</transition-group>
二十八、vue脚手架开启代理
在vue.config.js配置方式一
devServer: {proxy: 'http://localhost:5000'}
注意:
- 不能配置多个代理
- 优先匹配前端资源,不存在则走后端路径
方法二
devServer: {
proxy: {
'/wwt': {
target: 'http://localhost:5000',
pathRewrite: { '^/wwt': '' },
ws: true,//默认支持websocket
changeOrigin: true //默认控制请求头的host值
},
'/demo': {
target: 'http://localhost:5001',
pathRewrite: { '^/demo': '' },
},
}
}
注意:
changeOrigin=true,服务端地址的端口号同服务器,否则与前端端口号一直
二十九、 插槽
默认插槽
在App使用一个Category组件
<Category title="美食">
<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="" />
</Category>
在Category组件,使用slot标签接收Category的img
<slot></slot>
具名插槽
根据名字放到指定的插槽
<Category title="美食">
<a slot="footer" href="http://www.baidu.com">更多美食</a>
</Category>
<slot name="footer"></slot>
作用域插槽
定义Category组件,通过slot往组件使用者传数据(App)
<slot :games="games"></slot>
在App组件可以使用其数据
<Category title="游戏">
<template scope="{games}">
...
</template>
</Category>
三十、vuex
安装vuex依赖 npm i vuex@3
在src/store目录下新建index.js
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
//用于响应组件中的动作
const actions = {}
//用于操作数据
const mutations = {}
//用于存储数据
const state = {}
export default new Vuex.Store({
actions,
mutations,
state
})
在main.js创建vm时传入store配置
import store from "./store";
new Vue({el: '#app',
store,
...
})
三十一、vue-router
安装vue-router: npm i vue-router@3
在main.js引入vue-router,并使用该插件
import VueRouter from "vue-router";
Vue.use(VueRouter)
在src/router目录新建一个index.js文件,编写路由配置
import VueRouter from "vue-router";
import Abort from '../components/About.vue'
import Home from '../components/Home.vue'
//创建并暴露一个路由器
export default new VueRouter({ routes:
[
{
path: '/about',
component: Abort
},
{
path: '/home',
component: Home
}
]
})
实现路由切换
<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
指定展示位置
<router-view></router-view>
注意
- 路由组件通常放在pages文件夹,一般组件通常放在components文件夹
- 通过切换,默认是销毁了组件
- 每一个组件都有自己的$route属性,里面存储着自己的路由信息
- 整个应用只有一个router,可以通过组件的$router属性获取到。
路由传参方式一——通过query传参
方式一
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`"></router-link>
方式二
<router-link :to="{path: '/home/message/detail',query: { id: m.id, title: m.title },}"></router-link>
组件接收参数
<li>消息ID:{{ $route.query.id }}</li>
<li>消息主题:{{ $route.query.title }}</li>
路由传参方式二——通过params传参
<router-link :to="`/home/message/detail/${m.id}/${m.title}`"></router-link>
路由配置文件需配置
{
path: 'detail/:id/:title',
component: Detail
}
通过params的对象传参
<router-link
:to="{ name: 'detail', params: { id: m.id, title: m.title } }"
>{{ m.title }}</router-link
>
路由配置文件需配置那么属性,不能使用path
{
path: 'detail/:id/:title',
component: Detail,
name: 'detail'
}
接收参数
<ul>
<li>消息ID:{{ $route.params.id }}</li>
<li>消息主题:{{ $route.params.title }}</li>
</ul>
路由的props传参
{
path: 'detail/:id/:title',
component: Detail,
name: 'detail',
// 方式一: props:{key:value} 会将该参数以props形式传给组件
// 方式二:props:true 会把路由所有的params以props形式传给组件
// 方式三
props($route) {
return { id: $route.query.id, title: $route.query.title }
}
}
组件使用props接收
export default {
name: "Detail",
props: ["id", "title"],
};
缓存路由组件
缓存一个
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
缓存多个
<keep-alive :include="[News,Message]">
<router-view></router-view>
</keep-alive>
缓存所有
<keep-alive>
<router-view></router-view>
</keep-alive>
路由生命周期,组件被激活调用actived,失活调用deactivated
activated() {},
deactivated() {},
全局路由守卫
//全局前置路由守卫——每次路由切换之前被调用
router.beforeEach((to, from, next) => {
})
//全局前置路由守卫——每次路由切换之后被调用
router.afterEach((to,from) =>{
})
独享路由守卫
{
name: 'guanyu',
path: '/about',
component: Abort,
//独享路由守卫
beforeEnter: (to, from, next) => {
}
}
组件路由守卫
export default {
name: "About",
//通过路由规则,进入该组件时被调用
beforeRouteEnter(to, from, next) {},
//通过路由规则,离开该组件时被调用
beforeRouteLeave(to, from, next) {},
};