程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Vue2

    • Vue简介
    • Vue 基础使用
    • Vue的基础指令
    • 过滤器(Filters)
    • 侦听器(Watch)
      • 1. 什么是侦听器
      • 2. 定义侦听器的语法
        • 2.1 方法定义侦听器
        • 2.2 对象定义侦听器
        • 2.3 监测用户名是否可用
        • 1. 方法定义侦听器示例
        • 2. 对象定义侦听器示例
      • 3. immediate 选项
      • 4. deep 选项
      • 5. 监听对象单个属性的变化
      • 6. 监听路由变化
        • 1. 监听路由路径 ($route.path)
        • 2. 监听路由参数 ($route.params)
        • 3. 监听查询参数 ($route.query)
        • 4. 监听路由元信息 ($route.meta)
        • 5. 监听完整的路由对象 ($route)
        • 6. 监听路由嵌套路径 ($route.matched)
      • 7. 计算属性 vs 侦听器
    • 计算属性(computed)
    • vue-cli
    • vue.config.js配置
    • Vue组件
    • 生命周期和数据共享
    • Vue 组件实例与数据代理 (this)
    • $refs 引用
    • 动态组件
    • 插槽 (Slots)
    • 混入 (Mixin)
    • 自定义指令 (directives)
    • 插件 (Plugins)
    • 初识Vue-router
    • Vue-router的常见用法
  • Vue3

  • vue3 + TS 项目集成

  • Vue全家桶
  • Vue2
scholar
2024-07-30
目录

侦听器(Watch)

# 侦听器(Watch)

# 1. 什么是侦听器

侦听器(watchers)允许开发者监视 Vue 实例中数据的变化,并在数据变化时执行特定的操作。通过使用侦听器,开发者可以在数据变化时触发相应的回调函数,从而实现数据驱动的响应式编程。

提示

在 Vue 实例中,watch 选项是一个对象,其中的每个属性都是一个侦听器,用于监视 Vue 实例中对应数据的变化。watch 选项中的属性名必须与 data 中的属性名相对应,否则侦听器不会起作用。

# 2. 定义侦听器的语法

在 Vue 实例中,定义侦听器有两种方式:方法定义和对象定义。

# 2.1 方法定义侦听器

方法定义的侦听器是直接在 watch 选项中定义方法,用于监视对应的数据变化。方法中可以访问到数据变化前后的值。

语法格式




 



 
 
 
 



new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    username: '' // 定义一个 username 数据
  },
  watch: {
    // 方法定义的侦听器
    username(newVal, oldVal) {
      // newVal 是 username 的新值,oldVal 是 username 的旧值
      console.log('username changed from', oldVal, 'to', newVal);
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13

在定义的侦听器中,newVal 和 oldVal 是固定的写法,用于 Vue 侦听器(watchers)中表示数据变化前后的值。

  • newVal:变化后的新值,即数据变化后的当前值,始终是第一个参数。
  • oldVal:变化前的旧值,即数据变化前的之前值,始终是第二个参数。

# 2.2 对象定义侦听器

对象定义的侦听器可以更灵活地设置侦听器的选项,如 immediate 和 deep。handler 是侦听器的处理函数。

语法格式




 



 
 
 
 
 
 
 
 



new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    username: '' // 定义一个 username 数据
  },
  watch: {
    // 对象定义的侦听器
    username: {
      handler(newVal, oldVal) {
        // newVal 是 username 的新值,oldVal 是 username 的旧值
        console.log('username changed from', oldVal, 'to', newVal);
      },
      immediate: false, // 是否立即触发回调
      deep: false // 是否深度监听
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 2.3 监测用户名是否可用

以下是一个使用 watch 侦听器监测用户名变化,并使用 axios 发起 AJAX 请求,检测用户名是否可用的示例:

# 1. 方法定义侦听器示例




 



 
 
 
 
 
 
 
 
 
 



new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    username: '' // 定义一个 username 数据
  },
  watch: {
    // 监听 username 值的变化
    async username(newVal) {
      if (newVal === '') return; // 如果新值为空字符串,则不做任何处理
      try {
        // 使用 axios 发起请求,判断用户名是否可用
        const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal);
        console.log(res); // 打印服务器返回的结果
      } catch (error) {
        console.error('Error fetching username availability:', error); // 捕捉并打印请求错误
      }
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 2. 对象定义侦听器示例




 



 
 
 
 
 
 
 
 
 
 
 
 
 
 



new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    username: '' // 定义一个 username 数据
  },
  watch: {
    // 监听 username 值的变化
    username: {
      async handler(newVal) {
        if (newVal === '') return; // 如果新值为空字符串,则不做任何处理
        try {
          // 使用 axios 发起请求,判断用户名是否可用
          const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal);
          console.log(res); // 打印服务器返回的结果
        } catch (error) {
          console.error('Error fetching username availability:', error); // 捕捉并打印请求错误
        }
      },
      immediate: false, // 是否立即触发回调
      deep: false // 是否深度监听
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

总结

  • 方法定义侦听器:直接在 watch 选项中定义方法,用于监视数据变化,适用于简单的监听需求。
  • 对象定义侦听器:在 watch 选项中定义一个对象,包含 handler 方法和其他选项(如 immediate 和 deep),适用于需要更多控制的监听需求。

# 3. immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果希望在组件初次渲染完成后立即调用侦听器,可以使用 immediate 选项:








 










 




new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    username: '' // 定义一个 username 数据
  },
  watch: {
    username: {
      // handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
      handler: async function (newVal) {
        if (newVal === '') return; // 如果新值为空字符串,则不做任何处理
        try {
          // 使用 axios 发起请求,判断用户名是否可用
          const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal);
          console.log(res); // 打印服务器返回的结果
        } catch (error) {
          console.error('Error fetching username availability:', error); // 捕捉并打印请求错误
        }
      },
      immediate: true // 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

在上面的代码中,immediate: true 表示在组件初次渲染后立即调用侦听器。

笔记

当需要使用 deep 或 immediate 选项时,必须使用对象语法,并在对象中定义 handler 属性来指定回调函数。

# 4. deep 选项

如果需要侦听一个对象内部属性的变化,默认情况下是无法侦听到的。这时需要使用 deep 选项:












 


 




new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    user: {
      name: '', // 用户名
      age: 0 // 用户年龄
    }
  },
  watch: {
    // 监听 user 对象的变化
    user: {
      handler: function (newVal, oldVal) {
        console.log('User data changed:', newVal); // 打印新的用户数据
      },
      deep: true // 深度监听,对象内部任何一个属性发生变化都会被监听到
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

在上面的代码中,deep: true 选项用于深度监听 user 对象内部属性的变化。

# 5. 监听对象单个属性的变化

如果只需要监听对象中某个特定属性的变化,可以直接监听该属性:











 






new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    user: {
      name: '', // 用户名
      age: 0 // 用户年龄
    }
  },
  watch: {
    // 监听 user.name 的变化
    'user.name': function (newVal, oldVal) {
      // newVal 是 user.name 的新值,oldVal 是 user.name 的旧值
      console.log('User name changed from', oldVal, 'to', newVal); // 打印用户名的变化
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

在上面的代码中,直接监听 user.name 的变化。这里的 user.name 使用了字符串路径的方式,告诉 Vue 侦听的是 user 对象的 name 属性,而不是直接的属性名。

# 6. 监听路由变化

# 1. 监听路由路径 ($route.path)

监听路由路径的变化,可以用于更新导航菜单的激活状态或触发某些特定操作。

export default {
  data() {
    return {
      activeIndex: '' // 保存当前激活的菜单项
    };
  },
  watch: {
    // 监听路由路径的变化
    '$route.path'(newPath, oldPath) {
      console.log('Route path changed from', oldPath, 'to', newPath);
      // 更新导航菜单的激活项
      this.activeIndex = newPath;
      // 你还可以在这里添加逻辑,例如根据新路径加载数据
    }
  },
  created() {
    // 初始化时根据当前路由路径设置激活项
    this.activeIndex = this.$route.path;
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2. 监听路由参数 ($route.params)

动态路由参数变化时触发回调,比如 /user/:id,可以用于在参数变化时更新页面数据。

export default {
  watch: {
    // 监听路由参数 id 的变化
    '$route.params.id'(newId, oldId) {
      console.log('Route param id changed from', oldId, 'to', newId);
      // 根据新 ID 更新页面内容,例如加载新的用户信息
      this.fetchUserData(newId);
    }
  },
  methods: {
    fetchUserData(id) {
      // 执行获取用户数据的逻辑
      console.log('Fetching user data for ID:', id);
      // 在这里进行数据请求或其他处理
    }
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3. 监听查询参数 ($route.query)

查询参数变化时触发回调,可以用于处理 URL 中的查询字符串,例如搜索功能。

export default {
  watch: {
    // 监听查询参数的变化
    '$route.query'(newQuery, oldQuery) {
      console.log('Route query changed from', oldQuery, 'to', newQuery);
      // 根据新的查询参数执行搜索或筛选操作
      this.searchResults(newQuery.q);
    }
  },
  methods: {
    searchResults(query) {
      // 执行搜索的逻辑
      console.log('Searching for:', query);
      // 在这里发起请求或更新界面
    }
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 4. 监听路由元信息 ($route.meta)

元信息的变化可以用于权限控制或页面设置。例如,根据路由的元数据决定是否显示某个页面的内容。

export default {
  watch: {
    // 监听路由元信息的变化
    '$route.meta.requiresAuth'(newVal, oldVal) {
      console.log('Route meta requiresAuth changed from', oldVal, 'to', newVal);
      // 根据新的 requiresAuth 值执行逻辑
      if (newVal && !this.isAuthenticated()) {
        // 如果需要认证且用户未登录,则跳转到登录页面
        this.$router.push('/login');
      }
    }
  },
  methods: {
    isAuthenticated() {
      // 判断用户是否已登录
      return !!localStorage.getItem('token');
    }
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 5. 监听完整的路由对象 ($route)

如果需要对整个路由对象进行监听,可以监听 $route。这适用于在路径、参数或查询字符串任意一个发生变化时,执行统一的逻辑。

export default {
  watch: {
    // 监听整个路由对象的变化
    '$route'(to, from) {
      console.log('Route changed from', from.fullPath, 'to', to.fullPath);
      // 根据新的路由执行统一的逻辑处理
      this.handleRouteChange(to, from);
    }
  },
  methods: {
    handleRouteChange(to, from) {
      // 处理路由变化的逻辑
      console.log('Handling route change from', from.fullPath, 'to', to.fullPath);
      // 例如,执行数据清理或更新页面标题
      this.updatePageTitle(to.meta.title);
    },
    updatePageTitle(title) {
      document.title = title || '默认标题';
    }
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 6. 监听路由嵌套路径 ($route.matched)

在多级嵌套路由中,监听 matched 可以用来处理特定层级的路由变化。

export default {
  watch: {
    // 监听路由匹配的组件链的变化
    '$route.matched'(newMatched, oldMatched) {
      console.log('Route matched changed:', newMatched, 'from', oldMatched);
      // 你可以在这里处理嵌套路由的特定逻辑
      this.handleNestedRoutes(newMatched);
    }
  },
  methods: {
    handleNestedRoutes(matched) {
      // 处理嵌套路由的逻辑
      console.log('Handling nested routes:', matched);
      // 例如,加载相应的子组件或更新某些状态
    }
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 7. 计算属性 vs 侦听器

计算属性和侦听器都是响应式编程的重要工具,但它们的适用场景有所不同:

  • 计算属性:适用于依赖其他数据计算得来的属性,具有缓存功能,只有当依赖的数据发生变化时才会重新计算。
  • 侦听器:适用于监视数据的变化并执行异步或开销较大的操作,如 AJAX 请求、复杂的 DOM 操作等。
特性 计算属性 侦听器
缓存 是 否
适用场景 计算属性值 异步操作、复杂操作
简单逻辑 是 否
复杂操作 否 是








 





 






new Vue({
  el: '#app', // 绑定 Vue 实例的根元素
  data: {
    firstName: 'John', // 定义 firstName 数据
    lastName: 'Doe' // 定义 lastName 数据
  },
  computed: {
    // 定义一个计算属性 fullName,依赖于 firstName 和 lastName
    fullName() {
      return this.firstName + ' ' + this.lastName; // 返回拼接后的全名
    }
  },
  watch: {
    // 监听 firstName 的变化
    firstName(newVal, oldVal) {
      // newVal 是 firstName 的新值,oldVal 是 firstName 的旧值
      console.log('First name changed from', oldVal, 'to', newVal); // 打印 firstName 的变化
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在上面的示例中:

  • fullName 是一个计算属性,用于实时计算用户的全名,并且只有当 firstName 或 lastName 发生变化时才会重新计算。
  • watch 侦听器监视 firstName 的变化,并在变化时执行特定的操作。

在 Vue 中,侦听器是通过 watch 选项定义的对象方法,用于监视数据的变化,并在变化时执行相应的回调函数。通过合理使用侦听器,可以更好地实现数据驱动的响应式编程。

总结

watch 中的属性名必须与 data 中的属性名相同。

watch 中的同名属性可以是一个方法,也可以是一个对象。

  • 如果是方法,则为简单的侦听器。
  • 如果是对象,则可以包含 handler 方法和其他选项(如 immediate、deep)。
编辑此页 (opens new window)
上次更新: 2025/01/30, 23:55:43
过滤器(Filters)
计算属性(computed)

← 过滤器(Filters) 计算属性(computed)→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式