116 lines
3.1 KiB
Markdown
116 lines
3.1 KiB
Markdown
---
|
||
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 里面使用的话,思路也是一样,只是形式不同。***
|