3.1 KiB
3.1 KiB
title | date | tags | categories | |||
---|---|---|---|---|---|---|
Vue 侦听对象中的属性 | 2021-05-08 17:52:33 |
|
|
Vue 提供了一个 watch 方法可以让使用者去监听某些 data 内的数据变动,触发相应的方法,比如:
export default {
data() {
return {
question: '',
answer: 'Questions usually contain a question mark. ;-)'
}
},
watch: {
// whenever question changes, this function will run
question(newQuestion, oldQuestion) {
if (newQuestion.indexOf('?') > -1) {
this.getAnswer()
}
}
},
methods: {
getAnswer() {
this.answer = 'Thinking...'
axios
.get('https://yesno.wtf/api')
.then(response => {
this.answer = response.data.answer
})
.catch(error => {
this.answer = 'Error! Could not reach the API. ' + error
})
}
}
}
但是,当我们要侦听的数据是某个对象中的属性怎么办?
以前几天我所遇到的需求为例,一个对话框中的表单绑定了 queryData
,其中 date
绑定了一个日期选择器,count
则绑定了一个计数器,max
则是该计数器的值,需要根据 date
的值发送请求动态获取:
export default {
data() {
return {
max: 0,
queryData: {
date: '2021-05-08',
count: 0,
// 其它属性...
}
}
},
// ...
methods: {
getMax(date) {
// 发送请求后根据响应的值修改 this.max 的值
}
}
}
这时,我们如果只侦听 queryData
,queryData.date
更改时并不会触发侦听器,因为我们并没有给 queryData
重新赋值。
很多人都表示可以设置侦听器的 deep
选项为 true
,说实话,如果只是侦听 date
属性的话,我并不推荐这种方法,因为这样不仅 date
属性更改时会执行侦听器中的方法,其它属性(比如 count
)的值改变了,也会执行侦听器中的方法,还需要在其中加入判断,就很不理想。我推荐的方式是,将计算属性和监听器结合起来使用,如下:
export default {
data() {
return {
max: 0,
queryData: {
date: '2021-05-08',
count: 0,
// 其它属性...
}
}
},
computed: {
_queryData_date() {
return this.queryData.date
}
},
watch: {
_queryData_date(oldDate, newDate) {
this.getMax(newDate)
}
},
methods: {
getMax(date) {
// 发送请求后根据响应的值修改 this.max 的值
}
}
}
这样,我们就只侦听了 queryData.date
的值,可以在它改变时执行 getMax
方法。
关于计算属性和侦听器的使用方法,请查看 Vue 的官方文档:
- Vue 2.x
https://cn.vuejs.org/v2/guide/computed.html
https://cn.vuejs.org/v2/guide/reactivity.html- Vue 3.x
https://v3.cn.vuejs.org/guide/computed.html
https://v3.cn.vuejs.org/guide/reactivity-computed-watchers.html其实使用组合式 API的话,2.x 和 3.x 在这里并没有什么区别;Vue 3.x 中在 setup 里面使用的话,思路也是一样,只是形式不同。