vue中watch的使用时机,如何在初始化后再使用?

本文探讨了在Vue.js项目中如何正确使用watch属性来监听数据变化,并通过一个实例介绍了如何避免因初始化数据而导致的误触发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在做项目的时候,遇到这么一个需求,就是当页面切换的时候,如果当前页面没有改动,就弹出一个提示窗。我当时的第一反应是,这里应该使用watch来进行观察,再用一个变量来标识是否用户进行了改动,代码如下:

export default
{
    data()
    {
        return {
            data_list: [],
            do_not_save: false,
        }
    },
    watch: 
    {
        data_list: {
            handler: function(after, before) {
                this.do_not_save = true
            },
            deep: true,
        }
    },
    created: function() {
        axios.get(url).then(function(response){
            vm.data_list = response.data
        }
    }       
}

后来发现do_not_save这个变量,始终都是true。想了半天(原谅我很菜),原来我在初始化的时候,对data_list进行赋值,此时watch就观察到了data_list的变化,把do_not_save这个变量转换成了true。所以说,watch这个特性,是针对当前组件中的初始值来进行判断的,我们在初始化的时候,这个data_list已经被修改了,此时watch已经被触发。解决方法如下:

created: function() {
    axios.get(url).then(function(response){
        vm.data_list = response.data
    }
    this.$watch('data_list', function(){this.do_not_save = true}, {deep: true})
}

我把观察的方法,放在了初始化data_list之后,这样watch的初始值就不再是原来的空数组了,而是我们赋值之后的data_list了。欢迎大家批评指正!

<think>我们正在讨论Vue2中的watch属性。根据引用[1][2][3],Vue2中的watch是一个配置项,用于监听数据的变化并执行相应的回调函数。 在Vue2中,我们可以在组件的选项对象中定义一个watch属性,该属性是一个对象,键是需要观察的表达式(通常是data中的属性或计算属性),值是对应的回调函数(或者是一个包含handler函数的对象,还可以包含其他配置如deep、immediate等)。 使用方式: 1. 简单监听:直接使用函数作为值,该函数接收两个参数:新值(newValue)和旧值(oldValue)。 2. 深度监听:当监听对象或数组内部变化时,需要设置deep:true。 3. 立即执行:设置immediate:true,会在初始渲染时立即执行一次回调。 示例代码(来自引用[2][3]): ``` <template> <input type="number" v-model.number="counter" /> </template> <script> export default { data() { return { counter: 0 }; }, watch: { // 简单监听 counter: function(newVal, oldVal) { console.log('counter change to %d from %d', newVal, oldVal); }, // 监听对象属性,可以使用点分隔的字符串 'b.c': function(newVal, oldVal) { // 处理变化 }, // 监听对象,并深度监听 e: { handler: function(newVal, oldVal) { // 注意:对于对象或数组,新旧值可能相同,因为它们是引用类型 }, deep: true }, // 立即执行 someProp: { handler: function(newVal, oldVal) { // 立即执行一次 }, immediate: true } } }; </script> ``` 注意事项: - 在Vue2中,watch可以监听data中的属性,也可以监听计算属性。 - 对于对象或数组,由于它们引用类型,新值和旧值可能相同。如果需要深度监听内部变化,必须使用deep:true。 - 使用字符串键名可以监听嵌套属性(如:'b.c')。 与Vue3的区别(引用[1][4]): - Vue3中watch作为函数使用,在setup()中使用,并且需要按需导入。 - Vue3中watch可以监听多个数据源,并且提供了watchEffect函数。 因此,在Vue2中正确使用watch属性,就是在组件的配置对象中定义watch属性,然后按照上述示例编写监听逻辑。 下面是一个整的Vue2 watch使用示例: ``` <template> <div> <p>计数器: {{ counter }}</p> <button @click="counter++">增加</button> <p>用户信息: {{ user.name }} - 年龄: {{ user.age }}</p> <button @click="user.age++">增加年龄</button> </div> </template> <script> export default { data() { return { counter: 0, user: { name: '张三', age: 20 } }; }, watch: { // 监听基本数据类型 counter(newVal, oldVal) { console.log(`计数器从${oldVal}变为${newVal}`); }, // 监听对象的某个属性 'user.age': function(newVal, oldVal) { console.log(`用户年龄从${oldVal}变为${newVal}`); }, // 深度监听整个user对象 user: { handler(newVal, oldVal) { // 注意:由于是对象,newVal和oldVal指向同一个对象 console.log('user对象发生了变化', newVal); }, deep: true } } }; </script> ``` 相关问题: 1. Vue2中watch和computed有什么区别? 2. Vue2中如何监听数组的变化? 3. Vue2中watch的deep选项有什么作用? 4. 在Vue2中,watch能否监听路由变化? 5. Vue3的watchVue2的watch有哪些不同?</think>在 Vue2 中,`watch` 属性是一个强大的响应式工具,用于监听数据变化并执行相应操作。以下是 Vue2 中正确使用 `watch` 的详细指南: ### 1. 基本用法 ```javascript export default { data() { return { counter: 0 } }, watch: { // 监听 counter 的变化 counter(newVal, oldVal) { console.log(`计数器从 ${oldVal} 变为 ${newVal}`) // 执行其他业务逻辑 } } } ``` - **参数**:回调函数接收两个参数:`newVal`(新值)和 `oldVal`(旧值)[^2] - **触发时机**:当 `counter` 的值发生变化时触发 ### 2. 监听对象属性 ```javascript watch: { // 使用点语法监听嵌套属性 'user.name': function(newName, oldName) { console.log(`用户名从 ${oldName} 变为 ${newName}`) } } ``` ### 3. 深度监听(对象/数组) ```javascript watch: { user: { handler(newVal, oldVal) { console.log('用户对象发生变化', newVal) }, deep: true, // 启用深度监听 immediate: true // 组件创建时立即执行 } } ``` - **deep: true**:监听对象内部值的变化[^3] - **immediate: true**:组件初始化时立即执行一次回调 ### 4. 监听多个数据源 ```javascript watch: { // 同时监听多个数据 'user.name': 'nameChangedHandler', 'user.age': { handler: 'ageChangedHandler', deep: true } }, methods: { nameChangedHandler(newVal) { console.log('姓名变化:', newVal) }, ageChangedHandler(newVal) { console.log('年龄变化:', newVal) } } ``` ### 5. 高级场景示例 ```javascript export default { data() { return { searchQuery: '', results: [], // 防抖计时器 debounceTimer: null } }, watch: { searchQuery(newVal) { // 实现搜索防抖(300ms) clearTimeout(this.debounceTimer) this.debounceTimer = setTimeout(() => { this.fetchResults(newVal) }, 300) } }, methods: { fetchResults(query) { // 实际API请求逻辑 axios.get(`/search?q=${query}`).then(res => { this.results = res.data }) } } } ``` ### 注意事项 1. **引用类型陷阱**:监听对象/数组时,`newVal` 和 `oldVal` 可能指向同一引用 2. **性能优化**: - 避免在 `watch` 中执行重操作 - 必要时使用 `_.debounce` 或 `_.throttle` 限制触发频率 3. **与 computed 的区别**: - `computed`:派生数据(有返回值) - `watch`:执行副作用(无返回值) ### 最佳实践 ```javascript watch: { // 清晰命名的处理函数 userId: 'fetchUserData', // 带选项的监听 pagination: { handler: 'loadData', deep: true, immediate: true } }, methods: { // 将处理逻辑分离到methods fetchUserData(newId) { axios.get(`/users/${newId}`).then(...) }, loadData() { // 加载分页数据 } } ``` > 提示:在 Vue3 中,`watch` 作为组合式 API 的函数使用,但 Vue2 的选项式 API 仍是有效且广泛使用的方案[^1][
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值