1.库(lib) 代表:jQuery
说明:库里面有一系列函数的集合,我们想要实现某个功能,调用库里面的一些方法
特点:库为辅助功能,即开发人员说了算
2.框架(framework) 代表:vue
说明:框架里有一套完整的解决方案,‘它指定了一套规则’,使用这个框架就要按照它的规则去编写代码,编写好之后,框架会在适当的时机去解析我们的代码。
特点:框架说了算
比如:v-for created data
3.库和框架的区别:控制反转(谁说了算,谁起主导作用)
库:开发人员说了算
框架:框架说了算
从体量上看:框架>库(框架包含库)
1.MVC模式和MVVM模式
(1)MVC模式:后端编写代码控制视图
M:model 数据
V:view 视图
C:control 控制器
简单的流程就是:用户与View交互;Controller时间处理器被触发,控制器从模型中请求数据(model),并反馈给视图层(view),视图讲数据呈现给用户。
注意:真正处理业务逻辑的是Model层而不是controller;controller只是对页面节点事件的注册和控制
(2)MVVM模式
vue的模式是MVVM模式(数据的双向绑定)
M:model 数据层
V:view 视图层
VM:ViewModel 视图数据层 == vm(vue的实例)
View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
数据驱动视图的思想,数据是核心(数据改变,视图也改)
① vue的数据双向绑定,是通过Object.defineProperty()数据劫持来实现
② Object.defineProperty(obj, prop, descriptor) 添加/修改属性
(参数1:对象;参数2:属性(添加/设置);参数3:属性描述符,对象形式)
obj:要定义属性的对象。
prop:要定义或修改的属性的名称或 Symbol 。
descriptor:要定义或修改的属性描述符。
const object1 = {
};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false
});
// 读写设置为(writable: false),不能改
object1.property1 = 77;
console.log(object1.property1);
// 输出: 42
(3)vue的安装
// 安装:
npm i vue
// 导入:
<script src = './vue.js'></script>
{ {}} 插值表达式 小胡子语法
作用:直接读取data里的数据,展示到模板(<>{ {}}<>)
① 可以放表达式{msg + 200} { {[1, 2, 3].join(’-’)}}
② 不能放语句
③ { {}}不能用在属性上
<div id="app">
{
{ message }}
div>
const vm = new Vue({
el:'#app',
data : {
message : 'hhha'
}
})
1.v-model (数据的双向绑定)
场景:一般用在表单元素上
<div id="app">
<p>{
{ message }}p>
<input v-model="message">
div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
2.v-text/v-html 和{ {}}效果一样
v-text 不识别标签 v-html 识别标签的
<span v-text="msg">span>
<span>{
{msg}}span>
3.v-bind 动态绑定一个数据(单向m => v)
语法::属性 = ‘data里面的一个值’
<div :class="{ red: isRed }">div>
<div :class="[classA, classB]">div>
<div :class="[classA, { classB: isB, classC: isC }]">
<div :style="{
fontSize: size + 'px' }">div>
<div :style="[styleObjectA, styleObjectB]">div>
4.v-on 注册/绑定事件
① v-on:事件 = ‘事件函数’
② 语法糖:@事件 = ‘事件函数’、
③ 事件函数
// html部分
<div id='app'><button @click='click1'>按钮button>div>
// js部分
const vm = new Vue({
el:'#app',
data:'...',
method:{
click1(){
console.log('点击了按钮');
}
}
})
事件中的this就是vue实例
获取数据:
① 标签获取数据:{ message }
② js获取数据:this.message
事件对象(获取):
① 不传参,直接在事件函数里接收一个形参即可:@click = ‘fn’ fn(e){}
② 传参,vue预留了一个关键字 e v e n t @ c l i c k = ′ f n ( event @click = 'fn( event@click=′fn(event, 123)’ fn(e, num){}
事件修饰符:
① 事件.prevent 阻止默认行为
② 事件.stop 阻止冒泡
③ 事件.capture 捕获(即内部元素触发的事件先在此处理,然后才交由内部元素进行处理)
④ 事件.self 点击自己才会被触发
⑤ 事件.once 点击只触发一次
⑥ 事件.passive 移动端提高性能
按键修饰符:
enter/tab/delete/esc/space/up/down/left/right
使用回车的三种方式:
① if(e.keyCode == 13){}
② @keyup.13 = ‘fn1’
③ @keyup.ente = ‘fn1’
5.v-for 遍历数据,创建对应的(指令所在的)标签
① 遍历数据
key:
① vue推荐使用v-for的时候,加上key
② 如果不加key,会出现‘就地复用’的策略
③ 解决‘就地复用’的问题:添加一个key属性,并且给key一个正确值
④ 给key赋值的俩种情况:
=> 如果数组里的元素是一个对象(90%),key取对象里的属性(固定,唯一) :key=‘iten.id’
=> 如果数组里的元素不是一个对象 :key=‘index’(不要让顺序发生改变)
6.其它指令:
① v-pre 不解析
② v-once 解析一次
③ v-cloak 遮盖,解决闪烁问题
[v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
[v-cloak] {
display: none;
}
<div v-cloak>
{
{ message }}
div>
7.条件渲染指令
v-if 和 v-show
相同点:都可以切换元素的显示和隐藏
不同点:
v-if:显示(创建节点) 隐藏(删除节点)
v-show:显示(display:block) 隐藏(display:none)
场景:频繁(v-show) 不频繁(v-if)
<div v-if="type === 'A'">
A
div>
<div v-else-if="type === 'B'">
B
div>
<div v-else-if="type === 'C'">
C
div>
<div v-else>
Not A/B/C
div>
1.nextTick() 的自动触发
数据发生改变,vue会自动更新视图。
数据发生变化,不是一改变就立马更新的,而是当数据不再发生变化的时候,一次性统一更新的。
nextTick 数据变化,自动触发
this.nextTick(() => {})
2.数据响应式问题(v-model)
Vue无法检测到对象属性的添加或删除。
总结:
① 尽量先在data里声明好,给一个初始值
② 在一些第三方框架里,我们必须动态地添加额外的数据。 this. s e t ( ) t h i s . set() this. set()this.set(obj, key, value)
3.计算属性computed
计算属性:是一个新值,不是data里的值
computed:{
itemLeftCount(){
return this.list.filter(item=>!item.done).length
};
isClearCompletedShow(){
return this.list.some(item=>item.done)
}
}
1.监听简单类
data:{
num:100;
}
watch:{
num(newVal, oldVal){
console.log('新知:', newVal, '旧值:', oldVal);
}
}
2.监听复杂类型
方式1:监听对象+深度监听
obj:{
deep:true, // 深度监听
immediate:true, //立即监听
handler(newVal){
// 处理函数
console.log(newVal.name);
}
}
方式2:直接监听对象里面的属性(name)
'obj.name'(newVal):{
console.log(newVal);
}
作用:处理不合适的数据,处理好之后,返回合适的数据
使用过滤器的步骤:
① 先注册
全局过滤器:所有的vue实例里都可以使用
局部过滤器:只能在当前注册的实例里使用
② 再使用‘管道’
格式:要处理的数据 | 过滤器
1.全局过滤器
注意点(注册全局过滤器):
① 注册全局过滤器,一定要在实例vue之前注册
② 过滤器要有返回值,返回的值就是过滤处理好的值
参数1:过滤器的名字 参数2:回调函数(当使用过滤器的时候使用)
<div id='app'>
<h1>{
{date | dateFilter}}h1> // 使用‘管道’
div>
<script src='vue.js'>script>
<script>
// 参数1 : 过滤器的名字
// 参数2 : 回调函数 当使用过滤器的时候
// 注册全局过滤器
Vue.filter('dateFilter', () => {
return 'hhha'
})
const vm = new Vue({
el:'#app',
data:{
date:new Date()
}
})
script>
过滤器配合moment处理日期
① 安装:npm i moment
② 引入
③ 使用
Vue.filter('dateFilter', res => {
return moment(res).format('YYYY-MM-DD HH:mm:ss')
})
过滤器的参数:
<div id='app'>
<h1>{
{ date | dateFilter('YYYY-MM-DD HH-mm-ss')}}h1>
div>
Vue.filter('dateFilter', (res, fStr='YYYY-MM-DD' => {
return moment(res).format(fStr)
})
2.局部过滤器:
位置:局部过滤器是注册在vue实例里面
const vm = new Vue({
el : '#app',
dat : {
date : new Date()
}
filters : {
dateFilter(res){
return moment(res).format('YYYY-MM')
}
}
})
生命周期的三个大阶段
① 第一个阶段:挂载阶段(进入页面的阶段)
② 第二个阶段:更新阶段(数据发生改变的阶段)
③ 第三个阶段:销毁阶段(卸载阶段,关闭页面)
1.第一个阶段:挂载阶段(4个钩子函数)
① 第1个小阶段:数据的初始化 => msg:测试信息
② 第2个小阶段:找模板 => 找template等
③ 第3个小阶段:DOM渲染 => <标签>{ {msg}}标签>=><标签>测试信息标签>
第1个小阶段:数据的初始化
beforeCreate() 数据响应式之前调用
特点:无法获取到数据和事件
☆ create() 数据响应式之后调用
特点:可以获取到数据和事件
使用场景:① 发送ajax ② 操作data ③ 操作本地数据(操作数据)
第2个小阶段:找模板
询问有没有‘el’配置项(①有=>继续下一步 ②没有=>vm.$mount(’#app’)=>继续下一步)
询问有没有‘template’配置项(①有=>将template的值进行编译 ②没有=>el的outerHTML作为模板)
目的:找模板 结论:template>el(既先看vue实例里有没有template)
第3个小阶段:DOM渲染
before() DOM渲染之前调用
特点:<标签>{ {msg}}标签>
☆ mounted() DOM渲染之后调用
特点:<标签>测试信息标签>
使用场景:① 发送ajax ② 操作DOM
第二个大阶段:更新阶段(2个钩子)
beforeUpdate() 数据更新之前
updated() 数据更新之后
第三个大阶段:销毁阶段(2个钩子)
beforeDestory() 销毁之前(可以清除开发人员自己添加的定时器等)
destoryed() 销毁之后
安装:npm i axios
1.axios和ajax
axios是一个基于promise,发送ajax的工具库,可用于浏览器/node.js
① axios是对ajax的一个封装
② axios是基于promise的
2.格式:axios.get/post/put/patch(…).then(res => {})
(1)get
① 获取全部数据
参数:url地址接口
axios.get('http://localhost:300/list').then(res => {
cosole.log(res)})
② 获取具体某一个
axios.get('http://localhost:300/list/3').then(res => {
cosole.log(res)})
③ 获取具体某一个,id为参数
语法:axios.get(url, config)
配置项config:{params(对象)参数,herder(对象).请求头}
axios.get('http://localhost:300/list',{
params : {
id:4},
header : {
}
})
(2)post添加
post添加不需要传id的
语法:axios.post(url, data)
axios.post('http://localhost:300/list', {
name:'ZS', done:false}).then(res => {
console.log(res)})
(3)delete删除
axios.delete('http://localhost:300/list/3').then(res => {
cosole.log(res)})
(4)put/patch修改
axios.put('http://localhost:300/list/3', {
name:'改李四', done:false}).then(res => {
cosole.log(res)})
axios.patch('http://localhost:300/list/3', {
name:'改老王'}).then(res => {
cosole.log(res)})
axios.patch('http://localhost:300/list/$(this.editId)', {
name:e.target.value}).then(res => {
cosole.log(res)})
3.json-server
作用:可以根据一个json文件,开启一个借口服务器
安装:npm i json-server -g
使用:‘json-server json文件的路径’ =>终端运行命令获得浏览器路径
遵循REST API格式:
(1)获取:get
① 获取全部:http://localhost:300/list
② 获取具体某个:http://localhost:300/list/3
(2)添加
http://localhost:300/list
不需要id 参数:{name:‘张三’, done:true}
(3)删除:delete
http://localhost:300/list/2
(4)修改:put/patch
① put(修改某一个):http://localhost:300/list/3
把需要修改的和不需要修改的都传过去{name:‘张三’, done:true}
②patch(修改某一个):http://localhost:300/list/3
哪里需要修改就传对应的修改数据
组件可以看作是一些可复用的UI模块
官网:组件是可复用的Vue实例
1.注册组件
(1)全局组件
注意:
① 注册组件要在vue实例之前注册
② template只能有一个根节点
③ 组件里的data是一个函数,不是一个对象(因为想让组件复用,不想让组件里的数据复用)
<div id='app'><one>one>div>
<script src='./vue.js'></script>
<script>
Vue.compent('two', {
template:'{
{msg}}
'
}),
data(){
return {
msg:123 }
}
</script>
(2)局部组件
位置:vue实例里面
const child = {
template: '局部组件child:{
{msg}}',
data(){
return {
msg:'局部组件:哈哈'}
}
}
const one = {
...}
const two = {
...}
const vm = new Vue({
el: '#app',
data: {
},
filters: {
},
components: {
child, one, two
}
})
★2.组件间的通信机制
(1)父传子(父组件数据传给子组件)
步骤:
① 通过属性传递给子组件
② 子组件通过props配置项,指定一下要接收过来的数据 props : [‘msg’]
<div id="app">
<child :msg="pmsg">child>
div>
<script src="./vue.js">script>
<script>
// 子组件
Vue.component('child', {
template: `
子组件 : {
{ msg }}
`,
// 第二步 : 子组件通过 props 配置项 指定一下要接收过来的数据
props: ['msg']
})
// 父组件
const vm = new Vue({
el: '#app',
data: {
pmsg: '父组件里的信息'
}
})
script>
body>
(2)子传父(子组件数据传给父组件)
步骤:
① 父组件准备一个方法fn1(){}
② 通过自定义事件,把方法传递给子组件@fn=‘fn1’
③ 子组件通过$emit触发事件(手动触发事件)
$emit(参数1:事件(fn), 参数2:子组件传递的数据)
<div id="app">
<child @fn="fn1">child>
div>
<script src="./vue.js">script>
<script>
// 子组件
Vue.component('child', {
template: `
子组件 :
`,
created() {
// 例子
// @click='fn1'
// 1. 点击 => 调用fn1
// 2. 手动触发 this.$emit('click') => fn1
// 第三步 : 子组件里面触发这个事件,就调用了fn1
// $emit(参数1:事件 参数2..:传递的数据)
this.$emit('fn', '我是子组件里的数据')
}
})
const vm = new Vue({
el: '#app',
data: {
},
// 第一步: 父组件准备好一个方法
methods: {
fn1(res) {
console.log('fn1调用了:', res)
}
}
})
script>
(3)父子组件传递数据的总结
① 单向数据流(组件与组件之间)
所有的prop都使得父子prop之间形成一个单向下行绑定
父级更新可以,子组件不能修改父组件数据(简单数据和复杂数据(地址))
② props的特点:只读
注意:子组件不允许修改父组件传过来的prop数据(如果想修改可以通过子传父将要修改的信息传给父组件)
简单类型修改会报错
复杂类型:修改不会报错,因为地址没变,测试‘obj={}’马上报错=>改变了地址
③ prop的大小写问题
父传子: c-msg(属性) => CMsg(prop中)
子传父:@add-todo(自定义事件) => add-todo($emit中)
<div id="app">
<child :c-msg="pMsg" @add-todo="pAddTodo">child>
div>
<script src="./vue.js">script>
<script>
Vue.component('child', {
template: `
子组件 : {
{ cMsg }}
`,
props: ['cMsg'],
created() {
this.$emit('add-todo')
}
})
const vm = new Vue({
el: '#app',
data: {
pMsg: '父的信息'
},
methods: {
pAddTodo() {
console.log('hha')
}
}
})
script>
④ prop的类型问题
通过prop 赋值的时候,
如果直接赋值一个静态值 不管是什么,都是字符串类型( ‘abc’ / ‘123’ / ‘true’)
可以在 属性前面加一个: , 可以获取它的真实类型
总结 :
:msg=‘pmsg/动态值/data里属性’
:msg=‘固定值/静态值’ 读取固定值的真实类型赋值给 msg
<div id="app">
<child :msg="true" :na="name">child>
div>
<script src="./vue.js">script>
<script>
Vue.component('child', {
template: `
子组件 :
`,
props: ['msg'],
created() {
// 'abc' => 字符串
// '123' => '123' 字符串
console.warn(this.msg, typeof this.msg)
}
})
const vm = new Vue({
el: '#app',
data: {
name: 123
}
})
script>
⑤ prop的校验(判断传过来的数据是否为自己想要的)
props: {
// 默认值为数字
msg1: {
type: Number,
default: 100 // 默认为数字100
},
// 默认值为对象
msg2: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return {
message: 'hello' }
}
}
(4)非父子之间的通信是通过事件总线(event bus)来实现的
步骤:
① 创建事件总线(bus):一个空的vue实例
const bus = new Vue()
② 发送数据:触发事件=>bus. e m i t ( ′ 事 件 名 ′ , ′ 数 据 ′ ) ③ 接 收 数 据 : 注 册 事 件 = > b u s . emit('事件名', '数据') ③ 接收数据:注册事件=>bus. emit(′事件名′,′数据′)③接收数据:注册事件=>bus.on(‘事件名’, res => {})
<div id="app">
<div>
<div>
<component1>component1>
div>
div>
<div>
<component2>component2>
div>
div>
<script src="./vue.js">script>
<script>
//1. 事件总线
const bus = new Vue()
// component1
Vue.component('component1', {
template: `组件1`,
methods: {
send() {
console.log('send')
// 发送 一起 jump 的话
//2. 发送数据, 触发事件
bus.$emit('jump', 'component1发送的数据')
}
}
})
// component2
Vue.component('component2', {
template: `组件2`,
created() {
//3. 接收数据 注册事件
console.log('on')
bus.$on('jump', res => {
console.log('rose接收到的:', res)
})
}
})
const vm = new Vue({
el: '#app',
data: {
}
})
script>
(5)refs:refs可以获取DOM元素/组件
步骤:
① 注册ref=‘c’
② 获取:this.$refs.c
<div id="app">
// 注册ref
<div ref="d">我是divdiv>
<p ref="p">我是p标签p>
<child ref="c">child>
div>
<script src="./vue.js">script>
<script>
// 组件 看做是一个个可复用的ui模块
// 组件的本质 vue 实例
Vue.component('child', {
template: `
子组件 :
`,
data() {
return {
cmsg: '子组件里的数据'
}
}
})
const vm = new Vue({
el: '#app',
data: {
},
created() {
},
mounted() {
// 可以通过 this.$refs 获取dom元素/组件
console.log(this.$refs.p)
console.log(this.$refs.d)
// 也可以获取组件里的数据
// 父组件可以通过 refs 拿到子组件里的数据
console.log(this.$refs.c.cmsg)
}
})
script>
(6)组件传参的方式
① 方式1:to=’/one/4’ path=’/one/:id’
组件: r o u t e . p a r a m s . i d 事 件 : t h i s . route.params.id 事件:this. route.params.id事件:this.route.params.id
② 方式2:路由规则里props:true
将参数id作为组件的属性存在
路由里:props:true
组件内:props:[‘id’]
使用{ {id}}
③ 方式3:对象模型
路由里:props:{aaa:‘bbb’}
组件内:props:[‘aaa’]
使用{ {aaa}}
④ 方式4:函数模式
路由里: props : to => { return { aaa : ‘ccc’ } }
组件内:props:[‘aaa’]
使用{ {aaa}}
<div id="app">
<router-link to="/one">onerouter-link>
<router-view>router-view>
div>
<script src="./vue.js">script>
<script src="./node_modules/vue-router/dist/vue-router.js">script>
<script>
// 3. 组件
const One = {
props: ['id', 'aaa'],
template: `one组件 {
{ aaa }}`
}
// 实例化
const router = new VueRouter({
// 2. 规则
// props : true 将id参数作为组件的属性存在
routes: [
// { path: '/one/:id', component: One, props: true }
// 将aaa 作为 组件的属性存在
// { path: '/one', component: One, props: { aaa: 'bbb' } }
{
path: '/one',
component: One,
props: to => {
return {
aaa: 'ccc'
}
}
}
]
})
const vm = new Vue({
router,
el: '#app',
data: {
}
})
script>
(7)单页面应用程序(SPA:Singe Page Application)
浅谈前端SPA(单页面应用):https://blog.csdn.net/huangpb123/article/details/86183453
优势:
① 减少了体积,加快了页面响应速度,降低了对服务器的压力
② 更好的用户体验,让用户在web app感受到native app的流畅(局部刷新)
劣势:
① 开发成本高(需要学习路由)
② 不利于SEO
1.路由的基本使用
(1)准备工作
① 安装路由 npm i vue-router
② 引入路由
③ 实例化路由 + 挂载到vue上
(2)使用步骤
① 入口 (哈希值) 手动在url上写 /one
② 规则(routes):路由的匹配规则,一个哈希值对应一个组件
③ 组件 :路由组件
④ 出口:路由输出位置
既:根据入口哈希值路径,参与路由匹配规则,找到对应的组件,显示到对应的出口位置上
<div id="app">
<router-view>router-view>
div>
<script src="./vue.js">script>
<script src="./node_modules/vue-router/dist/vue-router.js">script>
<script>
// 第三步 : 路由组件
const One = {
template: `one组件`
}
// 实例化路由
const router = new VueRouter({
// 第二步 : 路由的匹配规则 一个哈希值 对应一个组件
routes: [{
path: '/one', component: One }]
})
const vm = new Vue({
router,
el: '#app',
data: {
}
})
script>
(3)入口(修改url路径)
① 手动url修改 /one
② 声明式导航 one
router-link最终会被编译成a标签
to:转换成href
作用:改变入口的哈希值路径
③ 编程式导航 this. r o u t e r . p u s h ( ′ / o n e ′ ) 前 进 ( 跳 转 ) = = > − t h i s . router.push('/one') 前进(跳转) ==> - this. router.push(′/one′)前进(跳转)==>−this.router.push() - 有记录
- this. r o u t e r . r e p l a c e ( ) − 没 有 记 录 返 回 = = = = > t h i s . router.replace() - 没有记录 返回 ====> this. router.replace()−没有记录返回====>this.router.back()
// 声明式导航
<router-link to='/one'>one</router-link>
// 编程式导航
this.$router.push('/two')
this.$router.replace('/two')
(4)多个路径和嵌套路由
// 多个路径的路由写法
const router = new VueRouter({
// 路由的匹配规则 一个哈希值 对应一个组件
routes: [
{
path: '/one', component: One },
{
path: '/two', component: Two }
]
})
<div id="app">
<router-view>router-view>
<hr />
div>
<script src="./vue.js">script>
<script src="./node_modules/vue-router/dist/vue-router.js">script>
<script>
// 3. 组件
const parent = {
template: `parent组件 `
}
const child = {
template: `child组件`
}
// 实例化
const router = new VueRouter({
// 2. 规则
routes: [
{
path: '/parent',
component: parent,
children: [{
path: '/child', component: child }]
}
]
})
const vm = new Vue({
router,
el: '#app',
data: {
}
})
script>
(5)动态路由
① 使用参数接收不同的路由参数path=’/detali/:id’
② 参数可传可不传path=’/detali/:id?’
精确匹配和模糊匹配:
① router-link-exact-active精确匹配
url上的路径==href的值
② router-link-active(包含)既>=href的值
(6)$route路由对象 哈希值#/one/2?age=18#abc
fullpath:字符串/one/2?age=18#abc 全路径
hash:字符串=>#abc 哈希
★ params:对象=>{id:‘2’} 路由参数
★ path:字符串=>/one/2 #后面?前面的path
★ query:对象=>{age:18} 查询参数
★重点:使用watch监听$route路由对象(地址改变)获取里面信息
watch: {
$route(newVal) {
console.warn(newVal.params.id)
}
}
(7)命名路由(同路径多组件)和命名路由
<div id="app">
<router-view>router-view>
<router-view name="m">router-view>
<router-view name="f">router-view>
div>
<script src="./vue.js">script>
<script src="./node_modules/vue-router/dist/vue-router.js">script>
<script>
// 3. 组件
const header = {
template: `header组件`
}
const main = {
template: `main组件`
}
const footer = {
template: `footer组件`
}
// 实例化
const router = new VueRouter({
// 2. 规则
routes: [
{
path: '/',
components: {
default: header,
m: main,
f: footer
}
}
]
})
const vm = new Vue({
router,
el: '#app',
data: {
}
})
script>
<div id="app">
<router-link :to="{ name : 'one' }">onerouter-link>
<router-link :to="{ name :'two' }">tworouter-link>
<router-view>router-view>
div>
<script src="./vue.js">script>
<script src="./node_modules/vue-router/dist/vue-router.js">script>
<script>
// 3. 组件
const One = {
template: `one组件`
}
const Two = {
template: `two组件`,
created() {
console.log(this.$route.name)
}
}
// 实例化
const router = new VueRouter({
// 2. 规则
routes: [
{
path: '/one', name: 'one', component: One },
{
path: '/two', name: 'two', component: Two }
]
})
const vm = new Vue({
router,
el: '#app',
data: {
}
})
script>
(8)重定向
路径的三种方式:
① 方式1:path路径 {path:’/’, redirect:’/one’}
② 方式2:路由的名称 {path:’/’, redirect:{name:‘one’}}
③ 方式3:函数
routes: [
// 方式1 : path路径
// { path: '/', redirect: '/one' },
// 方式2 : 路由的名称
// { path: '/', redirect: { name: 'one' } },
// 方式3 : 函数
{
path: '/',
redirect: to => {
if (to.XXX) {
return {
name : 'one'}
} else {
return {
name : 'two' }
}
}
}
]
(9)元信息:路由里添加meta字段
{path:/one, name:‘one’, component:one, meta:{title:‘张三页’}}
示例:meta信息修改document.title = this.$route.meta.title
(10)前置导航守卫:beforeEach
场景:先登录再访问
① 写法 router.beforeEach( (to,from ,next)=> {} )
② 参数:
to : 目标路由对象
from : 来源路由对象
next: 下一步
③ next() 允许下一步
next(false) 不允许
next(’/login’) 跳转到login
// 先登录后访问
router.beforeEach((to, from, next) => {
if(to.name == 'login'){
next();
}else{
next('/login');
}
})