banner
NEWS LETTER

试验computed与watch监听

Scroll down

本文试验了vue框架的计算属性与侦听器对于,number、String、Object、Array类型的监听效果

试验computed与watch监听

1. 监听一个number类型变量

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
<template>
<div class="main">
<div>{{number}}</div>
<div>computed: nowNumber = {{nowNumber}}</div>
<el-button @click="changeNumber">数值自增1</el-button>
</div>
</template>

<script>
export default {
data () {
return {
number: 0
}
},
computed: {
nowNumber () {
return this.number
}
},
watch: {
number (val) {
console.log(val)
}
},
methods: {
changeNumber () {
this.number++
}
}
}
</script>

computed 与 watch 都能监听到number类型变量的变化。变量改变,computed中的计算属性更新。watch监听到变量变化,控制台输出改变后的值

2. 监听一个String类型变量

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
template>
<div class="main">
<div>{{name}}</div>
<div>computed: newName = {{newName}}</div>
<el-input class="w_224" v-model="inputName" placeholder="请输入新名字"></el-input>
<el-button @click="changeName">改名</el-button>
</div>
</template>

<script>
export default {
data () {
return {
name: 'bob',
inputName: ''
}
},
computed: {
newName () {
return this.name
}
},
watch: {
name (val) {
console.log(val)
}
},
methods: {
changeName () {
this.name = this.inputName
}
}
}
</script>

computed 与 watch 都能监听到String类型变量的变化。变量改变,computed中的计算属性更新。watch监听到变量变化,控制台输出改变后的值

3. 监听一个Object类型变量

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
<template>
<div class="main">
<div>姓名:{{user.name}}, 年龄:{{user.age}}
<span v-if="user.heigh">身高{{user.heigh}}</span> </div>
<div>computed: userInfo = {{userInfo}}</div>
<el-input class="w_224" v-model="inputName" placeholder="请输入新名字"></el-input>
<el-button @click="changeName">改名</el-button>
<el-input class="w_224" v-model="heigh" placeholder="请输入身高"></el-input>
<el-button @click="insertHeigh">新增身高属性</el-button>
<el-input class="w_224" v-model="heigh" placeholder="请输入身高"></el-input>
<el-button @click="del">删除age属性</el-button>
</div>
</template>

<script>
export default {
data () {
return {
user: {
name: 'bob',
age: 20
},
inputName: '',
heigh: ''
}
},
computed: {
userInfo () {
return `${this.user.name}-${this.user.age}-${this.user.heigh}`
}
},
watch: {
user (val) {
console.log(val)
}
},
methods: {
changeName () {
this.user.name = this.inputName
},
insertHeigh () {
this.user.heigh = this.heigh
},
del () {
delete this.user.age
}
}
}
</script>
  1. 对于直接监听整个对象,computed能够监听到对象的其中的一个属性值的变化,而watch去监听整个对象,对象内的某个属性的值改变,并不能监听到。若需要watch能够监听到对象内的某个属性值的变化,需要做深度监听。
    watch深度监听:
1
2
3
4
5
6
7
8
watch: {
user :{
handler: (val) => {
console.log(val)
},
deep: true
}
}

用computed作为中间件转化,因为computed可以取到对应的属性值

1
2
3
4
5
6
7
8
9
10
computed: {
userName () {
return this.user.name
}
},
watch: {
userName (val) {
console.log('userName', val)
}
}
  1. 对于对象新增一个属性,computed 与 watch 都无法监听到对象的改变(原因vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的)
  2. 对于对象删除一个属性,computed 与 watch 都无法监听到对象的改变(原因同上,vue是响应式的)

4. 监听一个Array类型变量

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
<template>
<div class="main">
<div>{{list}}</div>
<div>{{newList}}</div>
<el-button @click="pushNewItem">插入新项</el-button>
<el-button @click="delItem">移除一项</el-button>
<el-button @click="spliceItem">替换某项</el-button>
<el-button @click="changeItem">某项值的改变</el-button>
</div>
</template>

<script>
export default {
data () {
return {
list: [],
count: 0
}
},
computed: {
newList () {
return this.list
}
},
watch: {
list (val) {
console.log(val)
}
},
methods: {
pushNewItem () {
this.list.push(this.count)
this.count++
},
delItem () {
this.list.splice(0, 1)
},
spliceItem () {
this.list.splice(0, 1, '替换项')
},
changeItem () {
this.list[0] = '改变值'
}
}
}
</script>

computed 与 watch 都能监听到Array类型变量的新增项、删除某项、某项提换发生的改变,但对于直接为数组内已存在的某项进行赋值,computed与watch并不能监听到(原因: this.list[0] = ‘改变值’ 并不是响应式的)

5. 监听一个复杂Array类型变量,Array[Object]

1. 对整个Object项的操作

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
<template>
<div class="main">
<div>{{list}}</div>
<div>{{newList}}</div>
<el-button @click="pushNewItem">插入新项</el-button>
<el-button @click="delItem">移除一项</el-button>
<el-button @click="spliceItem">替换某项</el-button>
<el-button @click="changeItem">某项值的改变</el-button>
</div>
</template>

<script>
export default {
data () {
return {
list: [{
name: 'bob',
age: 20
}],
}
},
computed: {
newList () {
return this.list
}
},
watch: {
list (val) {
console.log(val)
}
},
methods: {
pushNewItem () {
let user = {
name: 'newName',
age: 20
}
this.list.push(user)
},
delItem () {
this.list.splice(0, 1)
},
spliceItem () {
let user = {
name: 'spliceName',
age: 20
}
this.list.splice(0, 1, user)
},
changeItem () {
this.list[0] = {
name: 'changeName',
age: 33
}
}
}
}
</script>

对整个Object项的操作,与简单类型的数组无区别,computed 与 watch 都能监听到变量的新增项、删除某项、某项提换发生的改变,但对于直接为数组内已存在的某项进行赋值,computed与watch并不能监听到(原因: this.list[0] = ‘改变值’ 并不是响应式的)

2. 对某项内的Object对象的属性操作

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
<template>
<div class="main">
<div>{{list}}</div>
<div>{{newList}}</div>
<el-button @click="pushNewItem">新增一个属性</el-button>
<el-button @click="delItem">移除一个属性</el-button>
<el-button @click="changeItem">某项值的改变</el-button>
</div>
</template>

<script>
export default {
data () {
return {
list: [{
name: 'bob',
age: 20
}],
}
},
computed: {
newList () {
return this.list
}
},
watch: {
list (val) {
console.log(val)
}
},
methods: {
pushNewItem () {
this.list[0].heigh = 123
},
delItem () {
delete this.list[0].age
},
changeItem () {
this.list[0].name = 'changeName'
}
}
}
</script>

computed与watch去监听整个数组变量。单项对象新增属性与删除属性两者都监听不到。对于单项对象内的某个属性的值改变,能够被computed监听到,但watch并不能监听到。若需要watch能够监听到对象内的某个属性值的变化,需要做深度监听。
watch深度监听:

1
2
3
4
5
6
7
8
watch: {
list: {
handler: (val) => {
console.log(val)
},
deep: true
}
}
其他文章