07-数组更新检测与Vue生命周期
码路教育 6/3/2022
# 1, 数组响应式注意事项
# 1.1, 数组更新检测
数组更新检测
- Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
- 上面的方法会直接修改原来的数组
- 某些方法不会替换原来的数组,而是会生成新的数组,比如 filter()、concat() 和 slice();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入Vue.js,人家向外暴露一个Vue类 new Vue -->
<script src="../lib/vue2.7.8.js"></script>
</head>
<body>
<!-- 定义的容器 -->
<div id="app">
<ul>
<li>{{name}}</li>
<li>{{age}}</li>
<li>{{sex}}</li>
<li>{{hobby}}</li>
</ul>
<button @click="updateHobby">修改睡觉为打代码</button>
</div>
<script>
let vm = new Vue({
el:"#app",
data(){
return {
name:"wc",
age:18,
sex:"man",
hobby:["睡觉","吃饭","打豆豆"]
}
},
methods:{
updateHobby(){
// 这样修改,数据已经变了,但是模板没有刷新
// 这个修改数据,并非是响应式的
// 如果数组中的数据是基本数据类型,通过索引去修改它,界面并不会更新
// this.hobby[0] = "打代码";
// 数据变了,界面也没有刷新
// 通过数组的length修改数据,并排是响应式的
// this.hobby.length = 2;
// 调用数组的push,pop方法,也是响应式的
// this.hobby.push("写代码")
// 下面的7个方法,会引起界面更新
// push()
// pop()
// shift()
// unshift()
// splice()
// sort()
// reverse()
// this.hobby.pop()
// this.hobby.splice(0,1,"打代码")
// map返回一个加工后的新数组
// console.log(this.hobby.map(item=>item=="睡觉" ? "打代码" : item));
this.hobby = this.hobby.map(item=>item=="睡觉" ? "打代码" : item);
}
}
});
</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
60
61
62
63
64
65
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入Vue.js,人家向外暴露一个Vue类 new Vue -->
<script src="../lib/vue2.7.8.js"></script>
</head>
<body>
<!-- 定义的容器 -->
<div id="app">
<p>a==>{{a}}</p>
<p>a.b==>{{a.b}}</p>
<p>a.b.c==>{{a.b.c}}</p>
<hr>
<p>{{arr}}</p>
<button @click="handle">修改data中的数据</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
// a是响应式数据 b也是响应式数据 c也是响应式数据
// 在data中,一个对象不管嵌套多深,所有数据都是响应式数据
a: {
b: {
c: 100
}
},
//
arr: ["xq", 123, { name: 'wangcai' }, true]
}
},
methods:{
handle(){
// 数据变了,但是界面没有更新,不是响应式的
// this.arr[0] = "666";
// 调用数据的7个方法,是响应式的
// 如果数组中的元素是一个对象的话,通过索引去修改对象中的属性,也会引起界面的更新
this.arr[2].name = "xiaoqiang";
}
}
});
// 总结数据更新检测:
// 在data中定义的数据都是响应式数据,有特殊情况:
// 数组中的元素有可能是响应式的【数组中的元素是对象】,也有可能不是响应式的【基本类型】
// 调用数组上的7个方法,也会引起界面更新
</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
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
# 2, Vue生命周期
# 2.1, Vue框架生命周期函数体验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入Vue.js,人家向外暴露一个Vue类 new Vue -->
<script src="../lib/vue2.7.8.js"></script>
</head>
<body>
<!--
-->
<!-- 定义的容器 -->
<div id="app">
<p :style="{opacity:tmd}">Vue是一个很NB的框架!!!</p>
</div>
<script>
let vm = new Vue({
el:"#app",
data(){
return {
tmd:1
}
},
// 生命周期函数,也叫钩子函数
// 这个函数会在合适的时机自动调用
// 函数的名字,不能随便,都是vue定死的
// 每一个钩子函数,都有特定的含义
mounted(){
setInterval(()=>{
this.tmd -= .1;
if(this.tmd<=0) this.tmd = 1;
},500)
}
});
</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
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
# 2.2, 生命周期函数完整版(八个)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入Vue.js,人家向外暴露一个Vue类 new Vue -->
<script src="../lib/vue2.7.8.js"></script>
</head>
<body>
<!-- 定义的容器 -->
<div id="app">
<button @click="add">加1</button>
<span ref="cur">{{count}}</span>
<button @click="minus">减1</button>
<br>
<button @click="handle">销毁vm</button>
</div>
<script>
let vm = new Vue({
el:"#app",
data(){
return {
count:1
}
},
methods:{
add(){
this.count++
},
minus(){
this.count--
},
handle(){
// 销毁vm
this.$destroy();
}
},
// 生成周期函数,最先执行执行的是beforeCreate,
// 说明:vm还没有初始化完成 不能通过vm使用data中的方法和methods中的方法
// 项目中没有什么用,了解就OK了
beforeCreate(){
// vm还没有初始化配置完毕,在这里不能获取vm的属性或方法
console.log("初始化阶段:beforeCreate","vm没有初始化完毕",this.count);
},
// vm实例已经初始化完成了
// 有用,在项目中,通常可以在这里发送ajax请求
created(){
// 此处,就可以获取vm的属性或方法了
console.log("初始化阶段:created","vm初始化完毕", this.count);
},
// vm挂载之前调用
// 项目中用的也不多
beforeMount(){
// 可以获取vm实例,可以得到vm实例上的属性或方法,但是不能获取真实DOM
console.log("挂载阶段:beforeMount","vm挂载之前执行一次",this.count,this.$refs.cur);
},
// vm已经挂载完毕了
mounted(){
// 挂载完毕,就可以获取DOM元素
// 在这里,也可以发生ajax请求 个人一般在mounted中发请求
console.log("挂载阶段:mounted","vm挂载完毕",this.$refs.cur);
},
// 更新阶段,当响应式数据发生了变化,就会触发一次
beforeUpdate(){
console.log("更新阶段:beforeUpdate",this.count);
},
// 更新阶段:当vm的响应式数据发生变化,更新界面会触发一次
updated(){
// 能不能在updated中更新状态?
// 答:不能,会导致死循环
console.log("更新阶段:updated",this.count);
},
// vm销毁之前调用
beforeDestroy(){
console.log("销毁阶段:beforeDestroy",this.count);
},
// vm销毁完毕:处理后事,如关闭之前开的一些定时器,或其它的收尾工作
destroyed(){
console.log("销毁阶段:destroyed",this.count);
}
});
// 总结:
// 初始化阶段:beforeCreate created 只会执行一次
// 挂载阶段:beforeMount mounted 只会执行一次
// 更新阶段:beforeUpdate updated 只响应式数据发生变化,都会调用,调用N次
// 销毁阶段:beforeDestroy destroyed
// 销毁后,并不是说界面看不见了,vm实例还可以访问,但是它不工作了!!!!
</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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93