Vue3的组合API——计算属性computed与监视watch

计算属性

在vue3中时可以使用vue2的方式编写计算属性的,但是不建议。

计算属性编写格式

vue3中把计算属性变成了一个组合式的API,使用的时候需要从vue中引入,然后再setup中进行配置。
vue3中的计算属性仍然有两种写法,简写和全写。全写有get和set方法,简写是如果计算属性只有get方法可以进行简写

import {
    
     computed } from 'vue'
setup() {
    
    
        // 计算属性——简写
        let fullName = computed(() => {
    
    
 			return   
        })
        // 计算属性——全写
        let fullName = computed(() => {
    
    
 			get(){
    
    
                return 
            },
            set(value){
    
    
           }
        })
        
        return {
    
    
            fullName
        }
    }

计算属性例子

实现效果:
在这里插入图片描述
App.vue:

<template>
  <demo/>
</template>

<script>
import Demo from './components/Demo.vue'
export default {
      
      
  name: 'AppVue',
  components: {
      
       Demo },
}
</script>

Demo.vue

<template>
    <h1>Demo组件</h1>
    姓:<input type="text" v-model="person.firstName" />
    <br />
    名:<input type="text" v-model="person.lastName" />
    <br />
    <span>全名:{
   
   {person.fullName}}</span>
    <br />
    全名(可改):<input type="text" v-model="person.fullNameChange" />
</template>

<script>
import {
      
       reactive,computed } from 'vue'
export default {
      
      
    name: 'DemoVue',
    // vue2实现
   /* computed:{
        fullName(){
          return this.person.firstName+"-"+this.person.lastName  
        }
    },*/
    setup() {
      
      
        //  数据
        let person = reactive({
      
      
            firstName: '张',
            lastName: '三',
        })
        // 计算属性
        // 计算属性-简写(没有考虑计算属性被修改的情况,只有get方法时)
        person.fullName = computed(() => {
      
      
            return person.firstName+"-"+person.lastName
        })
        // 计算属性-完整(计算属性可以被修改)
        person.fullNameChange = computed({
      
      
            get(){
      
      
                return person.firstName + "-" + person.lastName
            },
            set(value){
      
      
                const nameArr = value.split("-")
                person.firstName = nameArr[0]
                person.lastName = nameArr[1]
           }
        })
        return {
      
      
            person,
        }
    }
}
</script>

watch监视

在vue3中时可以使用vue2的方式编写watch,但是不建议。
vue3中把 watch变成了一个组合式的API,使用的时候需要从vue中引入,然后再setup中进行配置。

watch监视ref定义的数据

可以监视一个数据也可以同时监视多个数据。
格式:

import {
    
    watch } from 'vue'
setup() {
    
    
		//监视一个数据
        watch(监视属性, (newValue, oldValue) =>{
    
    
           监视的回调
        }{
    
    监视的配置})
        //监视多个数据
        watch([监视属性1,监视属性2], (newValue, oldValue) =>{
    
    
           监视的回调
        }{
    
    监视的配置})
    }

eg:
效果:
在这里插入图片描述
代码:
demo.vue:

<template>
    <h1>Demo组件</h1>
    <h2>当前求和为:{
   
   {sum}}</h2>
    <button @click="sum++">点我+1</button>
    <h2>当前信息为:{
   
   {msg}}</h2>
    <button @click="msg+='!'">修改信息</button>
</template>

<script>
import {
      
      reactive, ref, watch} from 'vue'
export default {
      
      
    name: 'DemoVue',
    // vue2中的watch写法
    /*watch: {
        // sum(newValue,oldValue) {
        //     console.log("sum的值变化了",newValue,oldValue)
        // }
        sum: {
            immediate: true,
            deep:true,
            handler(newValue, oldValue) {
                console.log('sum的值变化了', newValue, oldValue)
            }
        }
    
    },*/
    setup() {
      
      
        //  数据
        let sum = ref(0)
        let msg = ref('你好呀')
        // 监视
        // 监视ref所定义的一个响应式数据
        watch(sum, (newValue, oldValue) =>{
      
      
            console.log('sum的值变化了', newValue, oldValue)
        },{
      
      immediate:true})
         // 监视ref所定义的多个响应式数据
        watch([sum,msg], (newValue, oldValue) => {
      
      
            console.log('sum的值变化了', newValue, oldValue)
        })
        return {
      
      
            sum,
            msg,
        }
    }
}
</script>

watch监视ref对象——value问题

上面的情况是watch直接监视ref创建的对象,无需.value,因为.value之后取得就是该变量的具体的值(一个常量),无法监视它的变化。
如果watch监视的是ref所创建的对象,有两种监视办法:

  • 对象.value进行监视,因为.value之后才能获取对象的属性,进而进行监视。而.value之后检测的就是reactive生成的数据了,是深层次的
  • 开启{deep:true}配置,开启深层次监视,这样属性变化才能被监视到
    eg:
        //  数据
        let sum = ref(0)
        let msg = ref('你好呀')
        let person = ref({
    
    
            name: 'yang',
            age: 18,
            job:{
    
    
                j1:{
    
    
                    salary:20
                }
            }
        })
		//监视基本数据
        watch(sum, (newValue, oldValue) => {
    
    
            console.log('sum的值变化了', newValue, oldValue)
        })
        //监视对象
        //第一种写法
        watch(person.value, (newValue, oldValue) => {
    
    
            console.log('person的值变化了', newValue, oldValue)
        })
        //第二种写法
        watch(person, (newValue, oldValue) => {
    
    
            console.log('person的值变化了', newValue, oldValue)
        },{
    
    deep:true})

watch监视reactive定义的数据

  • 监视reactive定义的响应式数据时: oldValue无法正确获取、强制开启了深度监视(deep配置失效)
  • 监视reactive定义的响应式数据中某个属性时: deep配置有效(但是监视的数据是一个对象deep配置才有意义)。
  • 当监视reactive定义的响应式数据或其属性的时候,如果监视的是一个对象,oldValue就无效。

eg:监视reactive定义的数据的四种情况:

 setup() {
    
    
        //  数据
        let sum = ref(0)
        let msg = ref('你好呀')
        let person = reactive({
    
    
            name: 'yang',
            age: 18,
            job:{
    
    
                j1:{
    
    
                    salary:20
                }
            }
        })

        /* 监视reactive所定义的一个响应式数据的全部属性
            1.注意:此处无法正确的获取oldValue
            2.注意:强制开启了深度监视(deep配置无效),即自动默认deep为true且无法修改为false。
        */
        watch(person, (newValue, oldValue) => {
    
    
            console.log('person变换了', newValue, oldValue)
        })
        /* 
        监视reactive所定义的一个响应式数据的一个属性(需要使用函数包裹属性)
        oldValue有效,deep有效
        */
        watch(()=>person.age, (newValue, oldValue) => {
    
    
            console.log('person变换了', newValue, oldValue)
        })
        /* 监视reactive所定义的一个响应式数据的某些属性(需要使用数组)
        oldValue有效,deep有效
        */
        watch([() => person.age, () => person.name], (newValue, oldValue) => {
    
    
            console.log('person的age变化了', newValue, oldValue)
        })
        /*特殊情况:如果监视的reactive属性是一个对象,直接监视就监视不到改变,因为他监视的是对象的地址 ,所以需要设置deep:true
        监视的是一个对象所以oldValue无效;监视的不是reactive所定义的一个响应式数据,deep有效*/
        watch(() => person.job, (newValue, oldValue) => {
    
    
            console.log('person的job发生变化了', newValue, oldValue)
        },{
    
     deep: true })
        return {
    
    
            sum,
            msg,
            person
        }
    }

watchEffect函数

  • watch的套路是: 既要指明监视的属性,也要指明监视的回调
  • watchEffect的套路是: 不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
    watchEffect的回调函数一上来的时候会执行一次
    eg:
        watchEffect(() => {
    
    
            const x1 = sum.value
            const x2 = person.job.j1.salary
            console.log("watchEffect指定的回调执行了")
        })

即当sum.value属性和person.job.j1.salary属性发生变化的时候执行watchEffect的回调函数。

eg:

    setup() {
    
    
        //  数据
        let sum = ref(0)
        let msg = ref('你好呀')
        let person = reactive({
    
    
            name: 'yang',
            age: 18,
            job:{
    
    
                j1:{
    
    
                    salary:20
                }
            }
        })

        // 监视
        watch(sum, (newValue, oldValue) => {
    
    
            console.log('sum的值变化了', newValue, oldValue)
        }, {
    
     immediate: true })

        watchEffect(() => {
    
    
            const x1 = sum.value
            const x2 = person.job.j1.salary
            console.log("watchEffect指定的回调执行了")
        })
        
        return {
    
    
            sum,
            msg,
            person
        }
    }

在这里插入图片描述

watchEffect有点像computed :

  • 都是所依赖的属性发生变化的时候会执行函数体
  • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值;而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

猜你喜欢

转载自blog.csdn.net/mantou_riji/article/details/125963552