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

相关推荐
joan_851 分钟前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
m0_7482361132 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo6171 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_748248941 小时前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_748235611 小时前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O3 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink6 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者7 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-8 小时前
验证码机制
前端·后端
燃先生._.9 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js