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