blog/Vue-侦听对象中的属性.md

116 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: Vue 侦听对象中的属性
date: 2021-05-08 17:52:33
tags:
- 前端
- Vue
categories:
- 前端
---
Vue 提供了一个 watch 方法可以让使用者去监听某些 data 内的数据变动,触发相应的方法,比如:
```javascript
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` 的值发送请求动态获取:
```javascript
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`)的值改变了,也会执行侦听器中的方法,还需要在其中加入判断,就很不理想。我推荐的方式是,将**计算属性**和**监听器**结合起来使用,如下:
```javascript
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 里面使用的话,思路也是一样,只是形式不同。***