vue 侦听器

简介: vue 侦听器

基本示例

计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。

在组合式 API 中,我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数:

<script setup>
import { ref, watch } from 'vue'
const question = ref('')
const answer = ref('Questions usually contain a question mark. ;-)')
const loading = ref(false)
// 可以直接侦听一个 ref
watch(question, async (newQuestion, oldQuestion) => {
  if (newQuestion.includes('?')) {
    loading.value = true
    answer.value = 'Thinking...'
    try {
      const res = await fetch('https://yesno.wtf/api')
      answer.value = (await res.json()).answer
    } catch (error) {
      answer.value = 'Error! Could not reach the API. ' + error
    } finally {
      loading.value = false
    }
  }
})
</script>
<template>
  <p>
    Ask a yes/no question:
    <input v-model="question" :disabled="loading" />
  </p>
  <p>{{ answer }}</p>
</template>

侦听数据源类型

watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:

const x = ref(0)
const y = ref(0)
// 单个 ref
watch(x, (newX) => {
  console.log(`x is ${newX}`)
})
// getter 函数
watch(
  () => x.value + y.value,
  (sum) => {
    console.log(`sum of x + y is: ${sum}`)
  }
)
// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {
  console.log(`x is ${newX} and y is ${newY}`)
})

注意,你不能直接侦听响应式对象的属性值,例如:

const obj = reactive({ count: 0 })
// 错误,因为 watch() 得到的参数是一个 number
watch(obj.count, (count) => {
  console.log(`count is: ${count}`)
})

这里需要用一个返回该属性的 getter 函数:

// 提供一个 getter 函数
watch(
  () => obj.count,
  (count) => {
    console.log(`count is: ${count}`)
  }
)

深层侦听器

直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发:

const obj = reactive({ count: 0 })
watch(obj, (newValue, oldValue) => {
  // 在嵌套的属性变更时触发
  // 注意:`newValue` 此处和 `oldValue` 是相等的
  // 因为它们是同一个对象!
})
obj.count++

相比之下,一个返回响应式对象的 getter 函数,只有在返回不同的对象时,才会触发回调:

js

watch(
  () => state.someObject,
  () => {
    // 仅当 state.someObject 被替换时触发
  }
)

你也可以给上面这个例子显式地加上 deep 选项,强制转成深层侦听器:

watch(
  () => state.someObject,
  (newValue, oldValue) => {
    // 注意:`newValue` 此处和 `oldValue` 是相等的
    // *除非* state.someObject 被整个替换了
  },
  { deep: true }
)

 

相关文章
|
2天前
|
JavaScript 前端开发 C++
【Vue】Vue快速入门、Vue常用指令、Vue的生命周期
【Vue】Vue快速入门、Vue常用指令、Vue的生命周期
13 2
|
4天前
|
存储 缓存 JavaScript
谈谈你对vue的了解
谈谈你对vue的了解
14 3
|
4天前
|
JavaScript API
Vue axjx 跨域请求
Vue应用中解决跨域问题可通过配置代理服务器。方法一是设置`devServer.proxy`到目标服务器端口,如`http://localhost:3000`,然后使用axios发送请求。方法二是为多个代理配置,如`/api`和`/api2`,分别指向不同端口,利用`pathRewrite`重写路径。请求时需加上相应前缀,如`/api/index`。
13 1
|
5天前
|
JavaScript 前端开发 Java
JavaSE精选-Vue
JavaSE精选-Vue
7 1
|
5天前
|
JavaScript
Vue父子组件传值
<!-- 父组件向子组件传地值 -->
15 2
|
5天前
|
JavaScript Java
Vue : v-if, v-show
Vue : v-if, v-show
13 0
Vue : v-if, v-show
|
5天前
|
JavaScript 前端开发
Vue : 监视属性
Vue : 监视属性
9 0
|
5天前
|
缓存 JavaScript
Vue: 事件修饰符, 键盘事件, 鼠标事件,计算属性
Vue: 事件修饰符, 键盘事件, 鼠标事件,计算属性
22 2
|
5天前
|
JavaScript 安全
一文彻底学会vue的组件通信
Vue组件通信包括父向子通过`props`传递数据,如`&lt;Student :name=&quot;18&quot;&gt;&lt;/Student&gt;`,子组件通过`$emit`触发自定义事件与父组件通信,如`this.$emit(&#39;myEvent&#39;, this.name)`。此外,使用全局事件总线(`Vue.prototype.$bus`)可在多级组件间通信,通过`$on`订阅和`$emit`发布事件。还有消息订阅与发布模式,利用`pubsub-js`库实现更灵活的组件交互。
15 0
一文彻底学会vue的组件通信
|
5天前
|
缓存 JavaScript
一文彻底学会Vue路由
Vue Router简介,包括基本使用、嵌套路由、参数传递和路由守卫。首先,通过`npm i vue-router@3`安装,然后在`main.js`引入并应用。配置路由时,创建VueRouter实例,定义如`/home`、`/about`等路径及其对应组件。使用`&lt;router-link&gt;`进行切换,`&lt;router-view&gt;`展示组件。嵌套路由通过`children`配置多级路径,参数传递可使用`query`或`params`。路由守卫分为全局、独享和组件内三种,用于控制访问权限。
15 1
一文彻底学会Vue路由