JavaScript基础知识

  • ES6语法规范
  • ES6模块化
  • 包管理
  • 原型、原型链
  • 数组
  • axios
  • promise

组件化开发

数据—->虚拟DOM—>真实DOM

Vue模板语法

  1. 插值:{{}}
  2. 指令:

    • v-bind,单向绑定
    • v-mode,用于表单,双向绑定
  3. el和data的两种写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // el
    new Vue({
    el: "#app",
    data: {
    value: 123
    }
    })

    new Vue({
    data: {
    value: 123
    }
    }).$mount('#app')

    //data
    new Vue({
    el: "#app",
    data: {
    value: 123
    }
    })

    new Vue({
    el: "#app",
    data(){
    return{
    value:123
    }
    }
    })

MVVM

View ViewModel model
DOM

数据代理

通过一个对象代理对另一个对象中属性的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<script>
let num = 10
let obj = {
name: 'lang',
add: '兰州'
}
Object.defineProperty(obj, 'age', {
// value: 18,
// enumerable: true, // 控制属性可枚举,可遍历
// writable: true, // 可修
// configurable: true, // 控制是否可被删除
get() {
return num
},
set(value) {
num = value
}


})
console.log(Object.keys(obj));

/* for (key in obj) {
console.log(obj[key]);
} */
console.log(obj);
</script>

事件

@click
@scroll 滚动条
@wheel 滚轮 @wheel.passive 阻止回调函数,让默认行为先执行

事件修饰符

prevent stop once capture self passive

键盘事件

enter deleter esc space tab up down left right配和keyup
ctrl alt shift meta配合keydown

1
<input type="text" placeholder="请输入" name="" id="" @keyup.right="showInfo">

计算属性

可被缓存、直接读取相当于属性

监视属性

1
2
3
4
5
6
7
8
9
10
11
<script>
watch: {
info: {
immediate: true, // 立即执行
deep:true,// 深度监视
handler(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
}
</script>

Style样式

  1. class
    :class="xxx",xxx可以是字符串,对象数组
  2. style
    :style="{}",:style="[]"

条件渲染

v-if: 销毁和创建,文档中不存在
v-show:调整display:none/block,还存在于文档中
变化频繁使用v-show

template 不会被渲染,但是能配合v-if

1
2
3
4
5
<template v-if="">
<h2></h2>
<h2></h2>
<h2></h2>
</template>

v-for key

可遍历数组,对象,字符串,范围(0-10)

如果值是展示类表则可以用index作为:key
如果用输入框,删除等操作,则必须要用唯一标识

响应式 Vue.set()

Vue会监视data中所有层的数据

vue2的响应式是通过object.defineproperty实现的,JavaScript对象传入vue实例时,vue会遍历对象的所有property,并通过object.defineproperty把这些property转化为getter和setter,数据发生变化时,就会触发视图的更新;不过这种方式有点缺陷,就是不能监测到对象属性的添加和删除,因此需要用vue.set()来添加和删除。并且也不能监听数组的变化后添加的数据做响应式

vue.set(target,key,val)方法target不能是Vue实例,或者Vue实例对象的根数据对象
Vue.set(target,key,val),vm.$set(target,key,val)

过滤器

不会改变原始数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// 局部
filters: {
timeFormat(value, str = 'YYYY-MM-DD HH:mm:ss') {
return dayjs(value).format(str)
},
/* mySlice(value) {
// 1970 - 07 - 27 10: 33: 59
return value.slice(0, 4)
} */
}

// 全局过滤器

Vue.filter('mySlice', function (value) {
return value.slice(0, 4)
})

指令梳理

v-bind
v-model
v-for
v-if>
v-else-if
v-else
v-show

v-text

会替换标签中的所有内容

v-html

  1. 可识别html结构
  2. 在网站上动态渲染html是非常危险的,容易造成XSS攻击
  3. 不要在用户提交的内容上渲染

v-clock

1
2
3
4
5
6
<style>
[v-clock]{
display:none
}
</style>
<h2 v-clock>{{name}}</h2>

v-once

初次动态渲染后就会成为静态内容了

v-pre

跳过器所在结点编译过程,跳过没有指令语法的标签

自定义指令

1
2
3
4
5
6
7
directives:{
big(element, bingding) {
console.log(element)
console.log(bingding);
element.innerHTML = bingding.value * 10
}
}

big函数何时会被调用?指令与元素成功绑定时,指令所在的模板被重新解析时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<input type="text" name="" id="" v-fbind="num">

<script>
new Vue({
el:'xxx',
data:{},
fbind: {
// 指令与元素成功绑定(页面一上来)
bind(element, binding) {
element.value = binding.value
console.log('bind');
},
// 指令所在页面被插入页面
inserted(element, binding) {
element.focus()
console.log('inserted');
},
// 指令所在模板被重新解析
update(element, binding) {
element.value = binding.value
console.log('updated');
},
}
})
</script>

注意:自定义指令里面的this指向windows

全局指令

1
2
3
4
5
6
7
8
9
10
11
<p><span v-big="num"></span></p>

<script>
Vue.directive('big', function (element, binding) {
element.innerHTML = binding.value * 10
})
new Vue({
el:'xxx',
data:{},
})
</script>

生命周期

生命周期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<script>
new Vue({
el: "#app",
data: {
num: 1,

},
methods: {
add() {
console.log('add');
this.num++
},
bye() {
console.log('bye');
this.$destroy()
}
},
watch: {
num() {
console.log('num变了');
}
},

beforeCreate() {
console.log('beforeCreate', 'num', this.num);
},
created() {
console.log("created", 'num', this.num);
},
beforeMount() {
console.log('beforeMount', "num", this.num);
},
mounted() {
console.log('mounted', "num", this.num);
},
beforeUpdate() {
console.log(this);
console.log('beforeUpdate,更新数据,不更新dom');
},
updated() {
console.log(this);
console.log('updated,更新数据和dom');
},
beforeDestroy() {
this.add() // 可调用,但不可执行
console.log('beforeDestroy', 'num', this.num);
},
destroyed() {
console.log('destroyed', 'num', this.num);
},

})
</script>

常用生命周期钩子

  1. mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅消息
  2. beforeDestroy: 清除定时器、解绑自定义事件、取消订阅【收尾工作】

  3. 关于销毁vue实例

    • 销毁后借助vue开发者工具看不到任何消息
    • 销毁后自定义事件会失效,但原生dom事件依然存在
    • 一般不会再 beforeDestroy 操作数据,因为即便操作数据,也不会触发更新流程

组件化

非单页面组件

使用Vue.extend(options)创建组件
data必须写为函数——-避免组件被复用时,数据存在引用关系
使用template可配置组件的结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<body>
<div id="app">
<!--3. 引用组件 -->
<hello></hello>
<school></school>
<hr>
<student></student>
<hr>
<student></student>
<hr>
</div>
<div id="app2">
<hello></hello>
</div>


<script src="../../../js/vue.js"></script>
<script>
// 1.创建组件
const school = Vue.extend({
template: `
<div>
<h3>schoolname:{{name}}</h3>
<h3>address:{{addr}}</h3>
</div>

`,
data() {
return {
name: '清华',
addr: '北京'
}
}
})

const student = Vue.extend({
template: `
<div>
<h3>name:{{name}}</h3>
<h3>address:{{age}}</h3>
</div>
`,
data() {
return {
name: '张三',
age: 19
}
}
})

const hello = Vue.extend({
template: `
<div>
<h1>hello,{{name}}</h1>
</div>
`,
data() {
return {
name: 'Tom'
}
},
})

// 将hello注册为全局组件
Vue.component('hello', hello)
new Vue({
el: '#app',
// 2.注册组件
components: {
school,
student
}
})

new Vue({
el: '#app2'
})
</script>
</body>
  1. 组件的命名:如MySchool—->my-school,(MySchool需在vue-cli中使用)
  2. 在html中的写法</my-school>,</my-school>

组件的嵌套

VueComponent

  1. 组件中的this指向VueComponent实例对象
  2. new Vue(options)中的this指向Vue实例对象

内置关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<script>

Vue.prototype.a = 18

const demo = Vue.extend({
template: `
<div>
<h2>{{msg}}</h2>
</div>
`,
data() {
return {
msg: 'demo'
}
},
mounted() {
console.log(this.a); // VueComponent(prototype)--->Vue(prototype)---->Object(prototype.a)
},
})
// 定义一各构造函数
function Demo() {
this.a = 1
this.b = 2
}
console.log(Demo.prototype); // 显示原型属性
// 创建实例对象
let d = new Demo()
console.log(d.__proto__); // 隐式原型属性
console.log(Demo.prototype === d.__proto__);
Demo.prototype.x = 100
console.log(d);
console.log(d.x);
</script>

VueComponent.prototype.__proto__==Vue.prototype

单文件组件

Vue-cli(command line interface—命令行结构工具) 脚手架

vue.js:是完整版Vue,包括核心功能+模板解析器
vue.runtime.xxx.js:运行时的Vue,只包含核心功能

render渲染函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<script>
/*
项目的入口文件
*/
// 精简版vue配合render函数使用
import Vue from 'vue'
// 引入根组件
import App from './App.vue'
// 关闭生产提示
Vue.config.productionTip = false

// 创建Vue实例vm
// 1.import Vue from 'vue'
/* new Vue({
el: "#app",
render(h) {
return h('h1', '你好')
},
})
*/

//2.import Vue from 'vue'
/* new Vue({
el: "#app",
render(h) {
return h(App)
},
})
*/

// 3. 需要引入完成版vue,含有模板解析器
/* import Vue from 'vue/dist/vue'
new Vue({
el: "#app",
template: `<App></App>`,
components: { App },
}) */

// 4. import Vue from 'vue'
new Vue({
render: h => h(App)
}).$mount('#app')

</script>

配置文件,输出配置文件

输出配置文件:vue inspect > output.js
配置文件

ref属性

  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取doc元素,应用在组件上获取实例对象(VueComponent)
  3. 使用:<p ref="xxx"></p>,this.$refs.xxx

props

  1. 父向子传值
  2. 只读(不能修改,若业务需要修改,那么复制一份到data中,让后修改data中的数据)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <script>

    // 1.简单传值,只做接受
    props: ['name', 'age'],

    // 2. 限制类型
    props: {
    name: String,
    age: Number
    },
    // 3. 限制类型,限制必要性,指定默认值
    props: {
    name: {
    type: String,
    required: true
    },
    age: {
    type: Number,
    default: 99 // 默认值
    }
    },
    </script>

mixin(混入)

  1. 可以把多个组件的共用配置提取在一个混入对象中
  2. 定义
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    export const mixin = {
    data() {
    return {
    x: 10,
    y: 20
    }
    },
    methods: {
    showName() {
    alert(this.name)
    }
    },
    mounted() {
    console.log(888888);
    },

    }
  3. 使用
    • 全局引入:Vue.mixin(xxx)
    • 局部引入:mixins:[xxx,xxx]

插件

  1. plugins.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
export default {
install(Vue, x, y) {
console.log(x, y);
// 过滤器
Vue.filter('mySlice', function (value) {
return value.slice(0, 4)
})
// 自定义指令
Vue.directive('fbind', {

// 指令与元素成功绑定(页面一上来)
bind(element, binding) {
element.value = binding.value

},
// 指令所在页面被插入页面
inserted(element, binding) {
element.focus()
},
// 指令所在模板被重新解析
update(element, binding) {
element.value = binding.value
console.log('updated');
},

})

// 混入
Vue.mixin({
data() {
return {
x: 10,
y: 20
}
},
})

//
Vue.prototype.hello = () => {
alert(666)
}
}
}
  1. main.js
1
2
3
import Vue from "vue";
import plugins from "./plugins";
Vue.use(plugins,1,2)

scoped 样式

让样式局部生效,<style scoped>

todoList案例

eventBus,消息订阅,Vuex===>兄弟之间数据通信

  1. 组件化编码流程
    • 拆分为各个组件
    • 数据传输,共享
  2. props适用
    • 父=====>子
    • 子=====>父 通信(要求父先给子一个函数)
  3. 适用v-model是切记,v-model绑定的值不能是props(只读)传过来的值
  1. props传过来的若是对象类型,修改的对象中的属性时Vue不会报错,但是不推荐这么做

web Storage

  1. 存储的内容大小一般为(5MB)左右(依浏览器)
  2. 浏览器通过,sessionStorage,localStorage,属性实现本地存储
  3. 相关api:xxxStorage.setItem('key','val')设置存储的键值,xxxStorage.getItem('key')获取键对应的值,xxxStorage.removeItem('key')移除键值,xxxStorage.clear()清空存储的所有数据
  4. 备注:
    • sessionStorage存储的内容会随浏览器窗口的关闭而自动清除
    • localStorage存储的内容(永久性),需手动清除
    • getItem('key'),如果key对应的值不存在则返回null
    • 若存储的是对象记得用 JSON.Stringify()转为字符串,使用的时候用JSON.parse()解析为对象

组件的自定义事件(通信方式)

  1. 适用于:子—->父
  2. 第一种:子父组件中<Demo @test="test"></Demo>,@test表示子组件的自定义事件,test表示父组件接受的事件
  3. 第二种
    1
    2
    3
    mounted(){
    this.$refs.xxx.on('xxx',this.test)
    }
  4. 若想让自定义事件执行一次需要用once,或$once
  5. 触发自定义事件this.$emit('xxx',数据),解绑自定义事件this.$off('xxx')
  6. 组件绑定原生DOM事件,需要用native修饰符
  7. 通过this.$refs.xxx.$on('xxx',回调)回调要么配置在methods中要么用箭头函数,否则this指向会出问题

全局事件总线(GlobalEventBus)

  1. 适应于任意组之间的同信
  2. 安装

    1
    2
    3
    4
    5
    6
    7
    new Vue({
    el: '#app',
    render: h => h(App),
    beforeCreate() {
    Vue.prototype.$bus = this
    }
    })
  3. 使用

    发送数据

1
2
3
4
5
methods: {
giveVal() {
this.$bus.$emit('test', 数据)
}
}

接受数据

1
2
3
4
5
mounted() {
this.$bus.$on('test', (val)=>{
console.log(val);
})
},
  1. 最好在beforeDestroy中,用$off解除当前绑定的事件

消息订阅与发布(pubsub)

  1. 适用于任意组件同信
  2. 安装:npm i pubsub-js,引入:import pubsub from 'pubsub-js'
  3. 发布消息
    1
    pubsub.publish('xxx',数据)
  4. 订阅消息
    1
    2
    3
    4
    5
    6
    mounted(){
    this.pid=pubsub.subscribe('xxx',(msgData,data)=>{
    // msgData 订阅号(xxx)
    // data 订阅的东西(数据)
    })
    }
  5. 取消订阅:在beforeDestroy里,pubsub.unsubscribe(this.pid)

$nextTick

  1. this.$nextTick(callback)
  2. 在下一次dom更新后执行其回调
  3. 当改变数据后,要基于更新后的dom进行某些操作,要用到nextTick

Vue过度和动画

  1. 内部组件transition
  2. 第三方库,npm install animate.css --save,animate.css
    1
    2
    3
    4
    <transition-group name="h" appear="">
    <h2 v-show="!isShow" key="1" class="rounded">Hello1</h2>
    <h2 v-show="isShow" key="2" class="rounded">Hello2</h2>
    </transition-group>

配置代理 axios

跨域

  1. cors
  2. jsonp
  3. 代理Proxy nginx 代理服务器反向代理,负载均衡

插槽

子组件挖坑,父组件填坑

  1. 默认插槽
    <slot></slot>,占位
  2. 具名插槽
    <slot name='xxx'></slot>
  3. 作用域插槽
    • <slot :test="test"></slot>
    • <template scope="getData"></template>,使用{{getData.data}}

Vuex

vuex
vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import Vuex from 'vuex'

export default new Vuex.Store({
state: {
// 定义了应用状态的数据结构,可以在这里设置默认的初始状态
},
getters: {
// 定义了应用状态的数据结构,可以在这里设置默认的初始状态
// 加工数据相当于计算属性
},
mutations: {
// commit
// 唯一更改store中状态的方法,且必须是同步函数;
},
actions: {
// dispatch
// 用于提交mutation,而不是直接更改状态,包含异步操作;
},
modules: {
// 允许将单一的store拆分为多个store且同时保存在单一的状态树。
}
})

state

  1. 全局数据共享状态,相当于data
  2. 读取数据,映射为计算属性
    • this.$store.state.num
    • ...mapState({}) 对象形式
    • ...mapState([]) 数组形式

getters

  1. 对state中的数据进行加工,相当于计算属性
  2. 读取数据
    • this.$store.getters.xxx
    • ...mapGetters({})
    • ...mapGetters([])

mutations

  1. 在methods中, 唯一更改store中状态的方法(同步)
  2. 读取数据
    • this.$store.commit()
      ...mapMutations({})
    • ...mapMutations([])

actions

  1. 用于提交mutation(异步)
  2. 读取数据
    • this.$store.dispatch()
    • ...mapActions({})
    • ...mapActions([])

modules

  1. 将单一的store拆分为多个store
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

    const modeleA = {
    state: {
    s: 'I am modelueA'
    },
    getters: {

    },

    mutations: {

    },
    actions: {

    }
    }

    const modeluB = {
    state: {

    },
    getters: {

    },

    mutations: {

    },
    actions: {

    }
    }

    export default new Vuex.Store({
    modules: {
    a: modeleA,
    b: modeluB
    }
    })
Vuex模块化+namesapce
  1. 开启命名空间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const testModule = {
    namespaced: true,
    state: {
    },
    getters: {
    },
    mutations: {

    },
    actions: {
    },
    }
  2. 组件中读取state数据

    • this.$store.state.testModule.num
    • ...mapState('testModule',['num','xxx'])
  3. 组件中读取getters数据
    • this.$store.getters['testModule/xxx']
    • ...mapGetters('testModule',['xxx'])
  4. 组件中调用commit
    • this.$store.commit('testModule/xxx')
    • ...mapMutations('testModule',['xxx','xxx'])
  5. 组件中调用dispatch
    • this.$store.dispatch('testModule/xxx')
    • ...mapActions('testModule',['xxx','xxx'])

路由

官网

SPA(single page web application)

  1. 安装:npm i vue-router@3 Vue2安装3版本
  2. 应用:Vue.use(VueRouter)
  3. 配置
1
2
3
4
5
6
7
8
9
import VueRouter from "vue-router";
const routes = [
{ path: '/', name: 'Home', component: () => import('../views/Home') },
{ path: '/about', name: 'About', component: () => import('../views/About') }
]
export default new VueRouter({
routes
})

  1. <router-link to="" active-class=""></router-link> 配置路由切换
  2. <router-view></router-view> 组件的呈现位置
  3. 每次切换都伴随着组件的销毁和挂载
  4. 每个组件都有自己的$route属性,记录着自己的路由信息
  5. 整个应用只有一个router,可以通过组件的$router属性获取
  6. 多级路由,嵌套

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    path: '/home',
    name: 'Home',
    component: () => import('../views/Home'),
    directive: '/message',
    children: [
    { path: 'message', name: 'Message', component: () => import('../views/Message') },
    { path: 'news', name: 'News', component: () => import('../views/News') }
    ]
    },
  7. <router-link class="nav-link" active-class="active" aria-current="page" to="/home/message">message</router-link>

简化路由
  1. 给routes里的每一项加name属性
  2. 原来写法:<router-link :to="/home/message/detail?id=${lst.id}&title=${lst.title}">{{lst.title}}</router-link>
  3. 现在写法:<router-link :to="{name:'detail',query:{id:lst.id,title:lst.title}}">{{lst.title}}</router-link>
路由的参数携带
  1. query
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1.直接传递
<router-link :to="`/home/message/detail?id=${lst.id}&title=${lst.title}`">
{{lst.title}}
</router-link>

// 2.对象形式
<router-link :to="{
name:'detail',
// path:'/home/message/detail',
query:{
id:lst.id,
title:lst.title
}
}">
{{lst.title}}
</router-link>
  1. params
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 1.直接传递
<router-link :to="`/home/message/detail/${lst.id}/${lst.title}`">
{{lst.title}}
</router-link>

// 2.对象形式
<router-link :to="{
name:'detail',
params:{
id:lst.id,
title:lst.title
}
}">
{{lst.title}}
</router-link>
  1. 接收数据🎉
    this.$route.query/params.xxx
路由props
1
2
3
4
5
6
7
8
9
10
11

<router-link :to="{
name:'detail',
// path:'/home/message/detail',
query/params:{
id:lst.id,
title:lst.title
}
}">
{{lst.title}}
</router-link>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

{
path: 'detail',
// path: 'detail/:id/:title', params传递
name: 'detail',
component: () => import('../views/Detail'),
// props第一种写法,值为对象,该对象中所有key-value都会以props的形式传递给Detail组件
// props: { id: 'id', title: 'title' } 东西是写死的不好

// prosp第二种,boolean,若为真,会把给路由的params参数传递给组件,query不行
props: true,

// props第三种,作为函数
props($route) {
return {
id: $route.query.id,
title: $route.query.title
}
}
}
  1. 控制路由跳转是操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种:push,repalce,push是追加记录模式,replace是替换当前记录模式,默认为push
  3. 开启replace,<router-link repalce></router-link>
  4. 就是一个入栈与出站的操作
编程式路由导航
  1. push,replace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
methods: {
pushShow(lst) {
this.$router.push({
name: 'detail',
// path:'/home/message/detail',
query: {
id: lst.id,
title: lst.title
}
})
},
replaceShow(lst) {
this.$router.replace({
name: 'detail',
query: {
id: lst.id,
title: lst.title
}
})
}
}
  1. back(),forward(),go()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    methods: {
    // 后退
    back() {
    this.$router.back()
    },
    // 前进
    forward() {
    this.$router.forward()
    },
    go() {
    //前进或,后退n步
    this.$router.go(-2)
    }
    }
缓存

让对应组件路由保持挂载,不销毁

1
2
3
4
 <!-- 缓存include='xxx' xxx是组件名也就是组件中的name属性-->
<keep-alive include="xxx">
<router-view></router-view>
</keep-alive>