玩转Vue3:计算属性和监视属性深度解析

计算属性computed

Vue中的计算属性是一种特殊的属性,它可以根据依赖的数据动态计算并返回结果。计算属性的值是通过getter函数计算得到的,当依赖的数据发生变化时,计算属性会自动重新计算并更新视图。计算属性具有缓存机制,只有当依赖的数据发生变化时才会重新计算 。

Vue3与Vue2中的计算属性配置功能是一样的,不同的是写法

Vue2写法

在Vue2中,computed是通过声明选项的方式书写的,在Vue中,声明选项是指在创建Vue实例时传入的参数,是一个对象。这个对象可以包含多个属性和方法,其中包括data、methods、computed、watch等。这些属性和方法可以用于定义组件的行为和状态。

js 复制代码
            数字1:<input type="text" v-model="num1"> <br/><br/>
            数字2:<input type="text" v-model="num2"> <br/><br/>
            求和:<span>{{num1}}+{{num2}}={{sum}}</span> <br/><br/>
            //在data中只定义num1和num2
            data:{
			num1:10,
			num2:20,
		},
            computed:{
                sum(){
                    return this.num1+this.num2
		       }
            }

其中需要注意的一点是计算属性是不需要声明在data中的,而且声明了会报错

Vue3写法

在Vue3中,computed是通过组合式api的方式书写的,Vue中的组合式API是一组新的API,它允许我们使用函数而不是声明选项的方式书写Vue组件。组合式API包括响应式API、生命周期钩子、工具函数等,这些API可以让我们更灵活地组织和复用代码,提高代码的可读性和可维护性 。

所以我们在Vue3中使用computed的时候需要先引入 import {computed} from 'vue'

js 复制代码
  let sum = computed(()=>{
        return this.num1 + this.num2
    })

监视属性watch

与computed一致,Vue2和Vue3中的watch属性在功能上是一致的。

Vue2

js 复制代码
watch:{
	num1(newval,oldval){
              console.log('num1变化了','新值为:',newval,'旧值为:',oldval)
	}
}

当输入框中的值发生改变时,控制台就会打印相关信息,其中newval是修改后的值,oldval是原来的值。

Vue3

在vue3中watch()方法可以帮助我们监听数据的变化,并按执行一些任务。Vue3中watch接受三个参数,第一个参数是要监听的响应式数据,第二个参数是回调函数,第三个参数是配置项。如果需要监听多个数据,可以在setup函数中使用watch函数多次,每次传入不同的参数即可。不像vue2中的watch是一个配置项,vue3中的watch是一个方法可以多次调用。

1.情景一:监视ref定义的响应式数据

js 复制代码
<template>
  <div>
    <input type="text" v-model="num" placeholder="输入要改变的值">
  </div>
</template>

<script>
import { ref,watch } from 'vue';

export default {
  name: 'TodoList',
  setup() {
    // 使用 ref 创建响应式数据
    const num = ref(10);
    watch(num,(newval,oldval)=>{
      console.log('新值:',newval,'旧值:',oldval)
    })
    // 暴露数据和方法给模板使用
    return {
      num,
    };
  },
};
</script>

当我们修改输入框的值时,watch可以监听到数据的变化。

如果加了{immediate:true}配置项之后表示立即监听,输入框中的值还没有改变就会触发一次watch方法

情景二:监视多个ref定义的响应式数据

js 复制代码
const num = ref(10);
const msg =ref('静Yu讲Vue3')
watch([sum,msg],(newValue,oldValue)=>{
	console.log('sum或msg变化了',newValue,oldValue)
}) 

监听多个响应式数就是放在一个数组中,相应的回调函数中的newval和oldval也是数组的形式。 下图只是改变了num。 情景三:监视reactive定义的响应式数据

js 复制代码
  const person =reactive({
      name: 'JingYu',
      age:18
    })
    watch(person, (newValue, oldValue) => {
      console.log('person变化了', newValue, oldValue)
    }, { immediate: true })

从控制台打印的信息,我们可以清晰地看到oldval的值为undefined。这就是我们需要注意的第一点: 若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!

js 复制代码
     const person =reactive({
      name: 'JingYu',
      age:18,
      job:{
        name:'前端开发',
        salary:'10k'
      }
    })
    watch(person, (newValue, oldValue) => {
      console.log('person变化了', newValue, oldValue)
    }, { immediate: true })
    

在代码中我并没有写deep:true,但是依然可以监听到person下的job属性下的name属性。

js 复制代码
    watch(person, (newValue, oldValue) => {
      console.log('person变化了', newValue, oldValue)
    }, { immediate: true ,deep:false})

而且就算我们在代码中关闭深度监听也是没有用的,所以这里就是我们需要注意的第二点:若watch监视的是reactive定义的响应式数据,则强制开启了深度监视。

情景四:监视reactive定义的响应式数据中的某个属性

如果我们想监听一个对象中的某一个属性,我们肯定会轻松到想到这个代码该怎么写。

js 复制代码
watch(person.name, (newValue, oldValue) => {
      console.log('person变化了', newValue, oldValue)
    }, { immediate: true ,deep:false})

但这时控制台会弹出一个警告,简单翻译一下就是:监视源只能是getter/effect函数、ref、响应对象或这些类型的数组。通俗的说就是,只能监视一个ref的值或者是reactive对象。

正常的写法是写一个函数,函数有返回值

js 复制代码
watch(()=>person.name,(newValue,oldValue)=>{
	console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true}) 

情景五:监视reactive定义的响应式数据中的某些属性

如果是要监视一个响应式数据的多个属性,也按照上文写的监视多个ref定义的响应式数据那样,将多个属性写在一个数组中,不过每一个属性都要写成函数的形式。

js 复制代码
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
	console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true})

特殊情况

当我们监视一个reactive定义的对象中的某个属性时,此时deep配置就会生效,当我们将depp配置设置为false时,是监听不到person.job的变化的。

js 复制代码
   watch(() => person.job, (newValue, oldValue) => {
      console.log('person的job变化了', newValue, oldValue)
    }, { deep: false })

不管我们怎么去修改job下属性的值都是监听不到的。

watchEffect函数

当我们使用watch监视属性的时候,需要明确的指出需要监视的是哪个属性,,也要指明监视的回调函数。 watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

js 复制代码
 const person = reactive({
      name: 'JingYu',
      age: 18,
      job: {
        name: '前端开发',
        salary: '10k'
      }
    })
    watchEffect(() => {
      const x1 = person.name
      const x2 = person.age
      console.log('watchEffect配置的回调执行了',x1,x2)
    })

watchEffect中,我们将person的name和age赋值给两个新的变量,证明我们使用了这两个属性,所以修改这两个属性的值是,就会触发监听函数。

总结

最后总结一下:

1. Computed属性

computed 是一个函数,它返回一个值,该值依赖于组件的数据。当依赖的数据发生改变时,computed 返回的值会自动更新。

在 Vue.js 中,我们通常使用 computed 来封装复杂的逻辑或计算属性,使得我们能够更加方便地处理这些逻辑,并且保证其响应式的特性。

2. Watch属性

watch 是一个对象,它允许我们观察 Vue 实例的数据。当数据变化时,我们可以执行一些操作。

在某些情况下,我们可能需要等待数据改变后执行某些操作,或者在数据改变时执行异步操作。这种情况下,我们可以使用 watch

相关推荐
崔庆才丨静觅10 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606111 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅11 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅11 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅12 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment12 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅12 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊12 小时前
jwt介绍
前端
爱敲代码的小鱼12 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax