VUE-概述
# VUE-概述
# 1、生命周期
简单理解,生命周期钩子函数就是vue实例在某一个时间点会自动执行的函数
<div id="app">{{msg}}</div>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'Vue的生命周期'
},
beforeCreate: function() {
console.group('------beforeCreate创建前状态------');
console.log("el : " + this.$el); //undefined
console.log("data : " + this.$data); //undefined
console.log("msg: " + this.msg) //undefined
},
created: function() {
console.group('------created创建完毕状态------');
console.log("el : " + this.$el); //undefined
console.log("data : " + this.$data); //已被初始化
console.log("msg: " + this.msg); //已被初始化
},
beforeMount: function() {
console.group('------beforeMount挂载前状态------');
console.log(this.$el);// <div id="app">{{msg}}</div> 挂载前状态
},
mounted: function() {
console.group('------mounted 挂载结束状态------');
console.log(this.$el);// <div id="app">Vue的生命周期</div> msg内容被挂载并渲染到页面
},
// 当data被修改之前
beforeUpdate: function () {
console.group('beforeUpdate 更新前状态===============》');
console.log("el : " + this.$el);
console.log(this.$el);
console.log("data : " + this.$data);
console.log("msg: " + this.msg);
},
// 触发beforeUpdate之后,虚拟DOM重新渲染并应用更新
// 当data被修改之后
updated: function () {
console.group('updated 更新完成状态===============》');
console.log("el : " + this.$el);
console.log(this.$el);
console.log("data : " + this.$data);
console.log("msg: " + this.msg);
},
// 调用vm.$destroy() 销毁前
beforeDestroy: function () {
console.group('beforeDestroy 销毁前状态===============》');
console.log("el : " + this.$el);
console.log(this.$el);
console.log("data : " + this.$data);
console.log("msg: " + this.msg);
},
// 调用vm.$destroy() 销毁后
destroyed: function () {
console.group('destroyed 销毁完成状态===============》');
console.log("el : " + this.$el);
console.log(this.$el);
console.log("data : " + this.$data);
console.log("msg: " + this.msg)
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
# 2、组件间传递数据
# 2.1、父组件给子组件传值
父组件中,通过给子组件标签v-bind绑定属性的方式传入值
<ComponentName v-bind:name="value"></ComponentName>
1
子组件中,通过props对象接收值组件中,通过props对象接收值
props: {
name: { // 接收父组件传入值
type: String || ...,
default: ''
}
}
1
2
3
4
5
6
2
3
4
5
6
子组件不能直接修改父组件传入的值
这里有两种常见的试图改变一个 prop 的情形:
- 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
1
2
3
4
5
6
2
3
4
5
6
- 这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
1
2
3
4
5
6
2
3
4
5
6
# 2.2、子组件给父组件传值
子组件通过$emit
派发事件和值给父组件(值可以有多个)
this.$emit('fnX', value)
1
父组件通过v-on
绑定子组件派发的事件,并触发一个新的事件,新的事件内可以接收传来的值
<ComponentName @fnX="fnY"></ComponentName>
methods: {
fnY(value) {
console.log(value)
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
demo:
<div id="root">
<counter :count="0" @change="handleChange"></counter> +
<counter :count="1" @change="handleChange"></counter> = <span>{{total}}</span>
</div>
--------JS----------------
var counter = {
props: ['count'], // 接收父组件传来的值
data() {
return {
number: this.count // 拷贝prop值的副本,用于修改
}
},
template: '<button @click="handleClick()">{{number}}</button>',
methods: {
handleClick() {
this.number++ // 由于单向数据流,不能直接修改prop的值
this.$emit('change', 1) // 派发事件并传出值,值可以有多个
}
}
}
var vm = new Vue({
el: '#root',
data: {
total: 1
},
components: {
counter
},
methods: {
handleChange(step) {
// step 子组件传来的值
this.total += + step
}
}
})
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
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
# 2.3、兄弟组件传值
子组件1中把值传到父组件,父组件获取值传入子组件2
父组件:
<子组件1 @方法名x="方法名y"></子组件1>
<子组件2 :值名称x="值x"></子组件2 >
data() {
return {
值x: ''
}
},
methods: {
方法名y(值) {
this.值x = 值
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
子组件1:
this.$emit('方法名x', 值) // 传出值
1
子组件2:
props: {
值名称x: { // 接收父组件传入值
type: String,
default: ''
}
}
1
2
3
4
5
6
2
3
4
5
6
# 2.4、非父子组件间传值
当组件的嵌套多时,非父子组件间传值就显得复杂,除了使用vuex (opens new window)实现之外,还可以通过Bus(或者叫 总线/发布订阅模式/观察者模式)的方式实现非父子组件间传值。
<div id="root">
<child1 content="组件1:点我传出值"></child1>
<child2 content="组件2"></child2>
</div>
<script type="text/javascript">
Vue.prototype.bus = new Vue()
// 每个Vue原型上都会有bus属性,而且指向同一个Vue实例
Vue.component('child1', {
props: {
content: String
},
template: '<button @click="handleClick">{{content}}</button>',
methods: {
handleClick(){
this.bus.$emit('change', '我是组件1过来的~') // 触发change事件,传出值
}
}
})
Vue.component('child2', {
data() {
return {
childVal: ''
}
},
props: {
content: String,
},
template: '<button>{{content}} + {{childVal}}</button>',
mounted() {
this.bus.$on('change', (msg) => { // 绑定change事件,执行函数接收值
this.childVal = msg
})
}
})
var vm = new Vue({
el: '#root'
})
</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
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
# 2.5、父组件调用子组件方法并传入值
通过ref
引用调用子组件内的方法并传入参数
父组件:
<子组件标签 ref="refName"></子组件标签>
methods: {
fnX(x) {
this.$refs.refName.fnY(x) // 调用子组件方法并传入值
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
子组件:
methods: {
fnY(x) {
this.x = x
}
}
}
1
2
3
4
5
6
2
3
4
5
6
# 2.6、父子组件的生命周期顺序
加载渲染过程
父beforeCreate -> 父created-> 父beforeMount-> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
1
父组件会先执行到beforeMount,接着会执行子组件钩子到挂载结束,再挂载父组件。
子组件更新过程
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
1
父组件更新过程
父beforeUpdate -> 父updated
1
销毁过程
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
1
上次更新: 2024/01/12, 15:00:50