### Vue.js 中 Watch 的使用指南与示例代码
在 Vue.js 中,`watch` 提供了一种机制来监听特定数据的变化,并在这些数据发生变化时执行相应的逻辑。这种特性非常适合用来处理依赖于其他数据的状态更新场景。
---
#### 1. **基础用法**
`watch` 主要用于观察 `data` 或者 `computed` 属性的变化。每当被监听的属性值发生改变时,就会触发对应的回调函数。
##### 示例代码
```javascript
new Vue({
el: '#app',
data: {
message: 'Hello!'
},
watch: {
message(newVal, oldVal) {
console.log(`message 已经从 "${oldVal}" 改变为 "${newVal}"`);
}
}
});
```
- **解释**: 上述代码中,当 `message` 发生变化时,控制台会打印出新旧值的信息[^4]。
---
#### 2. **深度监听(Deep Watching)**
默认情况下,`watch` 不会深入监测对象内部属性的变化。如果需要监听嵌套对象内的属性变化,则需设置 `deep: true`。
##### 示例代码
```javascript
new Vue({
el: '#app',
data: {
user: {
name: 'Alice',
age: 25
}
},
watch: {
user: {
handler(newVal, oldVal) {
console.log('用户信息已更新:', newVal);
},
deep: true // 深度监听
}
}
});
```
- **解释**: 此处配置了对 `user` 对象的深度监听,因此无论 `name` 还是 `age` 发生变化,都会触发回调函数。
---
#### 3. **立即执行回调(Immediate Execution)**
有时候我们希望在组件初始化阶段就运行一次监听器中的逻辑,而不仅仅是在首次变化之后才触发。这时可以借助 `immediate: true` 来实现这一需求。
##### 示例代码
```javascript
new Vue({
el: '#app',
data: {
counter: 0
},
watch: {
counter: {
handler(newValue) {
console.log(`当前计数为:${newValue}`);
},
immediate: true // 初始化时立即执行一次
}
}
});
```
- **解释**: 即使 `counter` 初始值未变,在组件挂载完成后仍会立刻调用一次回调函数[^4]。
---
#### 4. **监听多个属性或计算属性**
除了直接监听单一的数据字段外,还可以通过监听计算属性的方式间接达到同时监控多个变量的目的。
##### 示例代码
```javascript
new Vue({
el: '#app',
data: {
width: 800,
height: 600
},
computed: {
aspectRatio() {
return `${this.width}:${this.height}`;
}
},
watch: {
aspectRatio(newAspectRatio) {
console.log(`宽高比例已经更改为 ${newAspectRatio}`);
}
}
});
```
- **解释**: 计算属性 `aspectRatio` 结合了 `width` 和 `height` 的值,任何一项改动都将重新计算并触发关联的监听器[^4]。
---
#### 5. **实际应用案例 —— 动态分页查询**
假设有这样一个场景:根据用户的筛选条件动态请求后台接口获取列表数据。
##### 示例代码
```javascript
new Vue({
el: '#app',
data: {
currentPage: 1,
pageSize: 10,
searchKeyword: ''
},
methods: {
fetchData(page, size, keyword) {
console.log(`正在加载第 ${page} 页,每页大小为 ${size},关键词为 "${keyword}"`);
}
},
watch: {
currentPage(val) {
this.fetchData(val, this.pageSize, this.searchKeyword);
},
pageSize(val) {
this.currentPage = 1; // 页面切换回首页
this.fetchData(this.currentPage, val, this.searchKeyword);
},
searchKeyword(val) {
this.currentPage = 1;
this.fetchData(this.currentPage, this.pageSize, val);
}
}
});
```
- **解释**: 当任一筛选条件 (`currentPage`, `pageSize`, `searchKeyword`) 变化时,均会触发对应的方法去刷新数据源。
---
###