Vue

Vue.js

Vue介绍

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue是一个渐进式的框架:

渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来丰富的交互体验。

生命周期

f9354e10221d4e6c905f04fb66c17698

vue 安装

方法一:直接CDN引入

1
2
3
4
5
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

方法二:下载和引入

官网下载地址:https://cn.vuejs.org/v2/guide/installation.html

方法三:npm安装

1
2
# 最新稳定版
$ npm install vue

入门案例:

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<h1>{{message}}</h1>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
message: 'HelloVue'
}
})
</script>

v-for列表循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<ul>
<li v-for = "item in movies">{{item}}</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
movies: ['aaa', 'bbb', 'ccc']
}
})
</script>

案例:计数器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<h1>当前计数:{{counter}}</h1>
<button @click="add">+</button><button v-on:click="sub">-</button>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
counter: 0
},
methods: { //定义方法
add: function(){
this.counter ++
},
sub: function(){
this.counter--
}
}
})
</script>

@click=”方法名”或者v-on:click=”方法名”

MVVM

1.1基本概念MVVM是Model-View-ViewModel的缩写,表示模型-视图-视图模型。模型层主要负责处理交互请示并返回响应的数据;视图层主要负责展示视图;视图-模型层起到前两者的桥梁作用,一方面响应用户事件并向模型层发送请求,另一方面将模型层返回的数据通过数据绑定在视图中展示。

1.2与MVC模式的区别1.MVVM模式本质上是MVC模式的改进版,MVVM有着最为独特的一个特性,那就是数据绑定;2.MVC模式是系统架构级别的,MVVM是用于单页面的,因此,MVVM也更灵活。

MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器)

1、 M:模型层,主要负责业务数据相关;

2、 V:视图层,顾名思义,负视图相关,细分下来就是html+css层;

3、 VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的要点;

image-20220626183745105

MVVM支持双向绑定,意思就是当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改,反之修改V层则会通知M层数据进行修改,以此也实现了视图与模型层的相互解耦;

image-20220626184530531

Mustache语法(双大括号)

v-once

该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变。

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<h1>{{message}}</h1>
<h1 v-once>{{message}}</h1> <!--message的值发生变化,这个不会发生变化-->>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
message: 'HelloVue'
}
})
</script>

v-html

如果我们希望解析出HTML展示,使用v-html标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<div >{{link}}</div>
<div v-text="link"></div>
<div v-html="link"></div>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
link: '<a href="http://www.baidu.com">百度</a>'
}
})
</script>

v-text

将数据显示在页面中

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<div v-text="content">这里的内容会被覆盖掉</div>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
content:'内容'
}
})
</script>

v-pre

v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<h2 v-pre>v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
{{content}}
</h2> <!--{{content}}不会被编译-->
<h2>
{{content}}
</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
content:'内容'
}
})
</script>

v-cloak

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

1
2
3
4
5
<style>
[v-cloak]{
display: none;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<h1>{{content}}</h1>
<h1 v-cloak>{{content}}</h1>
</div>
<script src="js/vue.js"></script>
<script>
//vue解析之前,<div id="app">中有一个v-cloak属性
//vue解析结束之后,v-cloak属性被删除
setTimeout(function (){
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
content:'内容'
}
})
},1000) //延迟加载以后会看到{{content}},渲染之后才会显示真正的内容
</script>

v-bind

某些属性我们也希望动态来绑定。
比如动态绑定a元素的href属性
比如动态绑定img元素的src属性这个时候,我们可以使用v-bind指令:
*作用:动态绑定属性
*缩写: :(v-bind语法糖(简写)也就是:)
*预期:any (with argument)| Object (without argument)口参-数:attrOrProp (optional)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<img :src="imgUrl" width="200px" height="200px">
<img v-bind:src="imgUrl" width="200px" height="200px">
<a :href="url">百度</a>
<a v-bind:href="url">百度</a>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
imgUrl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242306111155-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1658834535&t=722f054e22f82844513def82c53d8491',
url:"http://www.baidu.com"
}
})
</script>

v-bind动态绑定class(1)

1
2
3
4
5
6
7
8
<style>
.active {
background-color: burlywood;
}
.line {
border-bottom: 1px solid red;
}
</style>
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
<div id="app">
<!-- <h2 v-bind:class = "{key1:value1, key2:value2}"></h2>
<h2 v-bind:class="{类名1:true,类名2:boolean}"></h2> -->
<h2 :class="active">{{content}}</h2>
<h2 :class="{active:isActive,line:isLine}">{{content}}</h2>
<button v-on:click="btnClick">点击</button>
<h2 :class="getClass()">{{content}}</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
content:'内容',
active: 'active',
isActive: true,
isLine:true
},
methods :{
btnClick: function(){
this.isActive = !this.isActive
},
getClass: function(){
return {active: this.isActive, line: this.isLine}
}
}

})
</script>

v-bind动态绑定class

对象语法

image-20220626194811684

数组语法

image-20220626194932033

1
2
3
4
5
6
7
<h2 :class="['active']">{{content}}</h2>
<h2 :class="classes">{{content}}</h2>
computed: {
classes: function(){
return [this.active, this.line]
}
}

作业:鼠标点击高亮显示

1
2
3
4
5
<style>
.active {
background-color: brown;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
<ol>
<li v-for="(item,index) in lists" :key="index" :class="{'active':current==index}" @click="addRed(index)">{{item}}</li>
</ol>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
current: -1,
lists:['aaa', 'bbb', 'ccc', 'ddd']
},
methods:{
addRed: function(index){
this.current = index
}
}
})
</script>

v-bind绑定style样式

我们可以利用v-bind:style来绑定一些CSS内联样式,
·在写CSS属性名的时候,比如font-size
1.可以使用驼峰式 (camelCase) fontSize
2.横线分隔(kebab-case,记得用单引号括起来)’font-size‘
绑定class有两种方式:

image-20220626202104488(1)对象语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<!-- <h2 :style="{key(属性名): value(属性值)}">{{content}}</h2> -->
<!-- 50px要加上单引号,否则会被当成变量去解析 -->
<h2 :style="{fontSize:'50px'}">{{content}}</h2>
<h2 :style="{fontSize: fontSize + 'px',backgroundColor:finalColor}">{{content}}</h2>
<h2 :style="getStyles()">{{content}}</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
content:'内容',
fontSize: 50,
finalColor: 'red'
},
methods:{
getStyles:function(){
return {fontSize: this.fontSize + 'px',backgroundColor: this.finalColor}
}
}
})
</script>

(2)数姐语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
<h2 :style="[bck,font]">{{content}}</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
content:'内容',
bck:{backgroundColor: 'red'},
font: {fontSize: '50px'}
},
methods:{
getStyles:function(){
return {fontSize: this.fontSize + 'px',backgroundColor: this.finalColor}
}
}
})
</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
<div id="app">
<h2>{{firstName + ' '+ lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{fullName}}</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
firstName: 'zhang',
lastName: 'san'
},
methods: {
getFullName : function(){
return this.firstName + ' '+ this.lastName
}
},
computed: {
fullName: function(){
return this.firstName + ' '+ this.lastName
}
}
})
</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
<div id="app">
<h2 >{{sumPrice}}</h2>
<h2>{{Allprice}}</h2>
<h2>{{prices}}</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
books:[
{id:100, name:'aaa', price:100},
{id:101, name:'bbb', price:86},
{id:102, name:'ccc', price:130},
]
},
computed: {
sumPrice: function(){
sum = 0
for(let i = 0; i < this.books.length; i++){
sum += this.books[i].price
}
return sum
},

Allprice: function(){
sum = 0
for(let i in this.books){
sum += this.books[i].price
}
return sum
},
prices: function(){
sum = 0
for(let item of this.books){
sum += item.price
}
return sum
},
totalPrice(){
//使用高级函数
return this.books.reduce((total, n)=>{
return total + n.price
}, 0)
}
}
})
</script>

计算属性的setter和getter

计算属性一般是没有set方法的,只读属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
firstName: 'zhang',
lastName: 'san'
},
computed:{
fullName:{
get(){
console.log('调用了fullName的get')
return this.firstName+ ' ' + this.lastName
},
set(newValue){
console.log('调用了fullName的set')
const names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[1]
}
}
}
})

在控制台输入app.fullName = “li si”,即可调用计算属性的set和get方法

计算属性的缓存

image-20220626205250229

使用函数会调用多次,而计算属性只会调用一次

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
<div id="app">
<h1>{{fullName}}</h1>
<h1>{{fullName}}</h1>
<h1>{{fullName}}</h1>
<h1>{{getfullName()}}</h1>
<h1>{{getfullName()}}</h1>
<h1>{{getfullName()}}</h1>
<h1>{{getfullName()}}</h1>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
firstName: 'zhang',
lastName: 'san'
},
methods:{
getfullName(){
console.log('getfullName方法调用')
return this.firstName + ' ' + this.lastName
}
},
computed:{
fullName:{
get(){
console.log('计算属性调用fullName的get')
return this.firstName+ ' ' + this.lastName
}
}
}
})
</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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<h2>今天的天气很{{info}}</h2>
<button @click="isHot = !isHot">切换天气</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
isHot: false,
},
computed: {
info() {
return this.isHot ? "炎热" : "凉爽";
}
}
})
</script>
</body>
</html>

监视属性watch:

1.当被监视的属性变化时,回调函数自动调用,进行相关操作

2.监视的属性必须存在,才能进行监视!!

3.监视的两种写法:
(1).new Vue时传入watch配置 (2).通过vm.$watch监视

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h2>今天的天气很{{info}}</h2>
<button @click="isHot = !isHot">切换天气</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
isHot: false,
},
computed: {
info() {
return this.isHot ? "炎热" : "凉爽";
}
},
// watch: {
// isHot: { //原始写法这里是带引号的,所以最好加上引号
// immediate: true, // 初始化时让handler调用一下
// handler(newValue, oldValue) { // 当isHot发生变化时,handler调用
// console.log('isHot被修改了',newValue, oldValue);
// }
// }
// }
})
vm.$watch('isHot',{
immediate: true, // 初始化时让handler调用一下
handler(newValue, oldValue) { // 当isHot发生变化时,handler调用,newValue代表新的值,oldValue代表原来的值
console.log('isHot被修改了',newValue, oldValue);
}
})
</script>
</body>
</html>

深度监视:

(1).Vue中的watch默认不监测对象内部值的改变(一层)。

(2).配置deep:true可以监测对象内部值改变(多层)。

备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!

(2).使用watch时根据数据的具体结构,决定是否采用深度监视。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h2>a:{{numbers.a}}</h2>
<button @click="numbers.a++">add</button>
<br/>
<h2>b:{{numbers.b}}</h2>
<button @click="numbers.b++">add</button>
<br/>
<button @click="numbers={a:999,b:999}">彻底改变numbers</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
numbers: {
a: 1,
b: 1
}
},
watch: {
// 监听多级层次结构中某个属性的变化
'numbers.a': {
handler(newValue, oldValue) {
console.log("a被改变了")
}
},
// 检测多级层次结构中多有属性的改变(a,b属性改变都会触发)
numbers: {
deep: true,
handler(newValue, oldValue) {
console.log("numbers被改变了")
}
}
}
})
</script>
</body>
</html>

简写

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h2>今天的天气很{{info}}</h2>
<button @click="isHot = !isHot">切换天气</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
isHot: false,
},
computed: {
info() {
return this.isHot ? "炎热" : "凉爽";
}
},
// 完整写法
// watch: {
// isHot: {
// immediate: true, // 初始化时让handler调用一下
// handler(newValue, oldValue) { // 当isHot发生变化时,handler调用
// console.log('isHot被修改了',newValue, oldValue);
// }
// }
// }

// 简写,这时候不能用其他属性,相当于直接使用handler方法
watch: {
isHot(newValue, oldValue) {
console.log('isHot被修改了',newValue, oldValue);
},
// isHot: (newValue, oldValue) => { 如果使用的是箭头函数,this指向的是windows
// console.log('isHot被修改了',newValue, oldValue,this);
// }
}
})
// 完整写法
// vm.$watch('isHot',{
// immediate: true, // 初始化时让handler调用一下
// handler(newValue, oldValue) { // 当isHot发生变化时,handler调用,newValue代表新的值,oldValue代表原来的值
// console.log('isHot被修改了',newValue, oldValue);
// }
// })

// 简写,
// vm.$watch('isHot',function(newValue, oldValue) {
// console.log('isHot被修改了',newValue, oldValue);
// })
</script>
</body>
</html>

姓名案例:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
{{fullName}}
</div>
<script>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: '',
fullName: ''
},
watch: {
firstName(newValue) {
this.fullName = newValue + this.lastName;
},
lastName: {
handler(newValue){
this.fullName = this.firstName + newValue;
}
}
}
})
</script>
</body>
</html>

computed和watch之间的区别:

1.computed能完成的功能,watch都可以完成。

2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作.

两个重要的小原则:

1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。

2.所有不被Vue所管理的函数(定时器的回调函数、Ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm或组件实例对象.

绑定样式

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
<body>
<!--
绑定样式:
1.class样式
写法:class=" xxx"xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2. style样式
:style="{fontSize: xxx}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象。
-->
<div id="app">
<!--绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定-->
<div class="basic" :class="normal">样式</div>

<!--绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定-->
<!--<div class="basic" :class="['c1','c2','c3']">样式2</div> 需要加引号,不加引号找的是变量对应的值-->
<div class="basic" :class="classArr">样式2</div>

<!--绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用-->
<div class="basic" :class="classObj">样式3</div>

<!--:style="{fontSize: xxx}"其中xxx是动态值。-->
<!--<div :style="{fontSize: fontsize + 'px'}">style样式</div>-->
<div :style="styleObj">style样式</div>

<!--:style="[a,b]"其中a、b是样式对象。-->
<div :style="[styleObj,styleObj2]">style数组样式</div>


</div>
<script>
const app = new Vue({
el: '#app',
data: {
normal: 'normal',
classArr: ['c1', 'c2', 'c3'],
classObj: {
c1: true,
c2: false,
c3: true
},
fontsize: 40,
styleObj: {
color: 'red',
backgroundColor: 'orange'
},
styleObj2: {
fontSize: 50 + 'px'
}
}
})
</script>
</body>

事件监听

v-on

情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。
但是注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
情况二:如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。

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
<div id="app">
<h2>{{count}}</h2>
<!-- <button v-on:click="count++">+</button>
<button v-on:click="count--">-</button> -->
<!-- 1.事件调用的方法没有参数 -->
<!-- 2.在时间定义时,写方法时省略了小括号,但是方法本身是需要一个参数的,Vue会
默认将浏览器产生的event事件作为参数传入到方法 -->
<button @click="btnClick">点击事件</button>
<button @click="btnClick()">点击事件</button>

<!-- 3.方法定义时,我们需要event对象,同时又需要其他参数
调用方法,手动获取到浏览器的event对象
-->
<button @click="increment(2)">+</button>
<button @click="decrement(10, $event)">-</button>

</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
increment(num){
console.log(event)
this.count += num
},
decrement(num, event){
console.log(event)
this.count -= num
},
btnClick(){
console.log(event)
console.log('点击事件')
}
}
})
</script>

v-on修饰符

image-20220627190202627

.stop阻止冒泡

1
<div @click.stop="ziDivClick" ></div>

.prevent阻止默认行为

1
2
3
4
  <!-- 2. .prevent修饰符的使用 -->
<form action="baidu">
<input @click.prevent="formSubmit()" type="submit" value="提交">
</form>

.once只调用一次

1
2
<!-- 4. .once只触发一次回调 -->
<button @click.once="btnClick">只会调用一次</button>

代码:

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
<div id="app">
<!-- 1.stop修饰符的使用 -->
<div @click="fuDivClick"class="fu">
<!-- 点击子类事件时,会发生冒泡,触发父类事件 -->
<!-- <div @click="ziDivClick" ></div> -->
<!-- 停止冒泡 -->
<div @click.stop="ziDivClick" ></div>
</div>

<!-- 2. .prevent修饰符的使用 -->
<form action="baidu">
<input @click.prevent="formSubmit()" type="submit" value="提交">
</form>

<!-- 3.键盘某个键盘的键帽 -->
<input type="text" @keyup.enter="keyUp">

<!-- 4. .once只触发一次回调 -->
<button @click.once="btnClick">只会调用一次</button>
</div>

<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
ziDivClick(){
console.log('子类div被点击了')
},
fuDivClick(){
console.log('父类div被点击了')
},
formSubmit(){
console.log('表单提交')
},
keyUp(){
console.log('提交')
},
btnClick(){
console.log('只会调用一次')
}
}
})
</script>

条件判断

image-20220627192019491

v-if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
<h2 v-if="isShow">
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
</h2>
<h2 v-if="false">不会显示</h2>
<h2 v-if="true">会显示</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isShow: true
}

})
</script>

v-else

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
<div id="app">
<h2 v-if="isShow">
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
</h2>
<h2 v-else>
isShow为false是显示
</h2>
<button @click="btnClick">点击</button>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isShow: true
},
methods:{
btnClick() {
this.isShow = !this.isShow
}
}
})
</script>

v-else-if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<h2 v-if="score>=90">优秀</h2>
<h2 v-else-if="score>=80">良好</h2>
<h2 v-else-if="score>=70">中等</h2>
<h2 v-else-if="score>=60">及格</h2>
<h2 v-else>不及格</h2>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
score: 89
}

})
</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
<div id="app">
<span v-if="isUser">
<label>账号</label>
<!-- 加上可以属性时,切换就不会保留原来输入的值了 -->
<input type="text" placeholder="请输入账号" key="username">
</span>
<span v-else>
<label>邮箱</label>
<input type="email" placeholder="请输入邮箱" key="email">
</span>
<button @click="btnClick">切换类型</button>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
},
methods: {
btnClick(){
this.isUser = !this.isUser
}
}
})
</script>
  • 小问题:
    如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入的内容。
    但是按道理讲,我们应该切换到另外一个input元素中了。
    在另一个input元素中,我们并没有输入内容。

  • 为什么会出现这个问题呢?

  • 问题解答:
    这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。
    在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。

  • 解决方案:
    如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key
    并且我们需要保证key的不同

v-show

v-show当条件为false时,只是给元素添加了行内样式display:none

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<h2 v-if="isShow">
isShow为True显示
</h2>
<h2 v-else> isShow为fasle显示</h2>
<h2 v-show="isShow">v-show显示</h2>
<button @click="btnClick">点击</button>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isShow: true
},
methods:{
btnClick() {
this.isShow = !this.isShow
}
}

})
</script>

v-show和v-if对比

v-show的用法和v-if非常相似,也用于决定一个元素是否渲染:
v-if和v-show对比
v-if和v-show都可以决定一个元素是否渲染,那么开发中我们如何选择呢?

  • v-if当条件为false时,压根不会有对应的元素在DOM中。
    v-show当条件为false时,仅仅是将元素的display属性设置为none而已。
    开发中如何选择呢?
  • 当需要在显示与隐藏之间切片很频繁时,使用v-show
    当只有一次切换时,通过使用v-if

循环遍历

v-for遍历数组

image-20220627194855718

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<ul>
<li v-for = "item in movies">{{item}}</li>
</ul>
<ul>
<li v-for = "(item, index) in movies">{{index+1}}-{{item}}</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
movies: ['aaa', 'bbb', 'ccc']
}
})
</script>

v-for循环遍历对象

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
<div id="app">
<ul>
<!-- 1.在遍历对象的过程中,如果只是获取一个值,name获取的是value -->
<li v-for = "value in obj">{{value}}</li>
</ul>
<ul>
<!-- 2.获取key,value 格式:(value,key) -->
<li v-for = "(value, key) in obj">{{key}}-{{value}}</li>
</ul>
<ul>
<!-- 3.获取key,value,index 格式:(value, key, index) -->
<li v-for = "(value, key, index) in obj">{{key}}-{{value}}--{{index}}</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', //用于挂载要管理的元素
data: { //定义数据
obj:{
name:'lisi',
age: 18,
height: 188
}
}
})
</script>

image-20220627215000810

检测数组更新

​ 因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新。
Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新

  • push() 数组末尾添加元素

    1
    2
    3
    //1.push方法,数组末尾添加元素
    this.list.push('eee')
    this.list.push('eee', 'fff', 'ggg')
  • pop() 删除数组中的最后一个元素

    1
    2
    //2.pop()删除数组中的最后一个元素
    this.list.pop()
  • shift() 删除数组中的第一个元素

    1
    2
    //3.删除数组中的第一个元素
    this.list.shift()
  • unshift() 在数组最前面添加元素

    1
    2
    3
    //4..unshift()在数组最前面添加元素
    this.list.unshift('000')
    this.list.unshift('000','111','222')
  • splice()删除元素/插入元素/替换元素
    1.删除元素:第一个参数:从这个索引后面开始删除
    第二个参数:传入要删除几个元素(如果没有传,就删除后面所有元素)
    2.替换元素:第二个参数:标识我们要替换几个元素,后面就是用于替换前面的元素
    3.插入元素:第二个参数:传入0,并且后面跟上要插入的元素

  •   //5.splice()作用:删除元素/插入元素/替换元素
                        //删除元素:第一个参数:从这个索引后面开始删除
                        //         第二个参数:传入要删除几个元素(如果没有传,就删除后面所有元素)
                        //替换元素:第二个参数:标识我们要替换几个元素,后面就是用于替换前面的元素
                        //插入元素:第二个参数:传入0,并且后面跟上要插入的元素
                        const start = 1
                        this.list.splice(start)  //删除start后面所有的元素
                        this.list.splice(start,2)  //删除start后的两个元素
                        
                        this.list.splice(start, 2 ,'ffff')  //只传一个就只会替换一个
                        this.list.splice(start, 2 ,'fff', 'fff', 'fff')  //会替换两个,再插入一个
                        
                        this.list.splice(start,0, 'x','y')  //插入
      
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13



    * sort() 排序

    ```javascript
    this.list.sort()
    this.list.sort((a,b)=>{
    return a-b // 升序
    })
    this.list.sort((a,b)=>{
    return b-a // 降序
    })
  • reverse() 反转

    1
    this.list.reverse()
  • filter() 过滤 返回一个新数组

    1
    2
    3
    this.list.filter((p)=>{
    return 条件
    })

    注意:

    1
    2
    3
     this.list[0] = '1111111'  //通过这个修改方式修改无效,
    this.list[0].name = "zhangsan" //这种可以
    this.list[0] = {name:"张三",age:15} //不可以

    Vue数据监测原理

    image-20220821102752928

    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
        
    let data = {
    name : "张三",
    age : 14
    }
    // 创建一个监视的实例对象,用于监视data中属性的变化
    const obs = new Observer(data);
    console.log(obs);

    // 准备一个vm实例
    let vm = {}
    vm._data = data = obs

    function Observer(obj) {
    // 汇总对象中所有属性形成一个数组
    const keys = Object.keys(obj);
    // 遍历
    keys.forEach((k) => {
    Object.defineProperty(this,k,{
    get() {
    return obj[k]
    },
    set(val) {
    console.log(`${k}被改变了,我要去解析模板,生成虚拟DOM....`)
    obj[k] = val
    }
    })
    })
    }

    Vue.set

    1
    2
    //    this.list.splice(0, 1 ,'1111')
    Vue.set(this.list, 0, '1111') //修改索引为0的值

    列表过滤

    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
    <script type="text/javascript">
    Vue.config.productionTip = false

    //用watch实现
    //#region
    /* new Vue({
    el:'#root',
    data:{
    keyWord:'',
    persons:[
    {id:'001',name:'马冬梅',age:19,sex:'女'},
    {id:'002',name:'周冬雨',age:20,sex:'女'},
    {id:'003',name:'周杰伦',age:21,sex:'男'},
    {id:'004',name:'温兆伦',age:22,sex:'男'}
    ],
    filPerons:[]
    },
    watch:{
    keyWord:{
    immediate:true,
    handler(val){
    this.filPerons = this.persons.filter((p)=>{
    return p.name.indexOf(val) !== -1
    })
    }
    }
    }
    }) */
    //#endregion

    //用computed实现
    new Vue({
    el:'#root',
    data:{
    keyWord:'',
    persons:[
    {id:'001',name:'马冬梅',age:19,sex:'女'},
    {id:'002',name:'周冬雨',age:20,sex:'女'},
    {id:'003',name:'周杰伦',age:21,sex:'男'},
    {id:'004',name:'温兆伦',age:22,sex:'男'}
    ]
    },
    computed:{
    filPerons(){
    return this.persons.filter((p)=>{
    return p.name.indexOf(this.keyWord) !== -1
    })
    }
    }
    })
    </script>

    图书购物车案例

    filters过滤器使用

1
<td>{{item.price | showPrice}} </td>
1
2
3
4
5
filters:{
showPrice(price){
return '¥'+ price.toFixed(2)
}
}

image-20220628133156878

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
table{
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th,td {
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th{
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
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
<div id="app">
<div v-if="books.length">
<table>
<thead>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="(item, index) in books" :key="index">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}} </td>
<td>{{item.price | showPrice}} </td>
<td><button @click="increment(index)">+</button>{{item.count}}<button :disabled="item.count <= 0" @click="decrement(index)">-</button></td>
<td><button @Click="removeBook(index)">移除</button></td>
</tr>
</tbody>
</table>
<h2>总价格:{{totalPrice | showPrice}}</h2>
</div>
<h2 v-else>图书列表为空</h2>
</div>

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
const app = new Vue({
el: '#app',
data: {
books: [
{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85.00,
count: 1
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-2',
price: 59.00,
count: 1
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39.00,
count: 1
},
{
id: 4,
name: '《代码大全》',
date: '2006-3',
price: 128.00,
count: 1
},
]
},
methods:{
increment(index){
this.books[index].count ++
},
decrement(index){
this.books[index].count --
},
removeBook(index){
this.books.splice(index,1)
}
},
filters: {
showPrice(price){
return '¥'+ price.toFixed(2)
}
},
computed: {
// totalPrice(){
// let sum = 0;
// for (let item of this.books){
// sum += item.count * item.price;
// }
// return sum
// }
totalPrice(){
return this.books.reduce(function(preValue, book){
return preValue +book.count* book.price
},0 )
}
}
})

自定义指令

  1. 注册全局指令
1
2
3
Vue.directive('my-directive', function(el, binding){
el.innerHTML = binding.value.toupperCase()
})
  1. 注册局部指令
1
2
3
4
5
6
7
directives : {
'my-directive' : {
bind (el, binding) {
el.innerHTML = binding.value.toupperCase()
}
}
}
  1. 使用指令
    v-my-directive=’xxx’
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
<body>
<div id="app">
<h2>{{name}}</h2>
<h2>当前的n值是:<span v-text="n"></span></h2>
<h2>放大10倍n值是:<span v-big="n"></span></h2>
<button @click="n++">点我n+1</button>
<input type="text" v-fbind="n">
</div>
<script>
new Vue({
el:'#app',
data: {
name: "张三",
n: 1
},
directives: {
// big什么时候会被调用:
// 1.指令与元素成功绑定时,
// 2.指令所在的模板被重新解析时
big(element, binding) { // 简写,相当于bind()和update()
console.log('big')
console.log(element, binding)
element.innerText = binding.value * 10
},
fbind: { // 完整写法
// 指令与元素成功绑定时
bind(element, binding){
element.value = binding.value
},
// 指令所在元素被插入页面时
inserted(element, binding){
element.focus()
},
// 指令所在的模板被重新解析时
update(element, binding){
element.value = binding.value
}
}
}
})
</script>

v-model

Vue中使用v-model指令来实现表单元素和数据的双向绑定。

  • 案例的解析:
    当我们在输入框输入内容时
    因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message发生改变。
    当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
    所以,通过v-model实现了双向的绑定。
    当然,我们也可以将v-model用于textarea元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>

<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>

v-model原理

v-model其实是一个语法糖,它的背后本质上是包含两个操作:

  • 1.v-bind绑定一个value属性
  • 2.v-on指令给当前元素绑定input事件
1
2
3
<input type="text" v-model="message">
等同于
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<input type="text" :value="message" @input="inputChange">
{{message}}
<input type="text" :value="message2" @input="message2 = $event.target.value">
{{message2}}
</div>

<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
message2: 'hello'
},
methods: {
inputChange(){
this.message = event.target.value;
}
}
})
</script>

v-model:ratio

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
<div id="app">
<!-- 加上相同的name就可以实现单选 -->
<!-- <input type="radio" name="sex" value="男">男
<input type="radio" name="sex" value="女">女 -->

<label for="male">
<input type="radio" id="male" value="男" v-model="sex">
</label>
<label for="female">
<input type="radio" id="female" value="女" v-model="sex">
</label>
<h2>您选择的性别是: {{sex}}</h2>
</div>

<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
sex:'男'
},
methods: {

}
})
</script>

v-model:checkbox

  • 复选框分为两种情况:单个勾选框和多个勾选框
  • 单个勾选框:
    • v-model即为布尔值。
    • 此时input的value并不影响v-model的值。
1
2
3
4
5
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>您选择的是: {{isAgree}}</h2>
<button :disabled="!isAgree">下一步</button>
  • 多个复选框:
    • 当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
      当选中某一个时,就会将input的value添加到数组中。
1
2
3
4
5
6
7
8
9
10
 <!--2.checkbox多选框-->
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<h2>您的爱好是: {{hobbies}}</h2>
data: {
isAgree: true,
hobbies:[]
},

v-model结合select类型

  • 和checkbox一样,select也分单选和多选两种情况。
  • 单选:只能选中一个值。
    • v-model绑定的是一个值。
    • 当我们选中option中的一个时,会将它对应的value赋值到melect中
1
2
3
4
5
6
7
8
9
10
11
12
<!--1.选择一个-->
<select name="abc" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruit}}</h2>
data: {
fruit: '香蕉',
fruits: []
}
  • 多选:可以选中多个值。
    • v-model绑定的是一个数组。
    • 当选中多个值时,就会将选中的option对应的value添加到数组mySelect
1
2
3
4
5
6
7
8
9
10
11
12
<!--2.选择多个-->
<select name="abc" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruits}}</h2>
data: {
fruit: '香蕉',
fruits: []
}

:value值绑定

lazy修饰符:

  • 默认情况下,v-model默认是在input事件中同步输入框的数据的。

  • 也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。

  • lazy修饰符可以让数据在失去焦点或者回车时才会更新

    1
    2
    <input type="text" v-model.lazy="message" >
    {{message}}

number修饰符:

  • 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
  • 但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。
  • number修饰符可以让在输入框中输入的内容自动转成数字类型:
1
2
<input type="number" v-model.number="age" >
<h2>{{age}}-{{typeof age}}</h2>

trim修饰符:

  • 如果输入的内容首尾有很多空格,通常我们希望将其去除
  • trim修饰符可以过滤内容左右两边的空格
1
2
<input type="text" v-model.trim="name">
<h2>您输入的名字:{{name}}</h2>

组件化开发

image-20220628151133929

注册组件基本步骤

  • 组件的使用分成三个步骤:

    • 创建组件构造器

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      // 1.创建组件构造器对象
      const cnp = Vue.extend({
      template:`
      <div>
      <h2>我是标题</h2>
      <p>我是内容,哈哈哈哈哈</p>
      <p>我是内容,呵呵呵呵呵</p>
      </div>
      `
      })
    • 注册组件

      1
      2
      //2.注册组件
      Vue.component('my-cpn', cnp)
    • 使用组件

      1
      2
      <my-cpn></my-cpn>
      <my-cpn></my-cpn>
  • 1.Vue.extend():
    调用Vue.extend()创建的是一个组件构造器。
    通常在创建组件构造器时,传入template代表我们自定义组件的模板。
    该模板就是在使用到组件的地方,要显示的HTML代码。
    事实上,这种写法在Vue2.x的文档中几乎已经看不到了,它会直接使用下面我们会讲到的语法糖,但是在很多资料还是会提到这种方式,而且这种方式是学习后面方式的基础。

  • 2.Vue.component():
    调用Vue.component()是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。
    所以需要传递两个参数:1、注册组件的标签名 2、组件构造器

  • 3.组件必须挂载在某个Vue实例下,否则它不会生效。(见下页)
    我们来看下面我使用了三次
    而第三次其实并没有生效:

全局组件和局部组件

调用Vue.component()注册组件时,组件的注册是全局的

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
<div id="app">
<cnp></cnp>
<cnp></cnp>
</div>
<hr>
<div id="app2">
<cnp></cnp>
<cnp></cnp>
</div>

<script src="js/vue.js"></script>
<script>
// 1.创建组件构造器对象
const cnp = Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容,哈哈哈哈哈</p>
<p>我是内容,呵呵呵呵呵</p>
</div>
`
})
// //2.注册组件
// Vue.component('cnp', cnp)

const app = new Vue({
el: '#app',
data: {
},
components:{ //局部组件
cnp
}
})
</script>

父组件与子组件

子组件不能访问父组件

在前面我们看到了组件树:
组件和组件之间存在层级关系
而其中一种非常重要的关系就是父子组件的关系
我们来看通过代码如何组成的这种层级关系:

父子组件错误用法:以子标签的形式在Vue实例中使用
因为当子组件注册到父组件的components时,Vue会编译好父组件的模块
该模板的内容已经决定了父组件将要渲染的HTML(相当于父组件中已经有了子组件中的内容了)
是只能在父组件中被识别的。
类似这种用法,是会被浏览器忽略的。

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
<div id="app">
<!-- <cnp></cnp>
<cnp></cnp> -->
</div>
<hr>
<div id="app2">
<cnp></cnp>
<cnp></cnp>
</div>

<script src="js/vue.js"></script>
<script>
// 1.创建组件构造器对象
const cnp = Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容,哈哈哈哈哈</p>
<p>我是内容,呵呵呵呵呵</p>
</div>
`
})
// //2.注册组件
// Vue.component('cnp', cnp)

const app = new Vue({
el: '#app',
data: {
},
components:{
cnp
}
})

const app2 = new Vue({
el: '#app2',
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
<div id="app">
<cnp1></cnp1>
</div>
<hr>
<div id="app2">
<cnp1></cnp1>
</div>
<script src="js/vue.js"></script>
<script>
//注册全局组件
Vue.component('cnp1',{
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容, 哈哈哈哈</p>
</div>
`
})
const app = new Vue({
el: '#app',
data:{

}
})
const app2 = new Vue({
el: '#app2',
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
<div id="app">
<cnp1></cnp1>
<cnp2></cnp2>
</div>
<hr>
<div id="app2">
<cnp1></cnp1>
<cnp2></cnp2>
</div>
<script src="js/vue.js"></script>
<script>
//注册全局组件
Vue.component('cnp1',{
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容, 哈哈哈哈</p>
</div>
`
})
const app = new Vue({
el: '#app',
data:{
},
components:{
'cnp2':{
template: `
<div>
<h2>我是标题2</h2>
<p>我是内容, 哈哈哈哈</p>
</div>
`
}
}
})
const app2 = new Vue({
el: '#app2',
data:{

}
})

</script>

模板的分离写法

刚才,我们通过语法糖简化了Vue组件的注册过程,另外还有一个地方的写法比较麻烦,就是template模块写法。
如果我们能将其中的HTML分离出来写,然后挂载到对应的组件上,必然结构会变得非常清晰。

  • Vue提供了两种方案来定义HTML模块内容:

    • 使用

      image-20220630093942190

      (2)另一种打包方式:(配置入口和出口)

      webpack配置(文件名:webpack.config.js需要自己建)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      const path = require('path')

      module.exports = {
      //入口,可以是字符串/数组/对象,这里我们入口只有一个,所以写一个字符串即可
      entry: './src/main.js',
      //出口,通常是一个对象,里面至少包含两个重要性,path和filename
      output: {
      path: path.resolve(__dirname, 'dist'), //注意:path是一个绝对路径
      filename: 'bundle.js'
      }
      }

      输入命令webpack即可打包:

      1
      webpack

      局部安装webpack

      • 目前,我们使用的webpack是全局的webpack,如果我们想使用局部来打包呢?

      • 因为一个项目往往依赖特定的webpack版本,全局的版本可能很这个项目的webpack版本不一致,导出打包出现问题。

      • 所以通常一个项目,都有自己局部的webpack。

        • 第一步,项目中需要安装自己局部的webpack
          这里我们让局部安装webpack3.6.0

          1
          npm install webpack@3.6.0 --save-dev
        • Vue CLI3中已经升级到webpack4,但是它将配置文件隐藏了起来,所以查看起来不是很方便。

        第二步,通过node_modules/.bin/webpack启动webpack打包

        1
        node_modules/.bin/webpack

      package.json中定义启动

      • 但是,每次执行都敲这么一长串有没有觉得不方便呢?
        • OK,我们可以在package.json的scripts中定义自己的执行脚本。
      • package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。
        • 首先,会寻找本地的node_modules/.bin路径中对应的命令。
        • 如果没有找到,会去全局的环境变量中寻找。

      在psckage.json中配置”build”:”webpack”

      1
      2
      3
      4
      "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "build": "webpack"
      },

      以后就可以通过npm run build来导包

      1
      npm run build

      loader

      • loader是webpack中一个非常核心的概念。
      • webpack用来做什么呢?
        • 在我们之前的实例中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖。
        • 但是,在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等。
          对于webpack本身的能力来说,对于这些转化是不支持的。
        • 那怎么办呢?给webpack扩展对应的loader就可以啦。
        • loader使用过程:
          • 步骤一:通过npm安装需要使用的loader
          • 步骤二:在webpack.config.js中的modules关键字下进行配置
            大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法。
          • 官网:https://www.webpackjs.com/concepts/loaders/

      css文件处理

      • 项目开发过程中,我们必然需要添加很多的样式,而样式我们往往写到一个单独的文件中。
      • 在src目录中,创建一个css文件,其中创建一个normal.css文件。
      • 我们也可以重新组织文件的目录结构,将零散的js文件放在一个js文件夹中。
      • normal.css中的代码非常简单,就是将body设置为red
      • 但是,这个时候normal.css中的样式会生效吗?
        当然不会,因为我们压根就没有引用它。
        webpack也不可能找到它,因为我们只有一个入口,webpack会从入口开始查找其他依赖的文件。

      main.js导入css

      1
      2
      //引入css
      require('./css/normal.css')

      加载css文件必须有对应的loader

      1
      2
      npm install --save-dev css-loader
      npm install --save-dev style-loader

      配置webpack.config.js

      1
      2
      3
      4
      5
      6
      7
      module: {
      rules: [
      { test: /\.css$/,
      use: ['style-loader','css-loader']
      },
      ]
      }

      image-20220630101618449

      出现错误:原因版本不匹配

      image-20220630102104793

      1
      2
      npm install --save-dev css-loader@3.3.0
      npm install --save-dev style-loader@1.0.0

      image-20220630104411256

      less文件处理

      导入less文件

      1
      2
      3
      require('./css/index.less')
      //或者
      import index from './css/index.less'

      less文件

      1
      2
      3
      4
      5
      6
      7
      @fontSize: 50px;
      @fontColor: red;

      body {
      font-size: @fontSize;
      color: @fontColor;
      }

      安装lessloader

      1
      2
      3
      //这个版本不匹配
      npm install --save-dev less-loader less
      npm install --save-dev less-loader@4.1.0

      配置webpack.config.js

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      {
      test: /\.less$/,
      use: [{
      loader: "style-loader", // creates style nodes from JS strings
      }, {
      loader: "css-loader" // translates CSS into CommonJS
      }, {
      loader: "less-loader", // compiles Less to CSS
      }]
      }

      图片文件处理

      url-loader

      1
      2
      npm install --save-dev url-loader
      npm install --save-dev url-loader@1.1.2
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      {
      test: /\.(png|jpg|gif|jpeg)$/,
      use: [
      {
      loader: 'url-loader',
      options: {
      // 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
      // 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
      limit: 8192,
      name: 'img/[name].[hash:8].[ext]'
      },
      }
      ]
      }

      file-loader

      因为大于8kb的图片,会通过file-loader进行处理,但是我们的项目中并没有file-loader

      1
      2
      npm install --save-dev file-loader
      npm install --save-dev file-loader@1.1.5

      修改文件名称

      • 我们发现webpack自动帮助我们生成一个非常长的名字

      • 这是一个32位hash值,目的是防止名字重复

      • 但是,真实开发中,我们可能对打包的图片名字有一定的要求

      • 比如,将所有的图片放在一个文件夹中,跟上图片原来的名称,同时也要防止重复

      • 所以,我们可以在options中添加上如下选项:

        • img:文件要打包到的文件夹
        • name:获取图片原来的名字,放在该位置
        • hash:8:为了防止图片名称冲突,依然使用hash,但是我们只保留8位
        • ext:使用图片原来的扩展名
      • 但是,我们发现图片并没有显示出来,这是因为图片使用的路径不正确

      • 默认情况下,webpack会将生成的路径直接返回给使用者

      • 但是,我们整个程序是打包在dist文件夹下的,所以这里我们需要在路径下再添加一个dist/

      image-20220630113217849

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      {
      test: /\.(png|jpg|gif|jpeg)$/,
      use: [
      {
      loader: 'url-loader',
      options: {
      // 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
      // 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
      limit: 8192,
      name: 'img/[name].[hash:8].[ext]'
      },
      }
      ]
      }

      es6语法处理

      • 如果希望将ES6的语法转成ES5,那么就需要使用babel。
      • 而在webpack中,我们直接使用babel对应的loader就可以了。
      1
      npm install --save-dev babel-loader@7 babel-core@6.26.3 babel-preset-es2015@6.24.1

      webpack.config.js

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      ,
      {
      test: /\.js$/,
      // exclude: 排除
      // include: 包含
      exclude: /(node_modules|bower_components)/,
      use: {
      loader: 'babel-loader',
      options: {
      presets: ['es2015']
      }
      }
      }

      引入Vue.js

      • 我们希望在项目中使用Vuejs,那么必然需要对其有依赖,所以需要先进行安装
      • 注:因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖
      1
      2
      npm install vue --save
      npm install vue@2.5.21 --save

      安装vue-loader和vue-template-compiler

      如果vue-loader超过15以后需要配置VueLoaderPlugin

      1
      2
      3
      4
      npm install vue-loader vue-template-compiler --save-dev
      //下面版本可以用

      npm install vue-loader@13.0.0 vue-template-compiler@2.5.21 --save-dev

      修改webpack.config.js的配置文件:

      1
      2
      3
      4
      5
      ,
      {
      test: /\.vue$/,
      use: ['vue-loader']
      }

      runtime-only ->代码中,不可以有任何的template

      runtime-complier ->代码中,可以有template,因为有complier可以编译template

      image-20220630154252276

      解决方案:

      修改webpack.config.js的配置文件:放在module:的外面和这个是兄弟关系

      1
      2
      3
      4
      5
      6
      7
      resolve: {
      // alias: 别名
      extensions: ['.js', '.css', '.vue'],
      alias: {
      'vue$': 'vue/dist/vue.esm.js'
      }
      }

      补充:el和template区别

      image-20220630154620805

      image-20220630154638050

      Plugin的使用

      添加版权的Plugin

      • 我们先来使用一个最简单的插件,为打包的文件添加版权声明
      • 该插件名字叫BannerPlugin,属于webpack自带的插件。

      image-20220630155426070

      1
      2
      3
      4
      const webpack = require('webpack') 
      plugins: [
      new webpack.BannerPlugin('最终版权归aaa所有'),
      ],

      打包html的plugin

      image-20220630160037542

      1
      2
      npm install html-webpack-plugin --save-dev
      npm install html-webpack-plugin@3.2.0 --save-dev
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      const HtmlWebpackPlugin = require('html-webpack-plugin') 
      plugins: [
      new webpack.BannerPlugin('最终版权归aaa所有'),
      new HtmlWebpackPlugin({
      template: 'index.html'
      }),
      new UglifyjsWebpackPlugin()
      ],

      //注意:
      output: {
      path: path.resolve(__dirname, 'dist'), //注意:path是一个绝对路径
      filename: 'bundle.js',
      // publicPath: 'dist/' 安装html-webpack-plugin需要删去
      },

      js压缩的Plugin

      image-20220630160735383

      1
      2
      npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

      1
      2
      3
      4
      5
      6
      7
      8
      const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
      plugins: [
      new webpack.BannerPlugin('最终版权归aaa所有'),
      new HtmlWebpackPlugin({
      template: 'index.html'
      }),
      new UglifyjsWebpackPlugin()
      ],

      搭建本地服务器

      • webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。

      • 不过它是一个单独的模块,在webpack中使用之前需要先安装它

        1
        2
        npm install --save-dev webpack-dev-server@2.9.1

      • devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:

        • contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist

        • port:端口号

        • inline:页面实时刷新

        • historyApiFallback:在SPA页面中,依赖HTML5的history模式

      • webpack.config.js文件配置修改如下:(和mudule还有plugins是兄弟关系)

        1
        2
        3
        4
        5
            
        devServer: {
        contentBase: './dist',
        inline: true
        }
      • 我们可以再配置另外一个scripts:
        –open参数表示直接打开浏览器

        1
        2
        3
        4
        5
        "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack",
        "dev": "webpack-dev-server --open"
        },

      image-20220630161413980

      以后运行命令直接改为:自动在浏览器打开

      1
      npm run dev

      配置文件的分离

      安装:

      1
      2
      npm install webpack-merge --save-dev
      npm install webpack-merge@4.1.5 --save-dev
      1
      2
      3
      4
      5
      "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "build": "webpack --config ./build/prod.config.js",
      "dev": "webpack-dev-server --open --config ./build/dev.config.js"
      },

      base.config.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
      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
      const path = require('path')
      const webpack = require('webpack')
      const HtmlWebpackPlugin = require('html-webpack-plugin')
      const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')

      module.exports = {
      entry: './src/main.js',
      output: {
      path: path.resolve(__dirname, '../dist'),
      filename: 'bundle.js',
      // publicPath: 'dist/'
      },
      module: {
      rules: [
      {
      test: /\.css$/,
      // css-loader只负责将css文件进行加载
      // style-loader负责将样式添加到DOM中
      // 使用多个loader时, 是从右向左
      use: [ 'style-loader', 'css-loader' ]
      },
      {
      test: /\.less$/,
      use: [{
      loader: "style-loader", // creates style nodes from JS strings
      }, {
      loader: "css-loader" // translates CSS into CommonJS
      }, {
      loader: "less-loader", // compiles Less to CSS
      }]
      },
      {
      test: /\.(png|jpg|gif|jpeg)$/,
      use: [
      {
      loader: 'url-loader',
      options: {
      // 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
      // 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
      limit: 13000,
      name: 'img/[name].[hash:8].[ext]'
      },
      }
      ]
      },
      {
      test: /\.js$/,
      // exclude: 排除
      // include: 包含
      exclude: /(node_modules|bower_components)/,
      use: {
      loader: 'babel-loader',
      options: {
      presets: ['es2015']
      }
      }
      },
      {
      test: /\.vue$/,
      use: ['vue-loader']
      }
      ]
      },
      resolve: {
      // alias: 别名
      extensions: ['.js', '.css', '.vue'],
      alias: {
      'vue$': 'vue/dist/vue.esm.js'
      }
      },
      plugins: [
      new webpack.BannerPlugin('最终版权归aaa所有'),
      new HtmlWebpackPlugin({
      template: 'index.html'
      })
      ]
      }

      dev.config.js

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      const webpackMerge = require('webpack-merge')
      const baseConfig = require('./base.config')

      module.exports = webpackMerge(baseConfig, {
      devServer: {
      contentBase: './dist',
      inline: true
      }
      })

      prod.config.js

      1
      2
      3
      4
      5
      6
      7
      8
      9
      const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
      const webpackMerge = require('webpack-merge')
      const baseConfig = require('./base.config')

      module.exports = webpackMerge(baseConfig, {
      plugins: [
      new UglifyjsWebpackPlugin()
      ]
      })

      package.json

      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
      {
      "name": "webpack",
      "version": "1.0.0",
      "description": "",
      "main": "main.js",
      "dependencies": {
      "vue": "^2.5.21",
      "webpack": "^3.6.0"
      },
      "devDependencies": {
      "babel-core": "^6.26.3",
      "babel-loader": "^7.1.5",
      "babel-preset-es2015": "^6.24.1",
      "css-loader": "^3.3.0",
      "file-loader": "^1.1.5",
      "html-webpack-plugin": "^3.2.0",
      "install": "^0.13.0",
      "less": "^4.1.3",
      "less-loader": "^4.1.0",
      "npm": "^8.13.2",
      "style-loader": "^1.0.0",
      "uglifyjs-webpack-plugin": "^1.1.1",
      "url-loader": "^1.1.2",
      "vue-loader": "^13.0.0",
      "vue-template-compiler": "^2.5.21",
      "webpack-dev-server": "^2.9.1",
      "webpack-merge": "^4.1.5"
      },
      "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "build": "webpack --config ./build/prod.config.js",
      "dev": "webpack-dev-server --open --config ./build/dev.config.js"
      },
      "author": "",
      "license": "ISC"
      }

      Vue Cli

      • 如果你在开发大型项目, 那么你需要, 并且必然需要使用Vue CLI

      • 使用Vue.js开发大型应用时,我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。

        • 如果每个项目都要手动完成这些工作,那无以效率比较低效,所以通常我们会使用一些脚手架工具来帮助完成这些事情。
      • CLI是什么意思?

        • CLI是Command-Line Interface, 翻译为命令行界面, 但是俗称脚手架.
        • Vue CLI是一个官方发布 vue.js 项目脚手架
        • 使用 vue-cli 可以快速搭建Vue开发环境以及对应的webpack配置.

      Vue Cli的使用前提-Node

      • 安装NodeJS

      • 检测安装的版本
        默认情况下自动安装Node和NPM

      1
      node -v

      Node环境要求8.9以上或者更高版本

      • 什么是NPM呢?
        • NPM的全称是Node Package Manager
        • 是一个NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准。
        • 后续我们会经常使用NPM来安装一些开发过程中依赖包.

      cnpm安装

      • 由于国内直接使用 npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像。

      • 你可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:

        1
        npm install -g cnpm --registry=https://registry.npm.taobao.org
      • 这样就可以使用 cnpm 命令来安装模块了:

        1
        cnpm install [name]

      Vue Cli的使用前提-webpack

      • Vue.js官方脚手架工具就使用了webpack模板

        • 对所有的资源会压缩等优化操作
        • 它在开发过程中提供了一套完整的功能,能够使得我们开发过程中变得高效。
      • Webpack的全局安装

        1
        npm install webpack -g    

      Vue Cli的使用

      安装脚手架:

      1
      npm install -g @vue/cli

      注意:上面安装的是Vue CLI3的版本,如果需要想按照Vue CLI2的方式初始化项目时不可以的。

      image-20220630171224720

      • Vue CLI2初始化项目

        1
        2
        3
        npm install -g @vue/cli-init
        # `vue init` 的运行效果将会跟 `vue-cli@2.x` 相同
        vue init webpack my-project
      • Vue CLI3初始化项目

        1
        vue create my-project

      创建Vue Cli2项目

      image-20220630172728344

      image-20220630192333314

      目录结构详解

      image-20220630202842814

      不使用Eslint验证

      image-20220630210304091

      Runtime-Compiler和Runtime-only的区别

      image-20220630213152252

      • 如果在之后的开发中,你依然使用template,就需要选择Runtime-Compiler
      • 如果你之后的开发中,使用的是.vue文件夹开发,那么可以选择Runtime-only

      image-20220630213325875

      image-20220630213435117

      Vue运行过程

      parse:解析

      ast:抽象语法树(abstract syntax code,AST)

      image-20220630213613111

      render函数的使用

      main.js

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      new Vue({
      el: '#app',
      // components: { App },
      // template: '<App/>'
      render: (createElement) => {
      // 使用方式一: return createElement('标签', '相关数据对象(可以不传)', ['内容数组'])
      // return createElement('div', {class: 'box'}, ['我是div中的内容'])
      // 嵌套render函数
      return createElement('div', {class: 'box'}, [createElement('h2', {class: 'h2box'}, ['我是render函数里面嵌套的h2'])])
      }

      })

      使用方式二:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      const cpn = Vue.component('cpn', {
      template: '<div>我是cpn组件</div>',
      data () {
      return {}
      }
      })

      /* eslint-disable no-new */
      new Vue({
      el: '#app',
      // components: { App },
      // template: '<App/>'
      render: (createElement) => {
      // 使用方式一: return createElement('标签', '相关数据对象(可以不传)', ['内容数组'])
      // return createElement('div', {class: 'box'}, ['我是div中的内容'])
      // 嵌套render函数
      // return createElement('div', {class: 'box'}, [createElement('h2', {class: 'h2box'}, ['我是render函数里面嵌套的h2'])])
      // 使用方式二: 传入一个组件对象
      return createElement(cpn)
      }

      })

      最终方式

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      import Vue from 'vue'
      import App from './App'

      Vue.config.productionTip = false

      new Vue({
      el: '#app',
      // components: { App },
      // template: '<App/>'
      render: (createElement) => {
      return createElement(App)
      }
      })

      运行

      1
      npm run dev

      Vue Cli3

      • vue-cli 3 与 2 版本有很大区别
      • vue-cli 3 是基于 webpack 4 打造,vue-cli 2 还是 webapck 3
      • vue-cli 3 的设计原则是“0配置”,移除的配置文件根目录下的,build和config等目录
      • vue-cli 3 提供了 vue ui 命令,提供了可视化配置,更加人性化
      • 移除了static文件夹,新增了public文件夹,并且index.html移动到public中

      创建vue cli3项目

      1
      vue create 项目名

      采用手动选择,配置分多个文件

      image-20220630222144065

      image-20220630223459106

      删掉自定义配置:

      image-20220630221842803

      运行

      1
      npm run serve

      编译

      1
      npm run build

      目录结构详解

      image-20220701150038025


      图形化管理界面

      启动命令

      1
      vue ui

      Vue-Router

      路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动. — 维基百科

      后端路由

      • 早期的网站开发整个HTML页面是由服务器来渲染的.

        • 服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示.
      • 但是, 一个网站, 这么多页面服务器如何处理呢?

        • 一个页面有自己对应的网址, 也就是URL.

        • URL会发送到服务器, 服务器会通过正则对该URL进行匹配, 并且最后交给一个Controller进行处理.
          Controller进行各种处理, 最终生成HTML或者数据, 返回给前端.

        • 这就完成了一个IO操作

      • 上面的这种操作, 就是后端路由.

        • 当我们页面中需要请求不同的路径内容时, 交给服务器来进行处理, 服务器渲染好整个页面, 并且将页面返回给客户端.

        • 这种情况下渲染好的页面, 不需要单独加载任何的js和css, 可以直接交给浏览器展示, 这样也有利于SEO的优化.

      • 后端路由的缺点:

        • 一种情况是整个页面的模块由后端人员来编写和维护的.

        • 另一种情况是前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码.

        • 而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情.

      image-20220701153409044

      前端路由

      • 前后端分离阶段:
        • 随着Ajax的出现, 有了前后端分离的开发模式.
        • 后端只提供API来返回数据, 前端通过Ajax获取数据, 并且可以通过JavaScript将数据渲染到页面中.
        • 这样做最大的优点就是前后端责任的清晰, 后端专注于数据上, 前端专注于交互和可视化上.
        • 并且当移动端(iOS/Android)出现后, 后端不需要进行任何处理, 依然使用之前的一套API即可.
        • 目前很多的网站依然采用这种模式开发.
      • 单页面富应用阶段:
      • 其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由.
      • 也就是前端来维护一套路由规则.
      • 前端路由的核心是什么呢?
        • 改变URL,但是页面不进行整体的刷新。

      image-20220701153618522

      image-20220701141255271

      URL的hash

      • URL的hash也就是锚点(#), 本质上是改变window.location的href属性.

      • 我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新

        方法 含义
        window.location.href:”url” 在本页跳转到url所指的链接
        window.location.replace:”url” 用新的url替换原先的路径
        window.location.reload() 强制刷新页面,重新向服务端发送请求
        location.href:”url” 在本页跳转到链接地址
        parent.location.href:”url” 跳转到上一层页面的指定url链接
        top.location.href:”url” 在最外层页面上进行跳转
        window.location.href:这种请求方式,需要刷新整个界面,故而用户体验度不好。但是在文件下载的时候,却只能用这种方式发送请求,ajax请求得不到响应。

      image-20220701154122091

      HTML5的history模式

      • history接口是HTML5新增的, 它有五种模式改变URL而不刷新页面.
      • history.pushState()

      image-20220701155325559

      • history.replaceState()

        image-20220701155524333

      • history.go()

      • history.back() == history.go(-1)

      • history.forword() == history.go(1)

      image-20220701155916807

      认识Vue-Router

      • 目前前端流行的三大框架, 都有自己的路由实现:
        • Angular的ngRouter
        • React的ReactRouter
        • Vue的vue-router
      • vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。
      • vue-router是基于路由和组件的
        • 路由用于设定访问路径, 将路径和组件映射起来.
        • 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换.

      安装和使用Vue-Router

      • 步骤一: 安装vue-router

        1
        npm install vue-router --save
      • 步骤二: 在模块化工程中使用它(因为是一个插件, 所以可以通过Vue.use()来安装路由功能)

        • 第一步:导入路由对象,并且调用 Vue.use(VueRouter)

          1
          2
          3
          4
          5
          import Vue from 'vue'
          import VueRouter from 'vue-router'

          // 1.注入插件
          Vue.use(VueRouter)
        • 第二步:创建路由实例,并且传入路由映射配置

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          // 2.定义路由
          const routers = []

          // 3.创建路由实例
          const router = new VueRouter({
          routers
          })

          // 4.导出router实例
          export default router
        • 第三步:在Vue实例中挂载创建的路由实例(main.js)

          1
          2
          3
          4
          5
          6
          import router from './router'
          new Vue({
          router, // 路由挂载到Vue实例中
          render: h => h(App),
          }).$mount('#app')

      • 使用vue-router的步骤:
        第一步: 创建路由组件
        第二步: 配置路由映射: 组件和路径映射关系

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        // 2.定义路由
        const routers = [
        {
        path: '/home',
        component: Home
        },
        {
        path: '/about',
        component: About
        }
        ]

        第三步: 使用路由: 通过(App.vue)

        1
        2
        3
        4
        5
        <div id="app">
        <router-link to="/home">首页</router-link>
        <router-link to="/about">关于</router-link>
        <router-view></router-view>
        </div>

      src–>router–>index.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
      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import Home from '../components/Home.vue'
      import About from '../components/About.vue'

      // 1.注入插件
      Vue.use(VueRouter)

      // 2.定义路由
      const routers = [
      {
      path: '/home',
      component: Home
      },
      {
      path: '/about',
      component: About
      }
      ]

      // 3.创建路由实例
      const router = new VueRouter({
      routers
      })

      // 4.导出router实例
      export default router

      image-20220701161311725

      App.vue

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      <template>
      <div id="app">
      <router-link to="/home">首页</router-link>
      <router-link to="/about">关于</router-link>
      <router-view></router-view>
      </div>
      </template>

      <script>
      export default {
      name: 'App',
      components: {

      }
      }
      </script>

      <style>

      </style>

      : 该标签是一个vue-router中已经内置的组件, 它会被渲染成一个标签.
      : 该标签会根据当前的路径, 动态渲染出不同的组件.
      网页的其他内容, 比如顶部的标题/导航, 或者底部的一些版权信息等会和处于同一个等级.
      在路由切换时, 切换的是挂载的组件, 其他内容不会发生改变.

      路由的默认路径

      • 配置解析:
        • 我们在routes中又配置了一个映射.
        • path配置的是根路径: /
        • redirect是重定向, 也就是我们将根路径重定向到/home的路径下, 这样就可以得到我们想要的结果了.

      image-20220701193214936

      改变路径的hash模式

      当配置了代理服务器后,哈希模式不会向服务器端发送请求,而历史模式可能会

      哈希模式的兼容性更好

      • 我们前面说过改变路径的方式有两种:

        • URL的hash

        • HTML5的history

        • 默认情况下, 路径的改变使用的URL的hash.

      如果希望使用HTML5的history模式, 非常简单, 进行如下配置即可:

      1
      2
      3
      4
      5
      // 3.创建路由实例
      const router = new VueRouter({
      routes,
      mode: 'history'
      })
      1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
      2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。
      3. hash模式:
        1. 地址中永远带着#号,不美观 。
        2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
        3. 兼容性较好。
      4. history模式:
        1. 地址干净,美观 。
        2. 兼容性和hash模式相比略差。
        3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。

      router-link属性

      1
      2
      3
      4
      5
      6
      7
      8
      // 3.创建路由实例
      const router = new VueRouter({
      routes,
      mode: 'history',
      // 修改linkActiveClass
      linkActiveClass: 'active'

      })

      路由切换,未被用到的组件会被销毁

      路由代码跳转

      1
      2
      this.$router.push('/home')
      this.$router.replace('/home')

      获取当前路由($route)

      1
      this.$route.path

      点击相同路由报错解决方案:https://blog.csdn.net/weixin_44196222/article/details/125565441?spm=1001.2014.3001.5502

      动态路由

      • 在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望是如下的路径:
        /user/aaaa或/user/bbbb
        除了有前面的/user之外,后面还跟上了用户的ID
        这种path和Component的匹配关系,我们称之为动态路由(也是路由传递数据的一种方式)。
      1
      2
      3
      4
      {
      path: '/user/:userId',
      component: User
      }

      获取参数:(上面如果写abc,这里也要写abc)

      1
      this.$route.params.userId

      路由懒加载

      • 官方给出了解释:
        • 当打包构建应用时,Javascript 包会变得非常大,影响页面加载。
        • 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
      • 官方在说什么呢?
        • 首先, 我们知道路由中通常会定义很多不同的页面.
        • 这个页面最后被打包在哪里呢? 一般情况下, 是放在一个js文件中.
        • 但是, 页面这么多放在一个js文件中, 必然会造成这个页面非常的大.
        • 如果我们一次性从服务器请求下来这个页面, 可能需要花费一定的时间, 甚至用户的电脑上还出现了短暂空白的情况.
          如何避免这种情况呢? 使用路由懒加载就可以了.
      • 路由懒加载做了什么?
        • 路由懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块.
        • 只有在这个路由被访问到的时候, 才加载对应的组件

      image-20220702085748541

      懒加载的方式

      • 方式一: 结合Vue的异步组件和Webpack的代码分析.
      1
      const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
      • 方式二: AMD写法
      1
      const About = resolve => require(['../components/About.vue'], resolve);
      • 方式三: 在ES6中, 我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割.
      1
      const Home = () => import('../components/Home.vue')

      未使用路由懒加载打包:

      image-20220702090126794

      使用路由懒加载后打包:(会把每个路由单独打包到一个js文件里)

      image-20220702090638418

      1
      2
      3
      const Home = () => import('../components/Home.vue')
      const About = () => import('../components/About.vue')
      const User = () => import('../components/User.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
      // 2.定义路由
      const routes = [
      {
      path: '/',
      // 重定向
      redirect: '/home'
      },
      {
      path: '/home',
      component: Home,
      children:[
      {
      path: '',
      redirect: 'news'
      },
      {
      path: 'news',
      component: HomeNews
      },
      {
      path: 'message',
      component: HomeMessage
      }
      ]
      }
      ]

      image-20220825110138436

      路由传递参数

      传递参数的方式:

      • 传递参数主要有两种类型: params和query

        • params的类型:

          • 配置路由格式: /router/:id
          • 传递的方式: 在path后面跟上对应的值
          • 传递后形成的路径: /router/123, /router/ab
          1
          2
          <router-link :to="'/user/'+userId" tag="button" >用户</router-link>
          <button @click="userClick">用户</button>
          1
          2
          3
          userClick() {
          this.$router.push('/user/'+ this.userId)
          },

        image-20220825121227936

        image-20220825121520260

        • query的类型:

          • 配置路由格式: /router, 也就是普通配置
          • 传递的方式: 对象中使用query的key作为传递方式
          • 传递后形成的路径: /router?id=123, /router?id=abc
        1
        2
        <router-link :to="{path: '/profile', query: {name: 'zhangsan', age: 19, height: 188}}" tag="button">档案</router-link>
        <button @click="profileClick">档案</button>
        1
        2
        3
        4
        5
        6
        7
        8
        9
        profileClick () {
        this.$router.push({
        path: '/profile' + 123,
        query: {
        name: 'zhangsan',
        age: 18
        }
        })
        },

      获取

      1
      this.$route.query.参数名

      image-20220825120341053

      命名路由

      作用:简化路由的跳转

      1
      2
      3
      4
      5
      6
      7
      const routes = [
      {
      name: 'home'
      path: '/home',
      component: Home,
      }
      ]

      使用

      1
      <router-link :to="{name:'home'}" >主页</router-link>

      image-20220825120913783

      路由组件的props配置

      让路由组件更方便的接收参数

      image-20220825122611215

      组件激活与失活

      两个函数: activated,deactivated

      image-20220825131225446

      $route和$router的区别

      • $route和$router是有区别的
        • $router为VueRouter实例,想要导航到不同URL,则使用$router.push方法
        • $route为当前router跳转对象里面可以获取name、path、query、params等

      image-20220702110918428

      全局导航守卫

      • 我们来考虑一个需求: 在一个SPA应用中, 如何改变网页的标题呢?

        • 网页标题是通过来显示的, 但是SPA只有一个固定的HTML, 切换不同的页面时, 标题并不会改变.<br>但是我们可以通过JavaScript来修改<title>的内容.window.document.title = ‘新的标题’.</li> </ul> </li> <li><p>普通的修改方式:</p> <ul> <li><p>我们比较容易想到的修改标题的位置是每一个路由对应的组件.vue文件中.</p> </li> <li><p>通过mounted声明周期函数, 执行对应的代码进行修改即可.</p> </li> <li><p>但是当页面比较多时, 这种方式不容易维护(因为需要在多个页面执行类似的代码).</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">created () {<br> <span class="hljs-variable language_">document</span>.<span class="hljs-property">title</span> = <span class="hljs-string">"关于"</span><br> }<br></code></pre></td></tr></table></figure></li> </ul> </li> <li><p>有没有更好的办法呢? 使用导航守卫即可.</p> </li> <li><p>什么是导航守卫?</p> <ul> <li>vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.</li> <li>vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发.</li> </ul> </li> </ul> <p><strong>导航钩子的三个参数解析</strong>:</p> <ul> <li>to: 即将要进入的目标的路由对象.</li> <li>from: 当前导航即将要离开的路由对象.</li> <li>next: 调用该方法后, 才能进入下一个钩子.</li> </ul> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 前置路由导航守卫</span><br>router.<span class="hljs-title function_">beforeEach</span>(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span>, next</span>) =></span> {<br> <span class="hljs-variable language_">window</span>.<span class="hljs-property">document</span>.<span class="hljs-property">title</span> = to.<span class="hljs-property">matched</span>[<span class="hljs-number">0</span>].<span class="hljs-property">meta</span>.<span class="hljs-property">title</span><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(to)<br> <span class="hljs-title function_">next</span>()<br>})<br><span class="hljs-comment">// 后置路由导航守卫</span><br>router.<span class="hljs-title function_">afterEach</span>(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span></span>) =></span> {<br> <span class="hljs-variable language_">document</span>.<span class="hljs-property">title</span> = to.<span class="hljs-property">meta</span>.<span class="hljs-property">title</span><br>})<br></code></pre></td></tr></table></figure> <p>官网:<a target="_blank" rel="noopener" href="https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E8%B7%AF%E7%94%B1%E7%8B%AC%E4%BA%AB%E7%9A%84%E5%AE%88%E5%8D%AB">https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E8%B7%AF%E7%94%B1%E7%8B%AC%E4%BA%AB%E7%9A%84%E5%AE%88%E5%8D%AB</a></p> <h3 id="keep-alive"><a href="#keep-alive" class="headerlink" title="keep-alive"></a>keep-alive</h3><ul> <li>keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。</li> <li>它们有两个非常重要的属性:<ul> <li>include - 字符串或正则表达,只有匹配的组件会被缓存</li> <li>exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存</li> <li>router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存:</li> </ul> </li> </ul> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">keep-alive</span> <span class="hljs-attr">exclude</span>=<span class="hljs-string">"User,Profile"</span>></span> <span class="hljs-comment"><!-- 逗号之间不要空格 --></span><br> <span class="hljs-tag"><<span class="hljs-name">router-view</span>></span><br> <span class="hljs-comment"><!-- 所有路径匹配到的视图组件都会被缓存 --></span><br> <span class="hljs-tag"></<span class="hljs-name">router-view</span>></span><br><span class="hljs-tag"></<span class="hljs-name">keep-alive</span>></span><br></code></pre></td></tr></table></figure> <p><strong>exclude,里面的属性是这里的name</strong></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220825130834968.png" srcset="/img/loading.gif" lazyload alt="image-20220825130834968"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220825130704238.png" srcset="/img/loading.gif" lazyload alt="image-20220825130704238"></p> <p>实现保持默认状态:(保持上一个选中的)</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"> <span class="hljs-title function_">activated</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$router</span>.<span class="hljs-title function_">push</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">path</span>)<br> }, <br>beforeRouteLeave (to, <span class="hljs-keyword">from</span>, next) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">path</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">path</span><br> <span class="hljs-title function_">next</span>()<br> }<br></code></pre></td></tr></table></figure> <h3 id="独享导航守卫"><a href="#独享导航守卫" class="headerlink" title="独享导航守卫"></a>独享导航守卫</h3><blockquote> <p>写在routes里面,只有一个beforeEnter方法</p> </blockquote> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220825141018373.png" srcset="/img/loading.gif" lazyload alt="image-20220825141018373"></p> <h3 id="组件导航守卫"><a href="#组件导航守卫" class="headerlink" title="组件导航守卫"></a>组件导航守卫</h3><blockquote> <p>写在组件里面,两个方法 beforeRouteEnter, beforeRouteLeave</p> </blockquote> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220825141815818.png" srcset="/img/loading.gif" lazyload alt="image-20220825141815818"></p> <h2 id="TabBar"><a href="#TabBar" class="headerlink" title="TabBar"></a>TabBar</h2><p>创建项目</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">vue create 项目名称<br></code></pre></td></tr></table></figure> <ul> <li>如果在下方有一个单独的TabBar组件,你如何封装<br>自定义TabBar组件,在APP中使用<br>让TabBar出于底部,并且设置相关的样式</li> <li>TabBar中显示的内容由外界决定<br>定义插槽<br>flex布局平分TabBar</li> <li>自定义TabBarItem,可以传入 图片和文字<br>定义TabBarItem,并且定义两个插槽:图片、文字。<br>给两个插槽外层包装div,用于设置样式。<br>填充插槽,实现底部TabBar的效果</li> <li>4.传入 高亮图片<br>定义另外一个插槽,插入active-icon的数据<br>定义一个变量isActive,通过v-show来决定是否显示对应的icon</li> <li>5.TabBarItem绑定路由数据<br>安装路由:npm install vue-router —save<br>完成router/index.js的内容,以及创建对应的组件<br>main.js中注册router<br>APP中加入<router-view>组件</li> <li>6.点击item跳转到对应路由,并且动态决定isActive<br>监听item的点击,通过this.$router.replace()替换路由路径<br>通过this.$route.path.indexOf(this.link) !== -1来判断是否是active</li> <li>7.动态计算active样式<br>封装新的计算属性:this.isActive ? {‘color’: ‘red’} : {}</li> </ul> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220703184747611.png" srcset="/img/loading.gif" lazyload alt="image-20220703184747611"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220703184825242.png" srcset="/img/loading.gif" lazyload alt="image-20220703184825242"></p> <h3 id="MainTab"><a href="#MainTab" class="headerlink" title="MainTab"></a>MainTab</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">tab-bar</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">tab-bar-item</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/home"</span> <span class="hljs-attr">activeColor</span>=<span class="hljs-string">"#FF5777"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/home.svg"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon-active"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/home_active.svg"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-text"</span>></span>首页<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">tab-bar-item</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">tab-bar-item</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/category"</span> <span class="hljs-attr">activeColor</span>=<span class="hljs-string">"#FF5777"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/category.svg"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon-active"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/category_active.svg"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-text"</span>></span>分类<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">tab-bar-item</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">tab-bar-item</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/cart"</span> <span class="hljs-attr">activeColor</span>=<span class="hljs-string">"#FF5777"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/shopcart.svg"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon-active"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/shopcart_active.svg"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-text"</span>></span>购物车<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">tab-bar-item</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">tab-bar-item</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/profile"</span> <span class="hljs-attr">activeColor</span>=<span class="hljs-string">"#FF5777"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/profile.svg"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-icon-active"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"~img/tabbar/profile_active.svg"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"item-text"</span>></span>我的<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">tab-bar-item</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">tab-bar</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">TabBar</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'../tabbar/TabBar.vue'</span></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">TabBarItem</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'../tabbar/TabBarItem.vue'</span></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MianTab'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">components</span>: {</span><br><span class="language-javascript"> <span class="hljs-title class_">TabBar</span>,</span><br><span class="language-javascript"> <span class="hljs-title class_">TabBarItem</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br></code></pre></td></tr></table></figure> <h3 id="TabBar-1"><a href="#TabBar-1" class="headerlink" title="TabBar"></a>TabBar</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"tab-bar"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">slot</span>/></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'TabBar'</span></span><br><span class="language-javascript"> </span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.tab-bar</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: flex;</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f6f6f6</span>;</span><br><span class="language-css"> <span class="hljs-attribute">position</span>: fixed;</span><br><span class="language-css"> <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span>;</span><br><span class="language-css"> <span class="hljs-attribute">right</span>: <span class="hljs-number">0</span>;</span><br><span class="language-css"> <span class="hljs-attribute">bottom</span>: <span class="hljs-number">0</span>;</span><br><span class="language-css"></span><br><span class="language-css"> <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> -<span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">100</span>, <span class="hljs-number">100</span>, <span class="hljs-number">100</span>, .<span class="hljs-number">2</span>);</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br></code></pre></td></tr></table></figure> <h3 id="TabBarItem"><a href="#TabBarItem" class="headerlink" title="TabBarItem"></a>TabBarItem</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"tab-bar-item"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"itemClick"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"!isActive"</span>></span><span class="hljs-tag"><<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"item-icon"</span>></span><span class="hljs-tag"></<span class="hljs-name">slot</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">v-else</span>></span><span class="hljs-tag"><<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"item-icon-active"</span>></span><span class="hljs-tag"></<span class="hljs-name">slot</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">:style</span>=<span class="hljs-string">"activeStyle"</span>></span><span class="hljs-tag"><<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"item-text"</span>></span><span class="hljs-tag"></<span class="hljs-name">slot</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'TabBarItem'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">props</span>: {</span><br><span class="language-javascript"> <span class="hljs-attr">path</span>: <span class="hljs-title class_">String</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">activeColor</span>: {</span><br><span class="language-javascript"> <span class="hljs-attr">type</span>: <span class="hljs-title class_">String</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">default</span>: <span class="hljs-string">'red'</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">computed</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">isActive</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">path</span>.<span class="hljs-title function_">indexOf</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">path</span>) !== -<span class="hljs-number">1</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">activeStyle</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">isActive</span> ? {<span class="hljs-attr">color</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">activeColor</span>} : {}</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">itemClick</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">path</span> != <span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">path</span>){</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$router</span>.<span class="hljs-title function_">push</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">path</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> </span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.tab-bar-item</span> {</span><br><span class="language-css"> <span class="hljs-attribute">flex</span>: <span class="hljs-number">1</span>;</span><br><span class="language-css"> <span class="hljs-attribute">text-align</span>: center;</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">49px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">font-size</span>: <span class="hljs-number">14px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-selector-class">.tab-bar-item</span> <span class="hljs-selector-tag">img</span> {</span><br><span class="language-css"> <span class="hljs-attribute">width</span>: <span class="hljs-number">24px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">24px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">3px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">vertical-align</span>: middle;</span><br><span class="language-css"> <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">2px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br></code></pre></td></tr></table></figure> <h3 id="修改文件路径别名"><a href="#修改文件路径别名" class="headerlink" title="修改文件路径别名"></a>修改文件路径别名</h3><p>vue.config.js(修改完要重启)</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">resolve</span>(<span class="hljs-params">dir</span>) {<br> <span class="hljs-keyword">return</span> path.<span class="hljs-title function_">join</span>(__dirname, dir);<br>}<br><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = {<br> <span class="hljs-attr">lintOnSave</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//去掉EsLint代码规范验证</span><br> <span class="hljs-attr">configureWebpack</span>: {<br> <span class="hljs-attr">resolve</span>: {<br> <span class="hljs-attr">alias</span>: {<br> <span class="hljs-string">'@'</span>: <span class="hljs-title function_">resolve</span>(<span class="hljs-string">'src'</span>),<br> <span class="hljs-string">'img'</span>: <span class="hljs-title function_">resolve</span>(<span class="hljs-string">'src/assets/img'</span>)<br> }<br> }<br> },<br>}<br></code></pre></td></tr></table></figure> <h2 id="Todo-List"><a href="#Todo-List" class="headerlink" title="Todo-List"></a>Todo-List</h2><p>App.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-container"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-wrap"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyHeader</span> <span class="hljs-attr">:addTodo</span>=<span class="hljs-string">"addTodo"</span>></span><span class="hljs-tag"></<span class="hljs-name">MyHeader</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyList</span> <span class="hljs-attr">:todos</span>=<span class="hljs-string">"todos"</span> <span class="hljs-attr">:checkTodo</span>=<span class="hljs-string">"checkTodo"</span> <span class="hljs-attr">:deleteTodo</span>=<span class="hljs-string">"deleteTodo"</span>></span><span class="hljs-tag"></<span class="hljs-name">MyList</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyFooter</span> <span class="hljs-attr">:todos</span>=<span class="hljs-string">"todos"</span> <span class="hljs-attr">:checkALLTodo</span>=<span class="hljs-string">"checkALLTodo"</span> <span class="hljs-attr">:cleanAllTodo</span>=<span class="hljs-string">"cleanAllTodo"</span>></span><span class="hljs-tag"></<span class="hljs-name">MyFooter</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyHeader</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyHeader"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyList</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyList"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyFooter</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyFooter"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'App'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">components</span>: {<span class="hljs-title class_">MyFooter</span>, <span class="hljs-title class_">MyList</span>, <span class="hljs-title class_">MyHeader</span>},</span><br><span class="language-javascript"> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">todos</span>: <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">getItem</span>(<span class="hljs-string">'todos'</span>)) || [] <span class="hljs-comment">// 没有数据就是空数组,不加【】会变成null,无法使用length函数</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">watch</span>:{</span><br><span class="language-javascript"> <span class="hljs-attr">todos</span>: {</span><br><span class="language-javascript"> <span class="hljs-attr">deep</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// 深度监视,数组里面集合内容发生变化也可以监视到</span></span><br><span class="language-javascript"> <span class="hljs-title function_">handler</span>(<span class="hljs-params">value</span>) { <span class="hljs-comment">// 存储到本地</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">setItem</span>(<span class="hljs-string">'todos'</span>,<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(value))</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-comment">// 添加任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">addTodo</span>(<span class="hljs-params">todoObj</span>) { <span class="hljs-comment">// 写一个方法,传递给子组件,然后子组件调用这个方法,传递值回来</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">unshift</span>(todoObj) <span class="hljs-comment">// 添加任务到任务数组</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 完成或取消完成任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">checkTodo</span>(<span class="hljs-params">id</span>) { <span class="hljs-comment">// 爷传父,再传子的方法,用于接收子传给爷的数据</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">todo</span>)=></span>{</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span>(todo.<span class="hljs-property">id</span> == id) todo.<span class="hljs-property">completed</span> = !todo.<span class="hljs-property">completed</span></span><br><span class="language-javascript"> })</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 删除任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">deleteTodo</span>(<span class="hljs-params">id</span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span>(<span class="hljs-title function_">confirm</span>(<span class="hljs-string">"确定要删除吗?"</span>)){</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">todo</span> =></span> todo.<span class="hljs-property">id</span> != id)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 选中全部</span></span><br><span class="language-javascript"> <span class="hljs-title function_">checkALLTodo</span>(<span class="hljs-params">done</span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">todo</span>) =></span> {</span><br><span class="language-javascript"> todo.<span class="hljs-property">completed</span> = done</span><br><span class="language-javascript"> })</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 清除已完成任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">cleanAllTodo</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">todo</span> =></span> !todo.<span class="hljs-property">completed</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*base*/</span></span><br><span class="language-css"><span class="hljs-selector-tag">body</span> {</span><br><span class="language-css"> <span class="hljs-attribute">background</span>: <span class="hljs-number">#fff</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: inline-block;</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">4px</span> <span class="hljs-number">12px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0</span>;</span><br><span class="language-css"> <span class="hljs-attribute">font-size</span>: <span class="hljs-number">14px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">20px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">text-align</span>: center;</span><br><span class="language-css"> <span class="hljs-attribute">vertical-align</span>: middle;</span><br><span class="language-css"> <span class="hljs-attribute">cursor</span>: pointer;</span><br><span class="language-css"> <span class="hljs-attribute">box-shadow</span>: inset <span class="hljs-number">0</span> <span class="hljs-number">1px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.2</span>), <span class="hljs-number">0</span> <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.05</span>);</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn-danger</span> {</span><br><span class="language-css"> <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#da4f49</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#bd362f</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn-danger</span><span class="hljs-selector-pseudo">:hover</span> {</span><br><span class="language-css"> <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#bd362f</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn</span><span class="hljs-selector-pseudo">:focus</span> {</span><br><span class="language-css"> <span class="hljs-attribute">outline</span>: none;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-container</span> {</span><br><span class="language-css"> <span class="hljs-attribute">width</span>: <span class="hljs-number">600px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-selector-class">.todo-container</span> <span class="hljs-selector-class">.todo-wrap</span> {</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>MyHeader.vue</p> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><code class="hljs java"><template><br> <div class=<span class="hljs-string">"todo-header"</span>><br> <input type=<span class="hljs-string">"text"</span> placeholder=<span class="hljs-string">"请输入你的任务名称,按回车键确认"</span> v-model=<span class="hljs-string">"title"</span> <span class="hljs-meta">@keyup</span>.enter=<span class="hljs-string">"add"</span>/><br> </div><br></template><br><br><script><br><span class="hljs-keyword">import</span> {nanoid} from <span class="hljs-string">'nanoid'</span><br>export <span class="hljs-keyword">default</span> {<br> name: <span class="hljs-string">'MyHeader'</span>,<br> props: [<span class="hljs-string">'addTodo'</span>], <span class="hljs-comment">// 接收父组件传过来的方法</span><br> data() {<br> <span class="hljs-keyword">return</span> {<br> title: <span class="hljs-string">''</span><br> }<br> },<br> methods: {<br> add() {<br> <span class="hljs-keyword">if</span>(!<span class="hljs-built_in">this</span>.title.trim()) {<br> alert(<span class="hljs-string">"输入的任务不能为空"</span>)<br> <span class="hljs-keyword">return</span><br> }<br> <span class="hljs-type">const</span> <span class="hljs-variable">todoObj</span> <span class="hljs-operator">=</span> {<br> id: nanoid(), <span class="hljs-comment">// 生成一个唯一id</span><br> name: <span class="hljs-built_in">this</span>.title,<br> completed: <span class="hljs-literal">false</span><br> }<br> <span class="hljs-built_in">this</span>.addTodo(todoObj) <span class="hljs-comment">// 将生成的任务,传递回去给父组件</span><br> <span class="hljs-built_in">this</span>.title = <span class="hljs-string">''</span><br> }<br> }<br>}<br></script><br><br><style scoped><br><span class="hljs-comment">/*header*/</span><br>.todo-header input {<br> width: 560px;<br> height: 28px;<br> font-size: 14px;<br> border: 1px solid #ccc;<br> border-radius: 4px;<br> padding: 4px 7px;<br>}<br><br>.todo-header input:focus {<br> outline: none;<br> border-color: rgba(<span class="hljs-number">82</span>, <span class="hljs-number">168</span>, <span class="hljs-number">236</span>, <span class="hljs-number">0.8</span>);<br> box-shadow: inset <span class="hljs-number">0</span> 1px 1px <span class="hljs-title function_">rgba</span><span class="hljs-params">(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.075</span>)</span>, <span class="hljs-number">0</span> <span class="hljs-number">0</span> 8px <span class="hljs-title function_">rgba</span><span class="hljs-params">(<span class="hljs-number">82</span>, <span class="hljs-number">168</span>, <span class="hljs-number">236</span>, <span class="hljs-number">0.6</span>)</span>;<br>}<br></style><br><br></code></pre></td></tr></table></figure> <p>MyList.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-main"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyItem</span></span><br><span class="hljs-tag"> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"todoObj in todos"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:key</span>=<span class="hljs-string">"todoObj.id"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:todo</span> = <span class="hljs-string">"todoObj"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:deleteTodo</span> = <span class="hljs-string">"deleteTodo"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:checkTodo</span>=<span class="hljs-string">"checkTodo"</span></span><br><span class="hljs-tag"> ></span><span class="hljs-tag"></<span class="hljs-name">MyItem</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">ul</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyItem</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyItem"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyList'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">components</span>: {<span class="hljs-title class_">MyItem</span>},</span><br><span class="language-javascript"> <span class="hljs-attr">props</span>:[<span class="hljs-string">'todos'</span>,<span class="hljs-string">'checkTodo'</span>,<span class="hljs-string">"deleteTodo"</span>]</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*main*/</span></span><br><span class="language-css"><span class="hljs-selector-class">.todo-main</span> {</span><br><span class="language-css"> <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">0px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">0px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-empty</span> {</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">10px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>MyItem.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">li</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">:checked</span>=<span class="hljs-string">"todo.completed"</span> @<span class="hljs-attr">change</span>=<span class="hljs-string">"handlerCheck(todo.id)"</span>/></span><br> <span class="hljs-comment"><!--这种方式也能实现修改propos,但是vue检测不到,不推荐这样做,子组件不要直接修改父组件传过来的值--></span><br> <span class="hljs-comment"><!--<input type="checkbox" v-model="todo.completed" />--></span><br> <span class="hljs-tag"><<span class="hljs-name">span</span>></span>{{ todo.name }}<span class="hljs-tag"></<span class="hljs-name">span</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-danger"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"handlerDelete(todo.id)"</span>></span>删除<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">li</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyItem'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">props</span>:[<span class="hljs-string">'todo'</span>,<span class="hljs-string">'checkTodo'</span>,<span class="hljs-string">'deleteTodo'</span>],</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">handlerCheck</span>(<span class="hljs-params">id</span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">checkTodo</span>(id) <span class="hljs-comment">// 将勾选框发生变化的id传给爷爷</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">handlerDelete</span>(<span class="hljs-params">id</span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">deleteTodo</span>(id);</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*item*/</span></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> {</span><br><span class="language-css"> <span class="hljs-attribute">list-style</span>: none;</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">36px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">36px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">5px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-bottom</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">label</span> {</span><br><span class="language-css"> <span class="hljs-attribute">float</span>: left;</span><br><span class="language-css"> <span class="hljs-attribute">cursor</span>: pointer;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">label</span> <span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">input</span> {</span><br><span class="language-css"> <span class="hljs-attribute">vertical-align</span>: middle;</span><br><span class="language-css"> <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">6px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">position</span>: relative;</span><br><span class="language-css"> <span class="hljs-attribute">top</span>: -<span class="hljs-number">1px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">button</span> {</span><br><span class="language-css"> <span class="hljs-attribute">float</span>: right;</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: none;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">3px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:before</span> {</span><br><span class="language-css"> <span class="hljs-attribute">content</span>: initial;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:last-child</span> {</span><br><span class="language-css"> <span class="hljs-attribute">border-bottom</span>: none;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:hover</span> {</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ddd</span>;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:hover</span> <span class="hljs-selector-tag">button</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: block;</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>MyFooter.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-footer"</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"total"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"isAll"</span>/></span><br> <span class="hljs-tag"></<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">span</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">span</span>></span>已完成{{doneTotal}}<span class="hljs-tag"></<span class="hljs-name">span</span>></span> / 全部{{ total }}<br> <span class="hljs-tag"></<span class="hljs-name">span</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-danger"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"cleanAll"</span>></span>清除已完成任务<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyFooter'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">props</span>: [<span class="hljs-string">'todos'</span>,<span class="hljs-string">'checkALLTodo'</span>, <span class="hljs-string">'cleanAllTodo'</span>],</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">cleanAll</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">cleanAllTodo</span>()</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">computed</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">total</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-property">length</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">doneTotal</span>(<span class="hljs-params"></span>){</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">reduce</span>(<span class="hljs-function">(<span class="hljs-params">pre,todo</span>) =></span> {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> pre + (todo.<span class="hljs-property">completed</span> == <span class="hljs-literal">true</span> ? <span class="hljs-number">1</span>: <span class="hljs-number">0</span>)</span><br><span class="language-javascript"> },<span class="hljs-number">0</span>)</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">isAll</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">get</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">total</span> == <span class="hljs-variable language_">this</span>.<span class="hljs-property">doneTotal</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">total</span> > <span class="hljs-number">0</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">set</span>(<span class="hljs-params">value</span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">checkALLTodo</span>(value)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*footer*/</span></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> {</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">6px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> <span class="hljs-selector-tag">label</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: inline-block;</span><br><span class="language-css"> <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">20px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">cursor</span>: pointer;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> <span class="hljs-selector-tag">label</span> <span class="hljs-selector-tag">input</span> {</span><br><span class="language-css"> <span class="hljs-attribute">position</span>: relative;</span><br><span class="language-css"> <span class="hljs-attribute">top</span>: -<span class="hljs-number">1px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">vertical-align</span>: middle;</span><br><span class="language-css"> <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> <span class="hljs-selector-tag">button</span> {</span><br><span class="language-css"> <span class="hljs-attribute">float</span>: right;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <h3 id="利用全局事件总线和自定义事件版本"><a href="#利用全局事件总线和自定义事件版本" class="headerlink" title="利用全局事件总线和自定义事件版本"></a>利用全局事件总线和自定义事件版本</h3><p>main.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vue</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'./App.vue'</span><br><span class="hljs-keyword">import</span> router <span class="hljs-keyword">from</span> <span class="hljs-string">'./router'</span><br><br><span class="hljs-title class_">Vue</span>.<span class="hljs-property">config</span>.<span class="hljs-property">productionTip</span> = <span class="hljs-literal">false</span><br><br><span class="hljs-keyword">new</span> <span class="hljs-title class_">Vue</span>({<br> router,<br> <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-params">h</span> =></span> <span class="hljs-title function_">h</span>(<span class="hljs-title class_">App</span>),<br> <span class="hljs-title function_">beforeCreate</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-title class_">Vue</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">$bus</span> = <span class="hljs-variable language_">this</span> <span class="hljs-comment">// 安装全局事件总线</span><br> }<br>}).$mount(<span class="hljs-string">'#app'</span>)<br><br></code></pre></td></tr></table></figure> <p>App.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-container"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-wrap"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyHeader</span> @<span class="hljs-attr">addTodo</span>=<span class="hljs-string">"addTodo"</span>></span><span class="hljs-tag"></<span class="hljs-name">MyHeader</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyList</span> <span class="hljs-attr">:todos</span>=<span class="hljs-string">"todos"</span>></span><span class="hljs-tag"></<span class="hljs-name">MyList</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyFooter</span> <span class="hljs-attr">:todos</span>=<span class="hljs-string">"todos"</span> @<span class="hljs-attr">checkALLTodo</span>=<span class="hljs-string">"checkALLTodo"</span> @<span class="hljs-attr">cleanAllTodo</span>=<span class="hljs-string">"cleanAllTodo"</span>></span><span class="hljs-tag"></<span class="hljs-name">MyFooter</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">Fu</span>></span><span class="hljs-tag"></<span class="hljs-name">Fu</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyHeader</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyHeader"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyList</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyList"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyFooter</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyFooter"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Fu</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/views/Fu"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'App'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">components</span>: {<span class="hljs-title class_">MyFooter</span>, <span class="hljs-title class_">MyList</span>, <span class="hljs-title class_">MyHeader</span>,<span class="hljs-title class_">Fu</span>},</span><br><span class="language-javascript"> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">todos</span>: <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">getItem</span>(<span class="hljs-string">'todos'</span>)) || [] <span class="hljs-comment">// 没有数据就是空数组,不加【】会变成null,无法使用length函数</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">watch</span>:{</span><br><span class="language-javascript"> <span class="hljs-attr">todos</span>: {</span><br><span class="language-javascript"> <span class="hljs-attr">deep</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// 深度监视,数组里面集合内容发生变化也可以监视到</span></span><br><span class="language-javascript"> <span class="hljs-title function_">handler</span>(<span class="hljs-params">value</span>) { <span class="hljs-comment">// 存储到本地</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">setItem</span>(<span class="hljs-string">'todos'</span>,<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(value))</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">mounted</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$on(<span class="hljs-string">'checkTodo'</span>,<span class="hljs-variable language_">this</span>.<span class="hljs-property">checkTodo</span>) <span class="hljs-comment">// 这里不需要写参数</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$on(<span class="hljs-string">'deleteTodo'</span>,<span class="hljs-variable language_">this</span>.<span class="hljs-property">deleteTodo</span>)</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$on(<span class="hljs-string">'updateTodo'</span>,<span class="hljs-variable language_">this</span>.<span class="hljs-property">updateTodo</span>)</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">beforeDestroy</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$off([<span class="hljs-string">'checkTodo'</span>,<span class="hljs-string">'checkTodo'</span>,<span class="hljs-string">'updateTodo'</span>])</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-comment">// 添加任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">addTodo</span>(<span class="hljs-params">todoObj</span>) { <span class="hljs-comment">// 写一个方法,传递给子组件,然后子组件调用这个方法,传递值回来</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">unshift</span>(todoObj) <span class="hljs-comment">// 添加任务到任务数组</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 完成或取消完成任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">checkTodo</span>(<span class="hljs-params">id</span>) { <span class="hljs-comment">// 爷传父,再传子的方法,用于接收子传给爷的数据</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">todo</span>)=></span>{</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span>(todo.<span class="hljs-property">id</span> == id) todo.<span class="hljs-property">completed</span> = !todo.<span class="hljs-property">completed</span></span><br><span class="language-javascript"> })</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 删除任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">deleteTodo</span>(<span class="hljs-params">id</span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span>(<span class="hljs-title function_">confirm</span>(<span class="hljs-string">"确定要删除吗?"</span>)){</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">todo</span> =></span> todo.<span class="hljs-property">id</span> != id)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">updateTodo</span>(<span class="hljs-params">id, name</span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">forEach</span>( <span class="hljs-function">(<span class="hljs-params">todo</span>) =></span> {</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span> (todo.<span class="hljs-property">id</span> == id) {</span><br><span class="language-javascript"> todo.<span class="hljs-property">name</span> = name</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> })</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 选中全部</span></span><br><span class="language-javascript"> <span class="hljs-title function_">checkALLTodo</span>(<span class="hljs-params">done</span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">todo</span>) =></span> {</span><br><span class="language-javascript"> todo.<span class="hljs-property">completed</span> = done</span><br><span class="language-javascript"> })</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 清除已完成任务</span></span><br><span class="language-javascript"> <span class="hljs-title function_">cleanAllTodo</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">todo</span> =></span> !todo.<span class="hljs-property">completed</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*base*/</span></span><br><span class="language-css"><span class="hljs-selector-tag">body</span> {</span><br><span class="language-css"> <span class="hljs-attribute">background</span>: <span class="hljs-number">#fff</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: inline-block;</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">4px</span> <span class="hljs-number">12px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0</span>;</span><br><span class="language-css"> <span class="hljs-attribute">font-size</span>: <span class="hljs-number">14px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">20px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">text-align</span>: center;</span><br><span class="language-css"> <span class="hljs-attribute">vertical-align</span>: middle;</span><br><span class="language-css"> <span class="hljs-attribute">cursor</span>: pointer;</span><br><span class="language-css"> <span class="hljs-attribute">box-shadow</span>: inset <span class="hljs-number">0</span> <span class="hljs-number">1px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.2</span>), <span class="hljs-number">0</span> <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.05</span>);</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn-danger</span> {</span><br><span class="language-css"> <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#da4f49</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#bd362f</span>;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-selector-class">.btn-edit</span> {</span><br><span class="language-css"> <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: skyblue;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#0776a1</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn-danger</span><span class="hljs-selector-pseudo">:hover</span> {</span><br><span class="language-css"> <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#bd362f</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.btn</span><span class="hljs-selector-pseudo">:focus</span> {</span><br><span class="language-css"> <span class="hljs-attribute">outline</span>: none;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-container</span> {</span><br><span class="language-css"> <span class="hljs-attribute">width</span>: <span class="hljs-number">600px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-selector-class">.todo-container</span> <span class="hljs-selector-class">.todo-wrap</span> {</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>MyHeader.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-header"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"请输入你的任务名称,按回车键确认"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"title"</span> @<span class="hljs-attr">keyup.enter</span>=<span class="hljs-string">"add"</span>/></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> {nanoid} <span class="hljs-keyword">from</span> <span class="hljs-string">'nanoid'</span></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyHeader'</span>,</span><br><span class="language-javascript"> <span class="hljs-comment">// props: ['addTodo'], // 接收父组件传过来的方法</span></span><br><span class="language-javascript"> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">title</span>: <span class="hljs-string">''</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">add</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span>(!<span class="hljs-variable language_">this</span>.<span class="hljs-property">title</span>.<span class="hljs-title function_">trim</span>()) {</span><br><span class="language-javascript"> <span class="hljs-title function_">alert</span>(<span class="hljs-string">"输入的任务不能为空"</span>)</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> <span class="hljs-keyword">const</span> todoObj = {</span><br><span class="language-javascript"> <span class="hljs-attr">id</span>: <span class="hljs-title function_">nanoid</span>(), <span class="hljs-comment">// 生成一个唯一id</span></span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">title</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> <span class="hljs-comment">// this.addTodo(todoObj) // 将生成的任务,传递回去给父组件</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.$emit(<span class="hljs-string">'addTodo'</span>,todoObj)</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">title</span> = <span class="hljs-string">''</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*header*/</span></span><br><span class="language-css"><span class="hljs-selector-class">.todo-header</span> <span class="hljs-selector-tag">input</span> {</span><br><span class="language-css"> <span class="hljs-attribute">width</span>: <span class="hljs-number">560px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">28px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">font-size</span>: <span class="hljs-number">14px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ccc</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">4px</span> <span class="hljs-number">7px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-header</span> <span class="hljs-selector-tag">input</span><span class="hljs-selector-pseudo">:focus</span> {</span><br><span class="language-css"> <span class="hljs-attribute">outline</span>: none;</span><br><span class="language-css"> <span class="hljs-attribute">border-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">82</span>, <span class="hljs-number">168</span>, <span class="hljs-number">236</span>, <span class="hljs-number">0.8</span>);</span><br><span class="language-css"> <span class="hljs-attribute">box-shadow</span>: inset <span class="hljs-number">0</span> <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.075</span>), <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">8px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">82</span>, <span class="hljs-number">168</span>, <span class="hljs-number">236</span>, <span class="hljs-number">0.6</span>);</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>MyList.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-main"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">MyItem</span></span><br><span class="hljs-tag"> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"todoObj in todos"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:key</span>=<span class="hljs-string">"todoObj.id"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:todo</span> = <span class="hljs-string">"todoObj"</span></span><br><span class="hljs-tag"> ></span><span class="hljs-tag"></<span class="hljs-name">MyItem</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">ul</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">MyItem</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/MyItem"</span>;</span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyList'</span>,</span><br><span class="language-javascript"> <span class="hljs-attr">components</span>: {<span class="hljs-title class_">MyItem</span>},</span><br><span class="language-javascript"> <span class="hljs-comment">// props:['todos','checkTodo',"deleteTodo"]</span></span><br><span class="language-javascript"> <span class="hljs-attr">props</span>:[<span class="hljs-string">'todos'</span>]</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*main*/</span></span><br><span class="language-css"><span class="hljs-selector-class">.todo-main</span> {</span><br><span class="language-css"> <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">0px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">0px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-empty</span> {</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">10px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>MyItem.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">li</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">:checked</span>=<span class="hljs-string">"todo.completed"</span> @<span class="hljs-attr">change</span>=<span class="hljs-string">"handlerCheck(todo.id)"</span>/></span><br> <span class="hljs-comment"><!--这种方式也能实现修改propos,但是vue检测不到,不推荐这样做,子组件不要直接修改父组件传过来的值--></span><br> <span class="hljs-comment"><!--<input type="checkbox" v-model="todo.completed" />--></span><br> <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"!todo.isEdit"</span>></span>{{ todo.name }}<span class="hljs-tag"></<span class="hljs-name">span</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">input</span></span><br><span class="hljs-tag"> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"todo.isEdit"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:value</span>=<span class="hljs-string">"todo.name"</span></span><br><span class="hljs-tag"> @<span class="hljs-attr">blur</span>=<span class="hljs-string">"handlerBlur(todo,$event)"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">ref</span>=<span class="hljs-string">"editInput"</span></span><br><span class="hljs-tag"> ></span><br><br> <span class="hljs-tag"></<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-danger"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"handlerDelete(todo.id)"</span>></span>删除<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"!todo.isEdit"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-edit"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"handlerEdit(todo)"</span>></span>编辑<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">li</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyItem'</span>,</span><br><span class="language-javascript"> <span class="hljs-comment">//props:['todo','checkTodo','deleteTodo'],</span></span><br><span class="language-javascript"> <span class="hljs-attr">props</span>: [<span class="hljs-string">'todo'</span>],</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">handlerCheck</span>(<span class="hljs-params">id</span>) {</span><br><span class="language-javascript"> <span class="hljs-comment">// this.checkTodo(id) // 将勾选框发生变化的id传给爷爷</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$emit(<span class="hljs-string">'checkTodo'</span>, id)</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 删除</span></span><br><span class="language-javascript"> <span class="hljs-title function_">handlerDelete</span>(<span class="hljs-params">id</span>) {</span><br><span class="language-javascript"> <span class="hljs-comment">//this.deleteTodo(id);</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$emit(<span class="hljs-string">'deleteTodo'</span>, id)</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 编辑</span></span><br><span class="language-javascript"> <span class="hljs-title function_">handlerEdit</span>(<span class="hljs-params">todo</span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">if</span> (todo.<span class="hljs-title function_">hasOwnProperty</span>(<span class="hljs-string">'isEdit'</span>)) { <span class="hljs-comment">// 如果有这个属性</span></span><br><span class="language-javascript"> todo.<span class="hljs-property">isEdit</span> = <span class="hljs-literal">true</span></span><br><span class="language-javascript"> } <span class="hljs-keyword">else</span> { <span class="hljs-comment">// 没有这个</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.$set(todo, <span class="hljs-string">'isEdit'</span>, <span class="hljs-literal">true</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.$nextTick(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>){</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$refs</span>.<span class="hljs-property">editInput</span>.<span class="hljs-title function_">focus</span>()</span><br><span class="language-javascript"> })</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-comment">// 失去焦点回调,真正实现修改逻辑</span></span><br><span class="language-javascript"> <span class="hljs-title function_">handlerBlur</span>(<span class="hljs-params">todo, e</span>) {</span><br><span class="language-javascript"> todo.<span class="hljs-property">isEdit</span> = <span class="hljs-literal">false</span></span><br><span class="language-javascript"> <span class="hljs-keyword">if</span> (!e.<span class="hljs-property">target</span>.<span class="hljs-property">value</span>.<span class="hljs-title function_">trim</span>()) <span class="hljs-keyword">return</span> <span class="hljs-title function_">alert</span>(<span class="hljs-string">"任务名称不能为空"</span>)</span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$bus</span>.$emit(<span class="hljs-string">'updateTodo'</span>, todo.<span class="hljs-property">id</span>, e.<span class="hljs-property">target</span>.<span class="hljs-property">value</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*item*/</span></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> {</span><br><span class="language-css"> <span class="hljs-attribute">list-style</span>: none;</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">36px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">36px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">5px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">border-bottom</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">label</span> {</span><br><span class="language-css"> <span class="hljs-attribute">float</span>: left;</span><br><span class="language-css"> <span class="hljs-attribute">cursor</span>: pointer;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">label</span> <span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">input</span> {</span><br><span class="language-css"> <span class="hljs-attribute">vertical-align</span>: middle;</span><br><span class="language-css"> <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">6px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">position</span>: relative;</span><br><span class="language-css"> <span class="hljs-attribute">top</span>: -<span class="hljs-number">1px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span> <span class="hljs-selector-tag">button</span> {</span><br><span class="language-css"> <span class="hljs-attribute">float</span>: right;</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: none;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">3px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:before</span> {</span><br><span class="language-css"> <span class="hljs-attribute">content</span>: initial;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:last-child</span> {</span><br><span class="language-css"> <span class="hljs-attribute">border-bottom</span>: none;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:hover</span> {</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ddd</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:hover</span> <span class="hljs-selector-tag">button</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: block;</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>MyFooter.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"todo-footer"</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"total"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"isAll"</span>/></span><br> <span class="hljs-tag"></<span class="hljs-name">label</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">span</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">span</span>></span>已完成{{doneTotal}}<span class="hljs-tag"></<span class="hljs-name">span</span>></span> / 全部{{ total }}<br> <span class="hljs-tag"></<span class="hljs-name">span</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-danger"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"cleanAll"</span>></span>清除已完成任务<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyFooter'</span>,</span><br><span class="language-javascript"> <span class="hljs-comment">// props: ['todos','checkALLTodo', 'cleanAllTodo'],</span></span><br><span class="language-javascript"> <span class="hljs-attr">props</span>: [<span class="hljs-string">'todos'</span>],</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">cleanAll</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-comment">// this.cleanAllTodo()</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.$emit(<span class="hljs-string">'cleanAllTodo'</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">computed</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">total</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-property">length</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">doneTotal</span>(<span class="hljs-params"></span>){</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">todos</span>.<span class="hljs-title function_">reduce</span>(<span class="hljs-function">(<span class="hljs-params">pre,todo</span>) =></span> {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> pre + (todo.<span class="hljs-property">completed</span> == <span class="hljs-literal">true</span> ? <span class="hljs-number">1</span>: <span class="hljs-number">0</span>)</span><br><span class="language-javascript"> },<span class="hljs-number">0</span>)</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">isAll</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">get</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">total</span> == <span class="hljs-variable language_">this</span>.<span class="hljs-property">doneTotal</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">total</span> > <span class="hljs-number">0</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">set</span>(<span class="hljs-params">value</span>) {</span><br><span class="language-javascript"> <span class="hljs-comment">//this.checkALLTodo(value)</span></span><br><span class="language-javascript"> <span class="hljs-variable language_">this</span>.$emit(<span class="hljs-string">'checkALLTodo'</span>, value)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/*footer*/</span></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> {</span><br><span class="language-css"> <span class="hljs-attribute">height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">line-height</span>: <span class="hljs-number">40px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">6px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> <span class="hljs-selector-tag">label</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: inline-block;</span><br><span class="language-css"> <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">20px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">cursor</span>: pointer;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> <span class="hljs-selector-tag">label</span> <span class="hljs-selector-tag">input</span> {</span><br><span class="language-css"> <span class="hljs-attribute">position</span>: relative;</span><br><span class="language-css"> <span class="hljs-attribute">top</span>: -<span class="hljs-number">1px</span>;</span><br><span class="language-css"> <span class="hljs-attribute">vertical-align</span>: middle;</span><br><span class="language-css"> <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.todo-footer</span> <span class="hljs-selector-tag">button</span> {</span><br><span class="language-css"> <span class="hljs-attribute">float</span>: right;</span><br><span class="language-css"> <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <h3 id="nextTick"><a href="#nextTick" class="headerlink" title="nextTick"></a>nextTick</h3><ol> <li>语法:<code>his.$nextTick(回调函数)</code></li> <li>作用:在下一次DOM更新结束后执行其指定的回调。</li> <li>什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行.</li> </ol> <h3 id="消息订阅与发布-pubsub"><a href="#消息订阅与发布-pubsub" class="headerlink" title="消息订阅与发布(pubsub)"></a>消息订阅与发布(pubsub)</h3><p>1.安装</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm install pubsub-js<br></code></pre></td></tr></table></figure> <p>2.引入</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> pubsub <span class="hljs-keyword">from</span> <span class="hljs-string">'pubsub-js'</span><br></code></pre></td></tr></table></figure> <p>3.发布、订阅、取消</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-variable language_">this</span>.<span class="hljs-property">pubId</span> = pubsub.<span class="hljs-title function_">subscribe</span>(<span class="hljs-string">'消息名'</span>,<span class="hljs-string">'回调函数'</span>) <span class="hljs-comment">// 订阅消息</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-title function_">unsubscribe</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">pubId</span>) <span class="hljs-comment">// 取消订阅</span><br>pubsub.<span class="hljs-title function_">publish</span>(<span class="hljs-string">'消息名'</span>,数据) <span class="hljs-comment">// 发布消息</span><br></code></pre></td></tr></table></figure> <p>A.vue</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> pubsub <span class="hljs-keyword">from</span> <span class="hljs-string">'pubsub-js'</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> <span class="hljs-attr">name</span>: <span class="hljs-string">'A'</span>,<br> <span class="hljs-attr">components</span>: {},<br> <span class="hljs-attr">props</span>: {},<br> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">return</span> {}<br> },<br> <span class="hljs-attr">methods</span>: {<br> <span class="hljs-title function_">demo</span>(<span class="hljs-params">msgName, data</span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"订阅hello消息,msgName是消息名,data是数据"</span>,msgName ,data)<br> }<br> },<br> <span class="hljs-title function_">mounted</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-comment">// this.$bus.$on('hello',(data) => { // 这里也可以先在methods来定义方法,在这里回调</span><br> <span class="hljs-comment">// console.log('接收到B组件的data:' + data)</span><br> <span class="hljs-comment">// })</span><br><br> <span class="hljs-comment">// this.pubId = pubsub.subscribe('hello',(msgName, data) => { // /订阅消息</span><br> <span class="hljs-comment">// console.log("订阅hello消息,msgName是消息名,data是数据",msgName ,data)</span><br> <span class="hljs-comment">// })</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">pubId</span> = pubsub.<span class="hljs-title function_">subscribe</span>(<span class="hljs-string">'hello'</span>,<span class="hljs-variable language_">this</span>.<span class="hljs-property">demo</span>)<br> },<br> <span class="hljs-title function_">beforeDestroy</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-comment">// this.$bus.off('hello')</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">unsubscribe</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">pubId</span>) <span class="hljs-comment">// 取消订阅</span><br> }<br>}<br></code></pre></td></tr></table></figure> <p>B.vue</p> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> pubsub from <span class="hljs-string">'pubsub-js'</span><br>export <span class="hljs-keyword">default</span> {<br> name: <span class="hljs-string">'B'</span>,<br> components: {},<br> props: {},<br> data() {<br> <span class="hljs-keyword">return</span> {}<br> },<br> methods: {<br> send() {<br> <span class="hljs-comment">// this.$bus.$emit('hello',"我是B组件的数据")</span><br> pubsub.publish(<span class="hljs-string">'hello'</span>,<span class="hljs-number">666</span>) <span class="hljs-comment">// 发布消息</span><br> }<br> },<br>}<br></code></pre></td></tr></table></figure> <h2 id="Vuex"><a href="#Vuex" class="headerlink" title="Vuex"></a>Vuex</h2><ul> <li>官方解释:<strong>Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。</strong><ul> <li>它采用 集中式存储管理 应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。</li> <li>Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。</li> </ul> </li> <li>状态管理到底是什么?<ul> <li>状态管理模式、集中式存储管理这些名词听起来就非常高大上,让人捉摸不透。</li> <li>其实,你可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面。</li> <li>然后,将这个对象放在顶层的Vue实例中,让其他组件可以使用。</li> <li>那么,多个组件是不是就可以共享这个对象中的所有变量属性了呢?</li> </ul> </li> <li>等等,如果是这样的话,为什么官方还要专门出一个插件Vuex呢?难道我们不能自己封装一个对象来管理吗?<ul> <li>当然可以,只是我们要先想想VueJS带给我们最大的便利是什么呢?没错,就是响应式。</li> <li>如果你自己封装实现一个对象能不能保证它里面所有的属性做到响应式呢?当然也可以,只是自己封装可能稍微麻烦一些。</li> <li>不用怀疑,Vuex就是为了提供这样一个在多个组件间共享状态的插件,用它就可以了。</li> </ul> </li> </ul> <h3 id="单界面状态管理"><a href="#单界面状态管理" class="headerlink" title="单界面状态管理"></a>单界面状态管理</h3><p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704140742197.png" srcset="/img/loading.gif" lazyload alt="image-20220704140742197"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704141118572.png" srcset="/img/loading.gif" lazyload alt="image-20220704141118572"></p> <h3 id="多界面状态管理"><a href="#多界面状态管理" class="headerlink" title="多界面状态管理"></a>多界面状态管理</h3><p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704141053722.png" srcset="/img/loading.gif" lazyload alt="image-20220704141053722"></p> <h3 id="Vuex状态管理图例"><a href="#Vuex状态管理图例" class="headerlink" title="Vuex状态管理图例"></a>Vuex状态管理图例</h3><p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704141148985.png" srcset="/img/loading.gif" lazyload alt="image-20220704141148985"></p> <h3 id="安装和导入Vuex"><a href="#安装和导入Vuex" class="headerlink" title="安装和导入Vuex"></a>安装和导入Vuex</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm install vuex --save<br></code></pre></td></tr></table></figure> <p>src->store->index.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vue</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vuex</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vuex'</span><br><br><span class="hljs-title class_">Vue</span>.<span class="hljs-title function_">use</span>(<span class="hljs-title class_">Vuex</span>)<br><br><span class="hljs-keyword">const</span> store = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vuex</span>.<span class="hljs-title class_">Store</span>({<br> <span class="hljs-attr">state</span>: {<br> },<br> <span class="hljs-attr">mutations</span>: {<br> },<br> <span class="hljs-attr">actions</span>: {<br> },<br> <span class="hljs-attr">modules</span>: {<br> }<br>})<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> store<br><br></code></pre></td></tr></table></figure> <p>main.js</p> <ul> <li>挂载到Vue实例中,让所有的Vue组件都可以使用这个store对象</li> <li>来到main.js文件,导入store对象,并且放在new Vue中</li> <li>这样,在其他Vue组件中,我们就可以通过this.$store的方式,获取到这个store对象了</li> </ul> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vue</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'./App.vue'</span><br><span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">'./store'</span><br><br><span class="hljs-title class_">Vue</span>.<span class="hljs-property">config</span>.<span class="hljs-property">productionTip</span> = <span class="hljs-literal">false</span><br><br><span class="hljs-keyword">new</span> <span class="hljs-title class_">Vue</span>({<br> store,<br> <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-params">h</span> =></span> <span class="hljs-title function_">h</span>(<span class="hljs-title class_">App</span>)<br>}).$mount(<span class="hljs-string">'#app'</span>)<br><br></code></pre></td></tr></table></figure> <h3 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a><span id="mutations">基本使用</span></h3><p>APP.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>------APP组件------<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>{{this.$store.state.counter}}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"addCounter"</span>></span>+<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"subCounter"</span>></span>-<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">hello-vuex</span>></span><span class="hljs-tag"></<span class="hljs-name">hello-vuex</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br></code></pre></td></tr></table></figure> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> {<span class="hljs-variable constant_">INCREMENT</span>, <span class="hljs-variable constant_">DECREMENT</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">'./store/motations-types'</span><br> <span class="hljs-attr">methods</span>: {<br> <span class="hljs-title function_">addCounter</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span>.<span class="hljs-title function_">commit</span>(<span class="hljs-variable constant_">INCREMENT</span>)<br> },<br> <span class="hljs-title function_">subCounter</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span>.<span class="hljs-title function_">commit</span>(<span class="hljs-variable constant_">DECREMENT</span>)<br> }<br> }<br></code></pre></td></tr></table></figure> <p>store->index.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vue</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vuex</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vuex'</span><br><br><span class="hljs-keyword">import</span> mutations <span class="hljs-keyword">from</span> <span class="hljs-string">'./mutations'</span><br><br><span class="hljs-title class_">Vue</span>.<span class="hljs-title function_">use</span>(<span class="hljs-title class_">Vuex</span>)<br><br><span class="hljs-keyword">const</span> state = {<br> <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span><br>}<br><br><span class="hljs-keyword">const</span> store = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vuex</span>.<span class="hljs-title class_">Store</span>({<br> state,<br> mutations,<br> <span class="hljs-attr">actions</span>: {<br> },<br> <span class="hljs-attr">modules</span>: {<br> }<br>})<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> store<br><br></code></pre></td></tr></table></figure> <p>mutations.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { <span class="hljs-variable constant_">INCREMENT</span>, <span class="hljs-variable constant_">DECREMENT</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"./motations-types.js"</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> [<span class="hljs-variable constant_">INCREMENT</span>](state) { <span class="hljs-comment">// 默认会传入state</span><br> state.<span class="hljs-property">counter</span>++<br> },<br> [<span class="hljs-variable constant_">DECREMENT</span>](state) {<br> state.<span class="hljs-property">counter</span>--<br> }<br>}<br></code></pre></td></tr></table></figure> <p>motations-types.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">INCREMENT</span> = <span class="hljs-string">'increment'</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">DECREMENT</span> = <span class="hljs-string">'decrement'</span><br></code></pre></td></tr></table></figure> <ul> <li>1.提取出一个公共的store对象,用于保存在多个组件中共享的状态</li> <li>2.将store对象放置在new Vue对象中,这样可以保证在所有的组件中都可以使用到</li> <li>3.在其他组件中使用store对象中保存的状态即可<ul> <li>通过this.$store.state.属性的方式来访问状态</li> <li>通过this.$store.commit(‘mutation中方法’)来修改状态</li> </ul> </li> <li>注意事项:</li> <li>我们通过提交mutation的方式,而非直接改变store.state.count。</li> <li>这是因为Vuex可以更明确的追踪状态的变化,所以不要直接改变store.state.count的值。</li> </ul> <h3 id="State"><a href="#State" class="headerlink" title="State"></a>State</h3><p>Vuex提出使用单一状态树, 什么是单一状态树呢?<br>英文名称是Single Source of Truth,也可以翻译成单一数据源。</p> <h3 id="Getters"><a href="#Getters" class="headerlink" title="Getters"></a>Getters</h3><p>app.vue</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">h2</span>></span>------getters基本使用------<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br><span class="hljs-tag"><<span class="hljs-name">h2</span>></span>{{$store.getters.powerCounter}}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br><span class="hljs-tag"><<span class="hljs-name">p</span>></span>{{$store.getters.more20Age}}<span class="hljs-tag"></<span class="hljs-name">p</span>></span><br><span class="hljs-tag"><<span class="hljs-name">h2</span>></span>年龄超过20的数量:{{$store.getters.more20AgeLength}}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br><span class="hljs-tag"><<span class="hljs-name">p</span>></span>{{$store.getters.moreAgestu(12)}}<span class="hljs-tag"></<span class="hljs-name">p</span>></span><br></code></pre></td></tr></table></figure> <p>getters.js</p> <p><strong>getters默认是不能传递参数的, 如果希望传递参数, 那么只能让getters本身返回另一个函数.</strong></p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> <span class="hljs-title function_">powerCounter</span>(<span class="hljs-params">state</span>) {<br> <span class="hljs-keyword">return</span> state.<span class="hljs-property">counter</span> * state.<span class="hljs-property">counter</span><br> },<br> <span class="hljs-title function_">more20Age</span>(<span class="hljs-params">state</span>) {<br> <span class="hljs-keyword">return</span> state.<span class="hljs-property">students</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">s</span> =></span> s.<span class="hljs-property">age</span> >= <span class="hljs-number">20</span>) <br> },<br> <span class="hljs-title function_">more20AgeLength</span>(<span class="hljs-params">state, getters</span>){<br> <span class="hljs-keyword">return</span> getters.<span class="hljs-property">more20Age</span>.<span class="hljs-property">length</span><br> },<br> <span class="hljs-title function_">moreAgestu</span>(<span class="hljs-params">state</span>) {<br> <span class="hljs-comment">// return function (age) {</span><br> <span class="hljs-comment">// return state.students.filter(s => s.age > age)</span><br> <span class="hljs-comment">// }</span><br> <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-params">age</span> =></span> {<br> <span class="hljs-keyword">return</span> state.<span class="hljs-property">students</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">s</span> =></span> s.<span class="hljs-property">age</span> >= <span class="hljs-number">20</span>)<br> }<br> }<br>}<br></code></pre></td></tr></table></figure> <h3 id="Mutation(同步函数)"><a href="#Mutation(同步函数)" class="headerlink" title="Mutation(同步函数)"></a>Mutation(同步函数)</h3><ul> <li>Vuex的store状态的更新唯一方式:提交Mutation</li> <li>Mutation主要包括两部分:<ul> <li>字符串的事件类型(type)</li> <li>一个回调函数(handler),该回调函数的第一个参数就是state。</li> <li>mutation的定义方式:</li> </ul> </li> </ul> <p><a href="#mutations">代码</a></p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> {<span class="hljs-variable constant_">INCREMENT</span>, <span class="hljs-variable constant_">DECREMENT</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">'./store/motations-types'</span><br> <span class="hljs-attr">methods</span>: {<br> <span class="hljs-title function_">addCounter</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span>.<span class="hljs-title function_">commit</span>(<span class="hljs-variable constant_">INCREMENT</span>)<br> },<br> <span class="hljs-title function_">subCounter</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span>.<span class="hljs-title function_">commit</span>(<span class="hljs-variable constant_">DECREMENT</span>)<br> }<br> }<br></code></pre></td></tr></table></figure> <p>mutations.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { <span class="hljs-variable constant_">INCREMENT</span>, <span class="hljs-variable constant_">DECREMENT</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"./motations-types.js"</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> [<span class="hljs-variable constant_">INCREMENT</span>](state) { <span class="hljs-comment">// 默认会传入state</span><br> state.<span class="hljs-property">counter</span>++<br> },<br> [<span class="hljs-variable constant_">DECREMENT</span>](state) {<br> state.<span class="hljs-property">counter</span>--<br> }<br>}<br></code></pre></td></tr></table></figure> <p>motations-types.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">INCREMENT</span> = <span class="hljs-string">'increment'</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">DECREMENT</span> = <span class="hljs-string">'decrement'</span><br></code></pre></td></tr></table></figure> <h4 id="Mutation传递参数"><a href="#Mutation传递参数" class="headerlink" title="Mutation传递参数"></a>Mutation传递参数</h4><p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704164744613.png" srcset="/img/loading.gif" lazyload alt="image-20220704164744613"></p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-title function_">addCounter1</span>(<span class="hljs-params">count</span>) {<br> <span class="hljs-comment">// payload: 负载</span><br> <span class="hljs-comment">// 1.普通的提交封装</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span>.<span class="hljs-title function_">commit</span>(<span class="hljs-string">'addCounter'</span>, count)<br> },<br> <span class="hljs-title function_">subCounter1</span>(<span class="hljs-params">count</span>) {<br> <span class="hljs-comment">// // 2.特殊的提交封装</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span>.<span class="hljs-title function_">commit</span>({<br> <span class="hljs-attr">type</span>: <span class="hljs-string">'subCounter'</span>,<br> count<br> })<br> }<br></code></pre></td></tr></table></figure> <p>mutation.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { <span class="hljs-variable constant_">INCREMENT</span>, <span class="hljs-variable constant_">DECREMENT</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"./motations-types.js"</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> [<span class="hljs-variable constant_">INCREMENT</span>](state) { <span class="hljs-comment">// 默认会传入state</span><br> state.<span class="hljs-property">counter</span>++<br> },<br> [<span class="hljs-variable constant_">DECREMENT</span>](state) {<br> state.<span class="hljs-property">counter</span>--<br> },<br> <span class="hljs-title function_">addCounter</span>(<span class="hljs-params">state, n</span>) {<br> state.<span class="hljs-property">counter</span> += n<br> },<br> <span class="hljs-title function_">subCounter</span>(<span class="hljs-params">state, payload</span>) {<br> state.<span class="hljs-property">counter</span> -= payload.<span class="hljs-property">count</span><br> }<br>}<br></code></pre></td></tr></table></figure> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704170150819.png" srcset="/img/loading.gif" lazyload alt="image-20220704170150819"></p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-title function_">updateInfo</span>(<span class="hljs-params">state</span>) {<br> state.<span class="hljs-property">info</span>.<span class="hljs-property">name</span> = <span class="hljs-string">'modify'</span><br><br> <span class="hljs-comment">// 错误的代码: 不能在这里进行异步操作</span><br> <span class="hljs-comment">// setTimeout(() => {</span><br> <span class="hljs-comment">// state.info.name = 'modify'</span><br> <span class="hljs-comment">// }, 1000)</span><br> <br> <span class="hljs-comment">//state.info['address'] = '洛杉矶'</span><br> <br> <span class="hljs-comment">//Vue.set(state.info, 'address', '洛杉矶')</span><br> <span class="hljs-comment">// 该方式做不到响应式</span><br> <br> <span class="hljs-comment">// delete state.info.age</span><br> <span class="hljs-comment">//Vue.delete(state.info, 'age')</span><br> }<br></code></pre></td></tr></table></figure> <ul> <li>Vuex的store中的state是响应式的, 当state中的数据发生改变时, Vue组件会自动更新.</li> <li>这就要求我们必须遵守一些Vuex对应的规则:</li> <li>提前在store中初始化好所需的属性.</li> <li>当给state中的对象添加新属性时, 使用下面的方式:<ul> <li>方式一: 使用Vue.set(obj, ‘newProp’, 123)</li> <li>方式二: 用新对象给旧对象重新赋值</li> </ul> </li> </ul> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704181640574.png" srcset="/img/loading.gif" lazyload alt="image-20220704181640574"></p> <p><strong>通常情况下, Vuex要求我们Mutation中的方法必须是同步方法.</strong><br>主要的原因是当我们使用devtools时, 可以devtools可以帮助我们捕捉mutation的快照.<br>但是如果是异步操作, 那么devtools将不能很好的追踪这个操作什么时候会被完成.</p> <h3 id="Action(异步函数)"><a href="#Action(异步函数)" class="headerlink" title="Action(异步函数)"></a>Action(异步函数)</h3><ul> <li>我们强调, 不要再Mutation中进行异步操作.</li> <li>但是某些情况, 我们确实希望在Vuex中进行一些异步操作, 比如网络请求, 必然是异步的. 这个时候怎么处理呢?</li> <li>Action类似于Mutation, 但是是用来代替Mutation进行异步操作的.</li> <li>Action的基本使用代码如下:</li> <li>context是什么?<ul> <li>context是和store对象具有相同方法和属性的对象.</li> <li>也就是说, 我们可以通过context去进行commit相关的操作, 也可以获取context.state等.</li> <li>我们定义了actions, 然后又在actions中去进行commit, 这不是脱裤放屁吗?</li> <li>事实上并不是这样, 如果在Vuex中有异步操作, 那么我们就可以在actions中完成了.</li> </ul> </li> </ul> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704182957366.png" srcset="/img/loading.gif" lazyload alt="image-20220704182957366"></p> <p>在Vue组件中, 如果我们调用action中的方法, 那么就需要使用dispatch</p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704185842591.png" srcset="/img/loading.gif" lazyload alt="image-20220704185842591"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704205205735.png" srcset="/img/loading.gif" lazyload alt="image-20220704205205735"></p> <p>actions.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> <span class="hljs-comment">// aUpdateInfo(context, payload) {</span><br> <span class="hljs-comment">// setTimeout(() => {</span><br> <span class="hljs-comment">// context.commit('updateInfo')</span><br> <span class="hljs-comment">// console.log(payload.message)</span><br> <span class="hljs-comment">// payload.success()</span><br> <span class="hljs-comment">// },5000)</span><br> <span class="hljs-comment">// }</span><br><br> <span class="hljs-title function_">aUpdateInfo</span>(<span class="hljs-params">context, payload</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =></span> {<br> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =></span> {<br> context.<span class="hljs-title function_">commit</span>(<span class="hljs-string">'updateInfo'</span>);<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(payload);<br> <br> <span class="hljs-title function_">resolve</span>(<span class="hljs-string">'1111111'</span>)<br> }, <span class="hljs-number">1000</span>)<br> })<br> }<br>}<br></code></pre></td></tr></table></figure> <p>Info.vue</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-title function_">updateInfo</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-comment">// this.$store.commit('updateInfo')</span><br> <span class="hljs-comment">// this.$store.dispatch('aUpdateInfo', {</span><br> <span class="hljs-comment">// message: '我是携带的信息',</span><br> <span class="hljs-comment">// success: () => {</span><br> <span class="hljs-comment">// console.log('里面已经完成了');</span><br> <span class="hljs-comment">// }</span><br> <span class="hljs-comment">// })</span><br><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span><br> .<span class="hljs-title function_">dispatch</span>(<span class="hljs-string">'aUpdateInfo'</span>, <span class="hljs-string">'我是携带的信息'</span>)<br> .<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'里面完成了提交'</span>);<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res);<br> })<br> }<br></code></pre></td></tr></table></figure> <h3 id="Module"><a href="#Module" class="headerlink" title="Module"></a>Module</h3><p>我们在moduleA中添加state、mutations、getters<br>mutation和getters接收的第一个参数是局部状态对象</p> <p>虽然, 我们的doubleCount和increment都是定义在对象内部的.<br>但是在调用的时候, 依然是通过this.$store来直接调用的.</p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704210627095.png" srcset="/img/loading.gif" lazyload alt="image-20220704210627095"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704210950595.png" srcset="/img/loading.gif" lazyload alt="image-20220704210950595"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704211032754.png" srcset="/img/loading.gif" lazyload alt="image-20220704211032754"></p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">h2</span>></span>{{$store.state.a.counter}}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br><span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"addInfoCounter"</span>></span>+<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br></code></pre></td></tr></table></figure> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-title function_">addInfoCounter</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$store</span>.<span class="hljs-title function_">commit</span>(<span class="hljs-string">'add'</span>)<br>}<br></code></pre></td></tr></table></figure> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> <span class="hljs-variable language_">module</span> = {<br> <span class="hljs-attr">state</span>: {<br> <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span><br> },<br> <span class="hljs-attr">mutations</span>:{<br> <span class="hljs-title function_">add</span>(<span class="hljs-params">state</span>){<br> state.<span class="hljs-property">counter</span> ++<br> }<br> }<br>}<br></code></pre></td></tr></table></figure> <h3 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h3><p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220704205447837.png" srcset="/img/loading.gif" lazyload alt="image-20220704205447837"></p> <h3 id="四个map方法的使用"><a href="#四个map方法的使用" class="headerlink" title="四个map方法的使用"></a>四个map方法的使用</h3><p>使用前先引入</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> {mapState, mapGetters, mapMutations, mapActions} <span class="hljs-keyword">from</span> <span class="hljs-string">'vuex'</span><br></code></pre></td></tr></table></figure> <h4 id="mapState"><a href="#mapState" class="headerlink" title="mapState"></a>mapState</h4><blockquote> <p>用于帮助我们映射state中的数据为计算属性</p> </blockquote> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-attr">computed</span>: {<br> <span class="hljs-comment">// 借助mapState生成计算属性: num、 name、region(对象写法)</span><br> <span class="hljs-comment">// 对象写法可以映射$store.state里面的数据为一个新的名字</span><br> <span class="hljs-comment">// ...mapState({num:'num',name:'name',region:'region'})</span><br><br> <span class="hljs-comment">// 借助mapState生成计算属性: num、 name、region(数组写法)</span><br> <span class="hljs-comment">// 和$store.state名字一样</span><br> ...<span class="hljs-title function_">mapState</span>([<span class="hljs-string">'num'</span>,<span class="hljs-string">'name'</span>,<span class="hljs-string">'region'</span>]) <br>},<br></code></pre></td></tr></table></figure> <h4 id="mapperGetters"><a href="#mapperGetters" class="headerlink" title="mapperGetters"></a>mapperGetters</h4><blockquote> <p>用于帮助我们映射getters中的数据为计算属性</p> </blockquote> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-attr">computed</span>: {<br> <span class="hljs-comment">// 借助mapGetters生成计算属性: bigNum(对象写法)</span><br> <span class="hljs-comment">// ...mapGetters({bigNum:'bigNum'}),</span><br> <span class="hljs-comment">// 借助mapGetters生成计算属性: bigNum(数组写法)</span><br> ...<span class="hljs-title function_">mapGetters</span>([<span class="hljs-string">'bigNum'</span>])<br> },<br></code></pre></td></tr></table></figure> <h4 id="mapMutations"><a href="#mapMutations" class="headerlink" title="mapMutations"></a>mapMutations</h4><blockquote> <p>用于帮助我们生成与mutations对话的方法,即:包含 $store.commit(xxx)的函数</p> </blockquote> <h4 id="mapActions"><a href="#mapActions" class="headerlink" title="mapActions"></a>mapActions</h4><blockquote> <p>用于帮助我们生成actions对话的方法,即:包含$store.dispatch(xx)的函数</p> <p>注:调用时候要传递参数:</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"increment(n)"</span>></span>+<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br><span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"decrement(n)"</span>></span>-<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br></code></pre></td></tr></table></figure> </blockquote> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-attr">methods</span>: {<br> <span class="hljs-comment">// increment(){</span><br> <span class="hljs-comment">// this.$store.commit('JIA',this.n)</span><br> <span class="hljs-comment">// },</span><br> <span class="hljs-comment">// decrement(){</span><br> <span class="hljs-comment">// this.$store.commit('JIAN',this.n)</span><br> <span class="hljs-comment">// },</span><br> <span class="hljs-comment">// incrementOdd(){</span><br> <span class="hljs-comment">// this.$store.dispatch('jiaOdd',this.n)</span><br> <span class="hljs-comment">// },</span><br> <span class="hljs-comment">// incrementWait(){</span><br> <span class="hljs-comment">// this.$store.dispatch('jiaWait',this.n)</span><br> <span class="hljs-comment">// },</span><br> <span class="hljs-comment">// 对象写法</span><br> ...<span class="hljs-title function_">mapMutations</span>({<span class="hljs-attr">increment</span>:<span class="hljs-string">'JIA'</span>,<span class="hljs-attr">decrement</span>:<span class="hljs-string">'JIAN'</span>}),<br> <span class="hljs-comment">// 数组写法</span><br> <span class="hljs-comment">// ...mapMutations(['JIA','JIAN']),</span><br><br> <span class="hljs-comment">// 对象写法</span><br> ...<span class="hljs-title function_">mapActions</span>({<span class="hljs-attr">incrementOdd</span>:<span class="hljs-string">'jiaOdd'</span>,<span class="hljs-attr">incrementWait</span>:<span class="hljs-string">'jiaWait'</span>}),<br> <span class="hljs-comment">// 数组写法</span><br> <span class="hljs-comment">//...mapActions(['jiaOdd','jiaWait'])</span><br>},<br></code></pre></td></tr></table></figure> <p>完整代码:</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>当前求和为:{{num}}<span class="hljs-tag"></<span class="hljs-name">h1</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>放大10倍为:{{bigNum}}<span class="hljs-tag"></<span class="hljs-name">h1</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>我叫:{{name}},来自{{region}}<span class="hljs-tag"></<span class="hljs-name">h1</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">select</span> <span class="hljs-attr">v-model.number</span>=<span class="hljs-string">"n"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"1"</span>></span>1<span class="hljs-tag"></<span class="hljs-name">option</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"2"</span>></span>2<span class="hljs-tag"></<span class="hljs-name">option</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"3"</span>></span>3<span class="hljs-tag"></<span class="hljs-name">option</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">select</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"increment(n)"</span>></span>+<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"decrement(n)"</span>></span>-<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"incrementOdd(n)"</span>></span>当前求和为奇数再加<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"incrementWait(n)"</span>></span>等一等再加<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> {mapState, mapGetters, mapMutations, mapActions} <span class="hljs-keyword">from</span> <span class="hljs-string">'vuex'</span></span><br><span class="language-javascript"> <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>:<span class="hljs-string">'Count'</span>,</span><br><span class="language-javascript"> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">n</span>:<span class="hljs-number">1</span>, <span class="hljs-comment">//用户选择的数字</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">computed</span>: {</span><br><span class="language-javascript"> <span class="hljs-comment">// 借助mapState生成计算属性: num、 name、region(对象写法)</span></span><br><span class="language-javascript"> <span class="hljs-comment">// 对象写法可以映射$store.state里面的数据为一个新的名字</span></span><br><span class="language-javascript"> <span class="hljs-comment">// ...mapState({num:'num',name:'name',region:'region'}),</span></span><br><span class="language-javascript"></span><br><span class="language-javascript"> <span class="hljs-comment">// 借助mapState生成计算属性: num、 name、region(数组写法)</span></span><br><span class="language-javascript"> <span class="hljs-comment">// 和$store.state名字一样</span></span><br><span class="language-javascript"> ...<span class="hljs-title function_">mapState</span>([<span class="hljs-string">'num'</span>,<span class="hljs-string">'name'</span>,<span class="hljs-string">'region'</span>]),</span><br><span class="language-javascript"></span><br><span class="language-javascript"> <span class="hljs-comment">// 借助mapGetters生成计算属性: bigNum(对象写法)</span></span><br><span class="language-javascript"> <span class="hljs-comment">// ...mapGetters({bigNum:'bigNum'}),</span></span><br><span class="language-javascript"> <span class="hljs-comment">// 借助mapGetters生成计算属性: bigNum(数组写法)</span></span><br><span class="language-javascript"> ...<span class="hljs-title function_">mapGetters</span>([<span class="hljs-string">'bigNum'</span>])</span><br><span class="language-javascript"></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-comment">// increment(){</span></span><br><span class="language-javascript"> <span class="hljs-comment">// this.$store.commit('JIA',this.n)</span></span><br><span class="language-javascript"> <span class="hljs-comment">// },</span></span><br><span class="language-javascript"> <span class="hljs-comment">// decrement(){</span></span><br><span class="language-javascript"> <span class="hljs-comment">// this.$store.commit('JIAN',this.n)</span></span><br><span class="language-javascript"> <span class="hljs-comment">// },</span></span><br><span class="language-javascript"> <span class="hljs-comment">// incrementOdd(){</span></span><br><span class="language-javascript"> <span class="hljs-comment">// this.$store.dispatch('jiaOdd',this.n)</span></span><br><span class="language-javascript"> <span class="hljs-comment">// },</span></span><br><span class="language-javascript"> <span class="hljs-comment">// incrementWait(){</span></span><br><span class="language-javascript"> <span class="hljs-comment">// this.$store.dispatch('jiaWait',this.n)</span></span><br><span class="language-javascript"> <span class="hljs-comment">// },</span></span><br><span class="language-javascript"> <span class="hljs-comment">// 对象写法</span></span><br><span class="language-javascript"> ...<span class="hljs-title function_">mapMutations</span>({<span class="hljs-attr">increment</span>:<span class="hljs-string">'JIA'</span>,<span class="hljs-attr">decrement</span>:<span class="hljs-string">'JIAN'</span>}),</span><br><span class="language-javascript"> <span class="hljs-comment">// 数组写法</span></span><br><span class="language-javascript"> <span class="hljs-comment">// ...mapMutations(['JIA','JIAN']),</span></span><br><span class="language-javascript"></span><br><span class="language-javascript"> <span class="hljs-comment">// 对象写法</span></span><br><span class="language-javascript"> ...<span class="hljs-title function_">mapActions</span>({<span class="hljs-attr">incrementOdd</span>:<span class="hljs-string">'jiaOdd'</span>,<span class="hljs-attr">incrementWait</span>:<span class="hljs-string">'jiaWait'</span>}),</span><br><span class="language-javascript"> <span class="hljs-comment">// 数组写法</span></span><br><span class="language-javascript"> <span class="hljs-comment">//...mapActions(['jiaOdd','jiaWait'])</span></span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"css"</span>></span><span class="language-css"></span><br><span class="language-css"> <span class="hljs-selector-tag">button</span>{</span><br><span class="language-css"> <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">5px</span>;</span><br><span class="language-css"> }</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <h3 id="模块管理"><a href="#模块管理" class="headerlink" title="模块管理"></a>模块管理</h3><p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220824224508885.png" srcset="/img/loading.gif" lazyload alt="image-20220824224508885"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220824224722689.png" srcset="/img/loading.gif" lazyload alt="image-20220824224722689"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220824225043879.png" srcset="/img/loading.gif" lazyload alt="image-20220824225043879"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220824225701798.png" srcset="/img/loading.gif" lazyload alt="image-20220824225701798"></p> <p>完整代码:</p> <p>store/count.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//求和相关的配置</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> <span class="hljs-attr">namespaced</span>:<span class="hljs-literal">true</span>,<br> <span class="hljs-attr">actions</span>:{<br> <span class="hljs-title function_">jiaOdd</span>(<span class="hljs-params">context,value</span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'actions中的jiaOdd被调用了'</span>)<br> <span class="hljs-keyword">if</span>(context.<span class="hljs-property">state</span>.<span class="hljs-property">sum</span> % <span class="hljs-number">2</span>){<br> context.<span class="hljs-title function_">commit</span>(<span class="hljs-string">'JIA'</span>,value)<br> }<br> },<br> <span class="hljs-title function_">jiaWait</span>(<span class="hljs-params">context,value</span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'actions中的jiaWait被调用了'</span>)<br> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">()=></span>{<br> context.<span class="hljs-title function_">commit</span>(<span class="hljs-string">'JIA'</span>,value)<br> },<span class="hljs-number">500</span>)<br> }<br> },<br> <span class="hljs-attr">mutations</span>:{<br> <span class="hljs-title function_">JIA</span>(<span class="hljs-params">state,value</span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'mutations中的JIA被调用了'</span>)<br> state.<span class="hljs-property">sum</span> += value<br> },<br> <span class="hljs-title function_">JIAN</span>(<span class="hljs-params">state,value</span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'mutations中的JIAN被调用了'</span>)<br> state.<span class="hljs-property">sum</span> -= value<br> },<br> },<br> <span class="hljs-attr">state</span>:{<br> <span class="hljs-attr">sum</span>:<span class="hljs-number">0</span>, <span class="hljs-comment">//当前的和</span><br> <span class="hljs-attr">school</span>:<span class="hljs-string">'尚硅谷'</span>,<br> <span class="hljs-attr">subject</span>:<span class="hljs-string">'前端'</span>,<br> },<br> <span class="hljs-attr">getters</span>:{<br> <span class="hljs-title function_">bigSum</span>(<span class="hljs-params">state</span>){<br> <span class="hljs-keyword">return</span> state.<span class="hljs-property">sum</span>*<span class="hljs-number">10</span><br> }<br> },<br>}<br></code></pre></td></tr></table></figure> <p>store/person.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//人员管理相关的配置</span><br><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span><br><span class="hljs-keyword">import</span> { nanoid } <span class="hljs-keyword">from</span> <span class="hljs-string">'nanoid'</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> <span class="hljs-attr">namespaced</span>:<span class="hljs-literal">true</span>,<br> <span class="hljs-attr">actions</span>:{<br> <span class="hljs-title function_">addPersonWang</span>(<span class="hljs-params">context,value</span>){<br> <span class="hljs-keyword">if</span>(value.<span class="hljs-property">name</span>.<span class="hljs-title function_">indexOf</span>(<span class="hljs-string">'王'</span>) === <span class="hljs-number">0</span>){<br> context.<span class="hljs-title function_">commit</span>(<span class="hljs-string">'ADD_PERSON'</span>,value)<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-title function_">alert</span>(<span class="hljs-string">'添加的人必须姓王!'</span>)<br> }<br> },<br> <span class="hljs-title function_">addPersonServer</span>(<span class="hljs-params">context</span>){<br> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'https://api.uixsj.cn/hitokoto/get?type=social'</span>).<span class="hljs-title function_">then</span>(<br> <span class="hljs-function"><span class="hljs-params">response</span> =></span> {<br> context.<span class="hljs-title function_">commit</span>(<span class="hljs-string">'ADD_PERSON'</span>,{<span class="hljs-attr">id</span>:<span class="hljs-title function_">nanoid</span>(),<span class="hljs-attr">name</span>:response.<span class="hljs-property">data</span>})<br> },<br> <span class="hljs-function"><span class="hljs-params">error</span> =></span> {<br> <span class="hljs-title function_">alert</span>(error.<span class="hljs-property">message</span>)<br> }<br> )<br> }<br> },<br> <span class="hljs-attr">mutations</span>:{<br> <span class="hljs-title function_">ADD_PERSON</span>(<span class="hljs-params">state,value</span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'mutations中的ADD_PERSON被调用了'</span>)<br> state.<span class="hljs-property">personList</span>.<span class="hljs-title function_">unshift</span>(value)<br> }<br> },<br> <span class="hljs-attr">state</span>:{<br> <span class="hljs-attr">personList</span>:[<br> {<span class="hljs-attr">id</span>:<span class="hljs-string">'001'</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">'张三'</span>}<br> ]<br> },<br> <span class="hljs-attr">getters</span>:{<br> <span class="hljs-title function_">firstPersonName</span>(<span class="hljs-params">state</span>){<br> <span class="hljs-keyword">return</span> state.<span class="hljs-property">personList</span>[<span class="hljs-number">0</span>].<span class="hljs-property">name</span><br> }<br> },<br>}<br></code></pre></td></tr></table></figure> <p>store/index.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//该文件用于创建Vuex中最为核心的store</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vue</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span><br><span class="hljs-comment">//引入Vuex</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Vuex</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'vuex'</span><br><span class="hljs-keyword">import</span> countOptions <span class="hljs-keyword">from</span> <span class="hljs-string">'./count'</span><br><span class="hljs-keyword">import</span> personOptions <span class="hljs-keyword">from</span> <span class="hljs-string">'./person'</span><br><span class="hljs-comment">//应用Vuex插件</span><br><span class="hljs-title class_">Vue</span>.<span class="hljs-title function_">use</span>(<span class="hljs-title class_">Vuex</span>)<br><br><span class="hljs-comment">//创建并暴露store</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vuex</span>.<span class="hljs-title class_">Store</span>({<br> <span class="hljs-attr">modules</span>:{<br> <span class="hljs-attr">countAbout</span>:countOptions,<br> <span class="hljs-attr">personAbout</span>:personOptions<br> }<br>})<br></code></pre></td></tr></table></figure> <p>Count.vue</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><code class="hljs vue"><template><br> <div><br> <h1>当前求和为:{{sum}}</h1><br> <h3>当前求和放大10倍为:{{bigSum}}</h3><br> <h3>我在{{school}},学习{{subject}}</h3><br> <h3 style="color:red">Person组件的总人数是:{{personList.length}}</h3><br> <select v-model.number="n"><br> <option value="1">1</option><br> <option value="2">2</option><br> <option value="3">3</option><br> </select><br> <button @click="increment(n)">+</button><br> <button @click="decrement(n)">-</button><br> <button @click="incrementOdd(n)">当前求和为奇数再加</button><br> <button @click="incrementWait(n)">等一等再加</button><br> </div><br></template><br><br><script><br> import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'<br> export default {<br> name:'Count',<br> data() {<br> return {<br> n:1, //用户选择的数字<br> }<br> },<br> computed:{<br> //借助mapState生成计算属性,从state中读取数据。(数组写法)<br> ...mapState('countAbout',['sum','school','subject']),<br> ...mapState('personAbout',['personList']),<br> //借助mapGetters生成计算属性,从getters中读取数据。(数组写法)<br> ...mapGetters('countAbout',['bigSum'])<br> },<br> methods: {<br> //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)<br> ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),<br> //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)<br> ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})<br> },<br> mounted() {<br> console.log(this.$store)<br> },<br> }<br></script><br><br><style lang="css"><br> button{<br> margin-left: 5px;<br> }<br></style><br><br></code></pre></td></tr></table></figure> <p>Person.vue</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><code class="hljs vue"><template><br> <div><br> <h1>人员列表</h1><br> <h3 style="color:red">Count组件求和为:{{sum}}</h3><br> <h3>列表中第一个人的名字是:{{firstPersonName}}</h3><br> <input type="text" placeholder="请输入名字" v-model="name"><br> <button @click="add">添加</button><br> <button @click="addWang">添加一个姓王的人</button><br> <button @click="addPersonServer">添加一个人,名字随机</button><br> <ul><br> <li v-for="p in personList" :key="p.id">{{p.name}}</li><br> </ul><br> </div><br></template><br><br><script><br> import {nanoid} from 'nanoid'<br> export default {<br> name:'Person',<br> data() {<br> return {<br> name:''<br> }<br> },<br> computed:{<br> personList(){<br> return this.$store.state.personAbout.personList<br> },<br> sum(){<br> return this.$store.state.countAbout.sum<br> },<br> firstPersonName(){<br> return this.$store.getters['personAbout/firstPersonName']<br> }<br> },<br> methods: {<br> add(){<br> const personObj = {id:nanoid(),name:this.name}<br> this.$store.commit('personAbout/ADD_PERSON',personObj)<br> this.name = ''<br> },<br> addWang(){<br> const personObj = {id:nanoid(),name:this.name}<br> this.$store.dispatch('personAbout/addPersonWang',personObj)<br> this.name = ''<br> },<br> addPersonServer(){<br> this.$store.dispatch('personAbout/addPersonServer')<br> }<br> },<br> }<br></script><br><br></code></pre></td></tr></table></figure> <h2 id="axios"><a href="#axios" class="headerlink" title="axios"></a>axios</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm install axios --save<br></code></pre></td></tr></table></figure> <p><a target="_blank" rel="noopener" href="http://httpbin.org/">http://httpbin.org/</a></p> <p><a target="_blank" rel="noopener" href="http://123.207.32.32:8000/home/multidata">http://123.207.32.32:8000/home/multidata</a></p> <p><a target="_blank" rel="noopener" href="http://123.207.32.32:8000/home/data?type=sell&page=1">http://123.207.32.32:8000/home/data?type=sell&page=1</a></p> <p>Vue中发送网络请求有非常多的方式, 那么, 在开发中, 如何选择呢?</p> <ul> <li><p>选择一: 传统的Ajax是基于XMLHttpRequest(XHR)</p> <ul> <li>为什么不用它呢?<ul> <li>非常好解释, 配置和调用方式等非常混乱.</li> <li>编码起来看起来就非常蛋疼.</li> <li>所以真实开发中很少直接使用, 而是使用jQuery-Ajax</li> </ul> </li> </ul> </li> <li><p>选择二: 在前面的学习中, 我们经常会使用jQuery-Ajax<br>相对于传统的Ajax非常好用.</p> <ul> <li>为什么不选择它呢?<ul> <li>首先, 我们先明确一点: 在Vue的整个开发中都是不需要使用jQuery了.</li> <li>那么, 就意味着为了方便我们进行一个网络请求, 特意引用一个jQuery, 你觉得合理吗?</li> <li>jQuery的代码1w+行.</li> <li>Vue的代码才1w+行.</li> <li>完全没有必要为了用网络请求就引用这个重量级的框架.</li> </ul> </li> </ul> </li> <li><p>选择三: 官方在Vue1.x的时候, 推出了Vue-resource.</p> <p>Vue-resource的体积相对于jQuery小很多.<br>另外Vue-resource是官方推出的.</p> <ul> <li>为什么不选择它呢?</li> <li>在Vue2.0退出后, Vue作者就在GitHub的Issues中说明了去掉vue-resource, 并且以后也不会再更新.</li> <li>那么意味着以后vue-reource不再支持新的版本时, 也不会再继续更新和维护.</li> <li>对以后的项目开发和维护都存在很大的隐患.</li> </ul> </li> <li><p>选择四: 在说明不再继续更新和维护vue-resource的同时, 作者还推荐了一个框架: axios<br>axios有非常多的优点, 并且用起来也非常方便.</p> </li> </ul> <h3 id="jsonp"><a href="#jsonp" class="headerlink" title="jsonp"></a>jsonp</h3><ul> <li>在前端开发中, 我们一种常见的网络请求方式就是JSONP</li> <li>使用JSONP最主要的原因往往是为了解决跨域访问的问题.<ul> <li>JSONP的原理是什么呢?<ul> <li>JSONP的核心在于通过<script>标签的src来帮助我们请求数据.</li> <li>原因是我们的项目部署在domain1.com服务器上时, 是不能直接访问domain2.com服务器上的资料的.</li> <li>这个时候, 我们利用<script>标签的src帮助我们去服务器请求到数据, 将数据当做一个javascript的</li> <li>函数来执行, 并且执行的过程中传入我们需要的json.</li> <li>所以, 封装jsonp的核心就在于我们监听window上的jsonp进行回调时的名称.</li> </ul> </li> </ul> </li> </ul> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220705090654925.png" srcset="/img/loading.gif" lazyload alt="image-20220705090654925"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220705090746429.png" srcset="/img/loading.gif" lazyload alt="image-20220705090746429"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220705090823031.png" srcset="/img/loading.gif" lazyload alt="image-20220705090823031"></p> <h3 id="axios特点"><a href="#axios特点" class="headerlink" title="axios特点"></a>axios特点</h3><ul> <li>在浏览器中发送 XMLHttpRequests 请求</li> <li>在 node.js 中发送 http请求</li> <li>支持 Promise API</li> <li>拦截请求和响应</li> <li>转换请求和响应数据</li> </ul> <p>支持多种请求方式:</p> <ul> <li>axios(config)</li> <li>axios.request(config)</li> <li>axios.get(url[, config])</li> <li>axios.delete(url[, config])</li> <li>axios.head(url[, config])</li> <li>axios.post(url[, data[, config]])</li> <li>axios.put(url[, data[, config]])</li> <li>axios.patch(url[, data[, config]])</li> </ul> <h3 id="发送get请求"><a href="#发送get请求" class="headerlink" title="发送get请求"></a>发送get请求</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-title function_">axios</span>({<br> <span class="hljs-attr">url</span>: <span class="hljs-string">'http://123.207.32.32:8000/home/multidata'</span>,<br> <span class="hljs-attr">method</span>: <span class="hljs-string">'get'</span> <span class="hljs-comment">// 默认是get请求</span><br>}).<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res)<br>})<br></code></pre></td></tr></table></figure> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220705092850949.png" srcset="/img/loading.gif" lazyload alt="image-20220705092850949"></p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript">axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'http://123.207.32.32:8000/home/data'</span>,<br> {<span class="hljs-attr">params</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">'shell'</span>, <span class="hljs-attr">page</span>: <span class="hljs-number">1</span>}})<br> .<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res)<br> })<br></code></pre></td></tr></table></figure> <p>使用axios.all, 可以放入多个请求的数组.<br>axios.all([]) 返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2] 展开为 res1, res2</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript">axios.<span class="hljs-title function_">all</span>([axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'http://123.207.32.32:8000/home/multidata'</span>),axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'http://123.207.32.32:8000/home/data'</span>,<br> {<span class="hljs-attr">params</span>: {<span class="hljs-attr">type</span>: <span class="hljs-string">'shell'</span>, <span class="hljs-attr">page</span>: <span class="hljs-number">1</span>}})<br>]).<span class="hljs-title function_">then</span>(axios.<span class="hljs-title function_">spread</span>(<span class="hljs-function">(<span class="hljs-params">res1, res2</span>) =></span>{<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res1)<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res2)<br>}))<br></code></pre></td></tr></table></figure> <p>全局配置</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">axios.<span class="hljs-property">defaults</span>.<span class="hljs-property">baseURL</span> = ‘<span class="hljs-number">123.207</span><span class="hljs-number">.32</span><span class="hljs-number">.32</span>:<span class="hljs-number">8000</span>’<br>axios.<span class="hljs-property">defaults</span>.<span class="hljs-property">headers</span>.<span class="hljs-property">post</span>[‘<span class="hljs-title class_">Content</span>-<span class="hljs-title class_">Type</span>’] = ‘application/x-www-form-urlencoded’;<br></code></pre></td></tr></table></figure> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript">axios.<span class="hljs-property">defaults</span>.<span class="hljs-property">baseURL</span> = <span class="hljs-string">"http://123.207.32.32:8000"</span><br><br>axios.<span class="hljs-title function_">all</span>([axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/home/multidata'</span>),axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/home/data'</span>,<br> {<span class="hljs-attr">params</span>: {<span class="hljs-attr">type</span>: <span class="hljs-string">'shell'</span>, <span class="hljs-attr">page</span>: <span class="hljs-number">1</span>}})<br>]).<span class="hljs-title function_">then</span>(axios.<span class="hljs-title function_">spread</span>(<span class="hljs-function">(<span class="hljs-params">res1, res2</span>) =></span>{<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res1)<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res2)<br>}))<br></code></pre></td></tr></table></figure> <ul> <li>请求地址<br>url: '/user',</li> <li>请求类型<br>method: 'get',</li> <li>请根路径<br>baseURL: '<a target="_blank" rel="noopener" href="http://www.mt.com/api'">http://www.mt.com/api'</a>,</li> <li>请求前的数据处理<br>transformRequest:[function(data){}],</li> <li>请求后的数据处理<br>transformResponse: [function(data){}],</li> <li>自定义的请求头<br>headers:{'x-Requested-With':'XMLHttpRequest'},</li> <li>URL查询对象<br>params:{ id: 12 },</li> <li>查询对象序列化函数<br>paramsSerializer: function(params){ }<br><strong>request body</strong><br>data: { key: 'aa'},</li> <li>超时设置s<br>timeout: 1000,</li> <li>跨域是否带Token<br>withCredentials: false,</li> <li>自定义请求处理<br>adapter: function(resolve, reject, config){},</li> <li>身份验证信息<br>auth: { uname: '', pwd: '12'},</li> <li>响应的数据格式 json / blob /document /arraybuffer / text / stream<br>responseType: 'json',</li> </ul> <h3 id="axios实例"><a href="#axios实例" class="headerlink" title="axios实例"></a>axios实例</h3><ul> <li>为什么要创建axios的实例呢?<ul> <li>当我们从axios模块中导入对象时, 使用的实例是默认的实例.</li> <li>当给该实例设置一些默认配置时, 这些配置就被固定下来了.</li> <li>但是后续开发中, 某些配置可能会不太一样.</li> <li>比如某些请求需要使用特定的baseURL或者timeout或者content-Type等.</li> <li>这个时候, 我们就可以创建新的实例, 并且传入属于该实例的配置信息.</li> </ul> </li> </ul> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 创建新的实例</span><br><span class="hljs-keyword">const</span> axiosInstance = axios.<span class="hljs-title function_">create</span>({<br> <span class="hljs-attr">baseURL</span>: <span class="hljs-string">'http://123.207.32.32:8000'</span>,<br> <span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span>,<br> <span class="hljs-attr">headers</span>: {<br> <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span><br> }<br>})<br><br><span class="hljs-title function_">axiosInstance</span>({<br> <span class="hljs-attr">url</span>:<span class="hljs-string">'/home/multidata'</span>,<br> <span class="hljs-attr">method</span>: <span class="hljs-string">'get'</span><br>}).<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res)<br>}).<span class="hljs-title function_">catch</span>(<span class="hljs-function"><span class="hljs-params">err</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(err)<br>})<br><br></code></pre></td></tr></table></figure> <h3 id="axios封装"><a href="#axios封装" class="headerlink" title="axios封装"></a>axios封装</h3><p>src->network->request.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">request</span>(<span class="hljs-params">config</span>) {<br> <span class="hljs-comment">// 1.创建axios的实例</span><br> <span class="hljs-keyword">const</span> instance = axios.<span class="hljs-title function_">create</span>({<br> <span class="hljs-attr">baseURL</span>: <span class="hljs-string">'http://123.207.32.32:8000'</span>,<br> <span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span>,<br> })<br><br> <span class="hljs-comment">// 2.axios的拦截器</span><br> <span class="hljs-comment">// 2.1请求拦截的作用</span><br> <span class="hljs-comment">// 发送真正的网络请求</span><br> instance.<span class="hljs-property">interceptors</span>.<span class="hljs-property">request</span>.<span class="hljs-title function_">use</span>(<span class="hljs-function"><span class="hljs-params">config</span> =></span> {<br> <span class="hljs-comment">// console.log(config);</span><br> <span class="hljs-comment">// 1.比如config中的一些信息不符合服务器的要求</span><br><br> <span class="hljs-comment">// 2.比如每次发送网络请求时, 都希望在界面中显示一个请求的图标</span><br><br> <span class="hljs-comment">// 3.某些网络请求(比如登录(token)), 必须携带一些特殊的信息</span><br> <span class="hljs-keyword">return</span> config<br> }, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(err)<br> })<br> <span class="hljs-comment">// 2.2响应拦截</span><br> instance.<span class="hljs-property">interceptors</span>.<span class="hljs-property">response</span>.<span class="hljs-title function_">use</span>(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {<br> <span class="hljs-keyword">return</span> res.<span class="hljs-property">data</span><br> }, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(err)<br> })<br> <span class="hljs-comment">// 3.发送真正的网络请求</span><br> <span class="hljs-keyword">return</span> <span class="hljs-title function_">instance</span>(config)<br>}<br></code></pre></td></tr></table></figure> <p>main.js</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> {request} <span class="hljs-keyword">from</span> <span class="hljs-string">'./network/request'</span><br><br><span class="hljs-title function_">request</span>({<br> <span class="hljs-attr">url</span>: <span class="hljs-string">'/home/multidata'</span><br>})<br>.<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res)<br>})<br>.<span class="hljs-title function_">catch</span>(<span class="hljs-function"><span class="hljs-params">err</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(err)<br>})<br></code></pre></td></tr></table></figure> <h3 id="拦截器"><a href="#拦截器" class="headerlink" title="拦截器"></a>拦截器</h3><p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220705134025390.png" srcset="/img/loading.gif" lazyload alt="image-20220705134025390"></p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220705134102544.png" srcset="/img/loading.gif" lazyload alt="image-20220705134102544"></p> <h3 id="配置代理一"><a href="#配置代理一" class="headerlink" title="配置代理一"></a>配置代理一</h3><p>直接请求会存在跨域问题</p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220824132658011.png" srcset="/img/loading.gif" lazyload alt="image-20220824132658011"></p> <p>vue.config.js文件配置代理服务器(配置完要重启)</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = {<br> <span class="hljs-attr">devServer</span>: {<br> <span class="hljs-attr">proxy</span>: <span class="hljs-string">'http://localhost:5000'</span> <span class="hljs-comment">//填写你需要代理的服务器的端口号</span><br> }<br>}<br></code></pre></td></tr></table></figure> <p>代理的服务还是8080,只不过发送请求时先往8080发,8080服务器向5000发,服务器向服务器发送请求就不会有跨域问题。</p> <p>再次请求,往8080发送就可以了</p> <p><img src="https://trpora-1300527744.cos.ap-chongqing.myqcloud.com/img/image-20220824133253730.png" srcset="/img/loading.gif" lazyload alt="image-20220824133253730"></p> <blockquote> <p>问题:</p> <p>1.只能配置一个代理</p> <p>2.(不能灵活配置走不走代理)会优先去本地资源找,如果本地public里面有,则不会去往5000服务器发送</p> </blockquote> <h3 id="配置代理二"><a href="#配置代理二" class="headerlink" title="配置代理二"></a>配置代理二</h3><p>vue.config.js文件配置代理服务器(配置完要重启)</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = {<br> <span class="hljs-comment">/**开启代理服务器方式一</span><br><span class="hljs-comment"> devServer: {</span><br><span class="hljs-comment"> proxy: 'http://localhost:5000'</span><br><span class="hljs-comment"> }</span><br><span class="hljs-comment"> */</span><br><br> <span class="hljs-comment">//开启代理服务器方式二</span><br> <span class="hljs-attr">devServer</span>: {<br> <span class="hljs-attr">proxy</span>: {<br> <span class="hljs-string">'/api'</span>: { <span class="hljs-comment">// 匹配所有以/api开头的请求,都会向服务器转发。这样就避免了优先匹配前端资源</span><br> <span class="hljs-attr">target</span>: <span class="hljs-string">'http://localhost:5000'</span>, <span class="hljs-comment">// 要代理的服务器地址</span><br> <span class="hljs-attr">pathRewrite</span>: {<span class="hljs-string">"^/api"</span>:<span class="hljs-string">""</span>}, <span class="hljs-comment">// 将/api替换为空,否则向服务器发送的是/api/test,其实我们想请求的是/test</span><br> <span class="hljs-attr">ws</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// 支持webscoket</span><br> <span class="hljs-attr">changeOrigin</span>: <span class="hljs-literal">true</span> <span class="hljs-comment">// 如果为true,服务器那边收到的发送请求端口号为 5000(相当于欺骗)</span><br> <span class="hljs-comment">// 如果为false,则服务器收到的请求端口号还是8080. 默认配置为true,所以注释掉也可以</span><br> <span class="hljs-comment">// 即使为false,也可以发送请求,因为是8080服务器向5000服务器发,服务器之间没有跨域。</span><br> <span class="hljs-comment">// 如果5000那边限制了请求的端口号啥的,就要设为true</span><br> },<br> <span class="hljs-string">'/demo'</span>: { <span class="hljs-comment">// 配置第二个代理,请求以/demo为前缀都会走这里</span><br> <span class="hljs-attr">target</span>: <span class="hljs-string">'http://localhost:5001'</span>,<br> <span class="hljs-attr">pathRewrite</span>: {<span class="hljs-string">"^/demo"</span>:<span class="hljs-string">""</span>}<br> }<br><br> }<br> }<br>}<br></code></pre></td></tr></table></figure> <p>发送请求时,加上前缀就会去对应的代理服务器里请求</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"send"</span>></span>点击发送请求<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"send2"</span>></span>向服务器2发送请求<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;</span><br><span class="language-javascript"> <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {</span><br><span class="language-javascript"> <span class="hljs-title function_">send</span>(<span class="hljs-params"></span>) { <span class="hljs-comment">//加上前缀/api,就会向5000转发</span></span><br><span class="language-javascript"> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'http://localhost:8080/api/students'</span>).<span class="hljs-title function_">then</span>(</span><br><span class="language-javascript"> <span class="hljs-function"><span class="hljs-params">response</span> =></span> {</span><br><span class="language-javascript"> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'请求成功'</span>,response.<span class="hljs-property">data</span>)</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-function"><span class="hljs-params">error</span> =></span> {</span><br><span class="language-javascript"> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'请求失败'</span>,error.<span class="hljs-property">message</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> )</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-title function_">send2</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'http://localhost:8080/demo/cars'</span>).<span class="hljs-title function_">then</span>(</span><br><span class="language-javascript"> <span class="hljs-function"><span class="hljs-params">response</span> =></span> {</span><br><span class="language-javascript"> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'请求成功'</span>,response.<span class="hljs-property">data</span>)</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-function"><span class="hljs-params">error</span> =></span> {</span><br><span class="language-javascript"> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'请求失败'</span>,error.<span class="hljs-property">message</span>)</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> )</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> }</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><span class="hljs-tag"><<span class="hljs-name">style</span>></span><br><br><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <h2 id="Vue-Resource(已弃用)"><a href="#Vue-Resource(已弃用)" class="headerlink" title="Vue-Resource(已弃用)"></a>Vue-Resource(已弃用)</h2><ol> <li>下载</li> </ol> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm install vue-resource<br></code></pre></td></tr></table></figure> <ol start="2"> <li><p>引入和使用插件</p> <p>main.js</p> </li> </ol> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> vueResource <span class="hljs-keyword">from</span> <span class="hljs-string">'vue-resource'</span><br><span class="hljs-comment">// 使用插件</span><br><span class="hljs-title class_">Vue</span>.<span class="hljs-title function_">use</span>(vueResource) <span class="hljs-comment">//会挂载在$http上</span><br></code></pre></td></tr></table></figure> <ol start="3"> <li>发送请求</li> </ol> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-built_in">this</span>.$http.get(<span class="hljs-string">'http://localhost:8080/api/students'</span>).then(<br> response => {<br> console.log(<span class="hljs-string">'请求成功'</span>,response.data)<br> },<br> error => {<br> console.log(<span class="hljs-string">'请求失败'</span>,error.message)<br> }<br> )<br></code></pre></td></tr></table></figure> <h2 id="Vue动画与过渡"><a href="#Vue动画与过渡" class="headerlink" title="Vue动画与过渡"></a>Vue动画与过渡</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">hr</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"isShow = !isShow"</span>></span>点击显示与隐藏<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-comment"><!--appear第一次出现就使用动画 ,加了name要用.hhhh-enter-active--></span><br> <span class="hljs-tag"><<span class="hljs-name">transition</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"hhhh"</span> <span class="hljs-attr">:appear</span>=<span class="hljs-string">"true"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"isShow"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>你好啊<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">transition</span>></span><br><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyAnimate'</span>,</span><br><span class="language-javascript"> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">isShow</span>: <span class="hljs-literal">true</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {},</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.box</span> {</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: skyblue;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-comment">/*</span></span><br><span class="hljs-comment"><span class="language-css">如果 translate没加name属性就用v,如果加了name就不能用v</span></span><br><span class="hljs-comment"><span class="language-css">.v-enter-active {</span></span><br><span class="hljs-comment"><span class="language-css"> animation: danimate 0.5s linear;</span></span><br><span class="hljs-comment"><span class="language-css">}</span></span><br><span class="hljs-comment"><span class="language-css">.v-leave-active {</span></span><br><span class="hljs-comment"><span class="language-css"> animation: danimate 0.5s linear reverse;</span></span><br><span class="hljs-comment"><span class="language-css">}</span></span><br><span class="hljs-comment"><span class="language-css">*/</span></span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.hhhh-enter-active</span> {</span><br><span class="language-css"> <span class="hljs-attribute">animation</span>: danimate <span class="hljs-number">0.5s</span> linear;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-selector-class">.hhhh-leave-active</span> {</span><br><span class="language-css"> <span class="hljs-attribute">animation</span>: danimate <span class="hljs-number">0.5s</span> linear reverse;</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-keyword">@keyframes</span> danimate {</span><br><span class="language-css"> <span class="hljs-selector-tag">from</span> {</span><br><span class="language-css"> <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(-<span class="hljs-number">100%</span>);</span><br><span class="language-css"> }</span><br><span class="language-css"> <span class="hljs-selector-tag">to</span> {</span><br><span class="language-css"> <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">0</span>);</span><br><span class="language-css"> }</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>方式二:</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">hr</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"isShow = !isShow"</span>></span>点击显示与隐藏<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-comment"><!--appear第一次出现就使用动画 ,加了name要用.hhhh-enter-active--></span><br> <span class="hljs-tag"><<span class="hljs-name">transition</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"hhhh"</span> <span class="hljs-attr">:appear</span>=<span class="hljs-string">"true"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"isShow"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>你好啊<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">transition</span>></span><br><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'MyAnimate2'</span>,</span><br><span class="language-javascript"> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">isShow</span>: <span class="hljs-literal">true</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript"> <span class="hljs-attr">methods</span>: {},</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.box</span> {</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: skyblue;</span><br><span class="language-css"> <span class="hljs-comment">/*transition: 0.5s liner;也可以加载这里*/</span></span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-comment">/**进入的起点,和离开的终点*/</span></span><br><span class="language-css"><span class="hljs-selector-class">.hhhh-enter</span>,<span class="hljs-selector-class">.hhhh-leave-to</span> {</span><br><span class="language-css"> <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(-<span class="hljs-number">100%</span>);</span><br><span class="language-css">}</span><br><span class="language-css"><span class="hljs-selector-class">.hhhh-enter-active</span>,<span class="hljs-selector-class">.hhhh-leave-active</span> {</span><br><span class="language-css"> <span class="hljs-attribute">transition</span>: <span class="hljs-number">0.5s</span> linear;</span><br><span class="language-css">}</span><br><span class="language-css"></span><br><span class="language-css"><span class="hljs-comment">/**进入的终点,离开的起点*/</span></span><br><span class="language-css"><span class="hljs-selector-class">.hhhh-enter-to</span>,<span class="hljs-selector-class">.hhhh-leave</span> {</span><br><span class="language-css"> <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">0</span>);</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> <p>如果想要加一组,要用transition-group,并且必须加key</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">transition-group</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"hhhh"</span> <span class="hljs-attr">:appear</span>=<span class="hljs-string">"true"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"isShow"</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"1"</span>></span>你好啊<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"!isShow"</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"2"</span>></span>哈哈哈<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br><span class="hljs-tag"></<span class="hljs-name">transition-group</span>></span><br></code></pre></td></tr></table></figure> <h3 id="引入animate-css"><a href="#引入animate-css" class="headerlink" title="引入animate.css"></a>引入animate.css</h3><p>1.安装</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm install animate.css --save<br></code></pre></td></tr></table></figure> <p>2.引入,在需要的组件script标签内引入</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'animate.css'</span>;<br></code></pre></td></tr></table></figure> <p>3.使用</p> <blockquote> <p> name="animate__animated animate__bounce" 必须加</p> <p> enter-active-class="" //进入时的动画名称<br> leave-active-class="" //离开时的动画名称</p> </blockquote> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">transition</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:appear</span>=<span class="hljs-string">"true"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">name</span>=<span class="hljs-string">"animate__animated animate__bounce"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">enter-active-class</span>=<span class="hljs-string">"animate__shakeY"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">leave-active-class</span>=<span class="hljs-string">"animate__backOutUp"</span></span><br><span class="hljs-tag">></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"isShow"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>你好啊<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">transition</span>></span><br></code></pre></td></tr></table></figure> <p>完整代码:</p> <figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">hr</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"isShow = !isShow"</span>></span>点击显示与隐藏<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br> <span class="hljs-comment"><!--appear第一次出现就使用动画 ,加了name要用.hhhh-enter-active--></span><br> <span class="hljs-tag"><<span class="hljs-name">transition</span></span><br><span class="hljs-tag"> <span class="hljs-attr">:appear</span>=<span class="hljs-string">"true"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">name</span>=<span class="hljs-string">"animate__animated animate__bounce"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">enter-active-class</span>=<span class="hljs-string">"animate__shakeY"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">leave-active-class</span>=<span class="hljs-string">"animate__backOutUp"</span></span><br><span class="hljs-tag"> ></span><br> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">v-show</span>=<span class="hljs-string">"isShow"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>你好啊<span class="hljs-tag"></<span class="hljs-name">h2</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">transition</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">template</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'animate.css'</span>;</span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">name</span>: <span class="hljs-string">'AnimateCss'</span>,</span><br><span class="language-javascript"> <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) {</span><br><span class="language-javascript"> <span class="hljs-keyword">return</span> {</span><br><span class="language-javascript"> <span class="hljs-attr">isShow</span>: <span class="hljs-literal">true</span></span><br><span class="language-javascript"> }</span><br><span class="language-javascript"> },</span><br><span class="language-javascript">}</span><br><span class="language-javascript"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><br><span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>></span><span class="language-css"></span><br><span class="language-css"><span class="hljs-selector-class">.box</span> {</span><br><span class="language-css"> <span class="hljs-attribute">background-color</span>: skyblue;</span><br><span class="language-css">}</span><br><span class="language-css"></span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br><br></code></pre></td></tr></table></figure> </div> <hr/> <div> <div class="post-metas my-3"> <div class="post-meta"> <i class="iconfont icon-tags"></i> <a href="/tags/Vue/">#Vue</a> <a href="/tags/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/">#前端框架</a> </div> </div> <div class="license-box my-3"> <div class="license-title"> <div>Vue</div> <div>http://example.com/2022/07/02/Vue.js/</div> </div> <div class="license-meta"> <div class="license-meta-item"> <div>作者</div> <div>Deng ErPu</div> </div> <div class="license-meta-item license-meta-date"> <div>发布于</div> <div>2022年7月2日</div> </div> <div class="license-meta-item"> <div>许可协议</div> <div> <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/"> <span class="hint--top hint--rounded" aria-label="BY - 署名"> <i class="iconfont icon-by"></i> </span> </a> </div> </div> </div> <div class="license-icon iconfont"></div> </div> <div class="post-prevnext my-3"> <article class="post-prev col-6"> <a href="/2022/07/03/JavaScript/" title="JavaScript和ES6"> <i class="iconfont icon-arrowleft"></i> <span class="hidden-mobile">JavaScript和ES6</span> <span class="visible-mobile">上一篇</span> </a> </article> <article class="post-next col-6"> <a href="/2022/06/28/Ajax/" title="Ajax"> <span class="hidden-mobile">Ajax</span> <span class="visible-mobile">下一篇</span> <i class="iconfont icon-arrowright"></i> </a> </article> </div> </div> </article> </div> </div> </div> <div class="side-col d-none d-lg-block col-lg-2"> <aside class="sidebar" style="margin-left: -1rem"> <div id="toc"> <p class="toc-header"><i class="iconfont icon-list"></i> 目录</p> <div class="toc-body" id="toc-body"></div> </div> </aside> </div> </div> </div> <a id="scroll-top-button" aria-label="TOP" href="#" role="button"> <i class="iconfont icon-arrowup" aria-hidden="true"></i> </a> <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel" aria-hidden="true"> <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document"> <div class="modal-content"> <div class="modal-header text-center"> <h4 class="modal-title w-100 font-weight-bold">搜索</h4> <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body mx-3"> <div class="md-form mb-5"> <input type="text" id="local-search-input" class="form-control validate"> <label data-error="x" data-success="v" for="local-search-input">关键词</label> </div> <div class="list-group" id="local-search-result"></div> </div> </div> </div> </div> </main> <footer> <div class="footer-inner"> <div class="footer-content"> <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> </div> </div> </footer> <!-- Scripts --> <script src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script> <link rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" /> <script> NProgress.configure({"showSpinner":false,"trickleSpeed":100}) NProgress.start() window.addEventListener('load', function() { NProgress.done(); }) </script> <script src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script> <script src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script> <script src="/js/events.js" ></script> <script src="/js/plugins.js" ></script> <script src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script> <script> (function (window, document) { var typing = Fluid.plugins.typing; var subtitle = document.getElementById('subtitle'); if (!subtitle || !typing) { return; } var text = subtitle.getAttribute('data-typed-text'); typing(text); })(window, document); </script> <script src="/js/img-lazyload.js" ></script> <script> Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() { var toc = jQuery('#toc'); if (toc.length === 0 || !window.tocbot) { return; } var boardCtn = jQuery('#board-ctn'); var boardTop = boardCtn.offset().top; window.tocbot.init({ tocSelector : '#toc-body', contentSelector : '.markdown-body', headingSelector : CONFIG.toc.headingSelector || 'h1,h2,h3,h4,h5,h6', linkClass : 'tocbot-link', activeLinkClass : 'tocbot-active-link', listClass : 'tocbot-list', isCollapsedClass: 'tocbot-is-collapsed', collapsibleClass: 'tocbot-is-collapsible', collapseDepth : CONFIG.toc.collapseDepth || 0, scrollSmooth : true, headingsOffset : -boardTop }); if (toc.find('.toc-list-item').length > 0) { toc.css('visibility', 'visible'); } }); </script> <script src=https://lib.baomitu.com/clipboard.js/2.0.10/clipboard.min.js></script> <script>Fluid.plugins.codeWidget();</script> <script> Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() { window.anchors.options = { placement: CONFIG.anchorjs.placement, visible : CONFIG.anchorjs.visible }; if (CONFIG.anchorjs.icon) { window.anchors.options.icon = CONFIG.anchorjs.icon; } var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(','); var res = []; for (var item of el) { res.push('.markdown-body > ' + item.trim()); } if (CONFIG.anchorjs.placement === 'left') { window.anchors.options.class = 'anchorjs-link-left'; } window.anchors.add(res.join(', ')); }); </script> <script> Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() { Fluid.plugins.fancyBox(); }); </script> <script>Fluid.plugins.imageCaption();</script> <script src="/js/local-search.js" ></script> <!-- 主题的启动项,将它保持在最底部 --> <!-- the boot of the theme, keep it at the bottom --> <script src="/js/boot.js" ></script> <noscript> <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div> </noscript> </body> </html>