前端VUE:watch 侦听器与computed计算属性

155 阅读4分钟

1. watch 侦听器

watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作

基本语法: 开发者要在 watch 节点下,定义自己的侦听器

export default {
  data() {
    return {
      name: ''
    }
  },
  watch: {
    name(newVal, oldVal) {
    // ......
    }
  }
}

1.1 immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。若想让 watch 侦听器立即被调用,需要使用 immediate 选项

示例代码如下:

watch: {
  name: {
    // handler 是固定写法,表示当 name 的值变化时,自动调用 handler 处理函数
    handler: async function (newVal) {
      if (newVal === '') return
        const { data: res } = await axios.get('请求地址' + newVal)
        console.log(res)
      },
  // 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
    immediate: true
  }
}

1.2 deep 选项

当 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。则需要使用 deep 选项

代码示例如下:

export default {
  data() {
    return {
      name: {name: 'zs'}
    }
  },
  watch: {
    name: {
      handler (newVal) {
        // ......
        },
      deep: true
    }
  }
}

如果只想监听对象中单个属性的变化,可以简写成以下方式:

export default {
  data() {
    return {
      name: {name: 'zs'}
    }
  },
  watch: {
    'name.name': {
      handler (newVal) {
        // ......
      },
    }
  }
}

2. computed计算属性

计算属性指的是通过一系列运算之后,最终得到一个属性值, 其动态计算出来的属性值可以直接被模板结构或 methods 方法使用

本质: 就是一个 function 函数,它可以实时监听 data 中数据的变化,并 return 一个计算后的新值,供组件渲染 DOM 时使用

计算属性需要以 function 函数的形式声明到组件的 computed 选项中

<input type="text" v-model.number="count" />
<p>{{count}} 乘以 2 的值为:{{plus}}</p>
export default {
  data() {
    return {
      count: 2
    }
  },
  computed: {
    plus() {
      return this.count * 2 // 返回结果当然就是 4
    }
  }
}

注意:计算属性侧重于得到一个计算的结果,因此计算属性中必须有 return 返回值!

  • 计算属性必须定义在 computed 节点中
  • 计算属性必须是一个 function 函数
  • 计算属性必须有返回值
  • 计算属性必须当做普通属性使用
  • 虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性

2.1 computed:{}计算属性 vs methods(){}方法

相对于方法来说,计算属性会缓存计算的结果 只有计算属性的依赖项发生变化时,才会重新进行运算 且计算属性的性能更好

3. 侦听器 vs 计算属性

侧重的应用场景不同:

  • 计算属性侧重于监听多个值的变化,最终计算并返回一个新值
  • 侦听器侧重于监听单个数据的变化,最终执行特定的业务处理,不需要有任何返回值

3.1 watch 侦听器

  • 不支持数据缓存,当数据变化时,它就会触发相应的操作
  • watch 侦听器支持异步监听,当想要执行异步或者昂贵的操作以响应不断的变化时,就需要使用 watch 侦听器
  • 监听的函数接收两个参数,第一个参数是最新的值,第二个是变化之前的值
  • 当一个属性发生变化时,就需要执行相应的操作
  • 监听数据必须是 data 中声明的或者父组件传递过来的 props 中的数据,当发生变化时,会触发其他操作

函数有两个的参数:

  • immediate:组件加载立即触发回调函数
  • deep:深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象发生变化。需要注意的是,deep无法监听到数组和对象内部的变化

当需要在 数据变化 时执行 异步或开销较大 的操作时,应该使用 watch 侦听器,使用 watch 侦听器 选项允许执行异步操作 ( 访问一个 API ),限制执行该操作的频率,并在得到最终结果前,设置中间状态。这些都是计算属性无法做到的

3.2 Computed 计算属性

  • 不支持异步,当 Computed 中有异步操作时,无法监听数据的变化
  • computed的值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于 data 声明过,或者父组件传递过来的 props 中的数据进行计算的
  • 如果一个属性是由其他属性计算而来的,这个属性依赖其他的属性,一般会使用 computed 计算属性
  • 如果 computed 属性的属性值是函数,那么默认使用get方法,函数的返回值就是属性的属性值;在computed中,属性有一个get方法和一个set方法,当数据发生变化时,会调用set方法

当需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算