本文试验了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>
|
- 对于直接监听整个对象,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) } }
|
- 对于对象新增一个属性,computed 与 watch 都无法监听到对象的改变(原因vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的)
- 对于对象删除一个属性,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 } }
|