玩转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
		       }
            }

image.png

 


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

image.png

 

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是原来的值。

image.png

 

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可以监听到数据的变化。

image.png

 

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

image.png

 

情景二:监视多个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。

image.png

 

情景三:监视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!

image.png

 

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

image.png

 

在代码中我并没有写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对象。

image.png

 

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

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下属性的值都是监听不到的。

image.png

 

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赋值给两个新的变量,证明我们使用了这两个属性,所以修改这两个属性的值是,就会触发监听函数。

image.png

 

总结

最后总结一下:

1. Computed属性

computed 是一个函数,它返回一个值,该值依赖于组件的数据。当依赖的数据发生改变时,computed 返回的值会自动更新。
在 Vue.js 中,我们通常使用 computed 来封装复杂的逻辑或计算属性,使得我们能够更加方便地处理这些逻辑,并且保证其响应式的特性。

2. Watch属性

watch 是一个对象,它允许我们观察 Vue 实例的数据。当数据变化时,我们可以执行一些操作。
在某些情况下,我们可能需要等待数据改变后执行某些操作,或者在数据改变时执行异步操作。这种情况下,我们可以使用 watch。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值