Vue3---基础5(computed和watch、watchEffect)

computed 计算属性

        代码示例

<template>
    <div class="person">
        <div>姓:<input type="text" v-model="firstName"></div>
        <div>名:<input type="text" v-model="lastName"></div>
        <button @click="hChangeName">修改名字</button>
        <div>全名:{{ fullName }}</div>
    </div>
</template>

<script lang="ts">
// 引入
import { ref, computed } from 'vue';
</script>

<script lang="ts" setup>
// 定义的数据
let firstName = ref('张')
let lastName = ref('杰')

// 此为 只读 的计算属性
// let fullName = computed(() => {
//     return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value
// })

// 此为 可读可写 的计算属性
let fullName = computed({
    get(){
        return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value
    },
    set(val){
        // console.log('val', val);
        const [str1, str2] = val.split('-')
        firstName.value = str1
        lastName.value = str2
    }
})

function hChangeName(){
    fullName.value = 'Jason-Zhang'
}
</script>

watch 监听

        作用:监视数据的变化( 和Vue2中的watch作用一致 )

        特点:Vue3 中的 watch 只能监视一下四种数据        

        1. ref 定义的数据

        2. reactive 定义的数据

        3. 函数返回一个值(getter函数)

        4. 一个包含上述内容的数组

        我们在 Vue3 中使用 watch 的时候,通常会遇到以下几种情况

情况一  ref定义的基本类型

        监视 ref 定义的 基本类型数据:直接写数据名即可,监视的是其 value 值的改变

<template>
    <div class="person">
        <h1>情况一:监视【ref】定义的【基本类型】数据</h1>
        <h2>当前求和为: {{ sum }}</h2>
        <button @click="hChangeSum">+1</button>
    </div>
</template>

<script lang="ts" setup name="text2">
    import { ref,watch} from 'vue';
    // 数据
    let sum = ref(0)
    // 方法
    function hChangeSum(){
        sum.value += 1
    }
    // 监视 情况一:监视【ref】定义的【基本类型】数据
    // watch(监视对象, 回调函数)
    const stopWatch = watch(sum, (newVal, oldVal) => {
        console.log("sum值变化",newVal, oldVal);
        // 在特定情况下停止监视
        if(newVal >= 10) {
            stopWatch()
        }
    })
</script>

情况二  ref定义的对象类型

        监视 ref 定义的 对象类型 数据:直接写数据名,监视的是对象的 地址值,若想监视对象内部的数据,要手动开启深度监听

注意:

        若修改的是 ref 定义的对象中的属性newValue 和 oldValue 都是新值,因为它们是同一个对象

        若修改整个 ref 定义的对象,newValue 是新值,oldValue 是旧值,因为不是同一个对象了

<template>
    <div class="person">
        <h1>情况二:监视【ref】定义的【对象类型】数据</h1>
        <h2>姓名:{{ person.name }}</h2>
        <h2>年龄:{{ person.age }}</h2>
        <button @click="hChangeName">修改名字</button>
        <button @click="hChangeAge">修改年龄</button>
        <button @click="hChangePerson">修改整个人</button>
    </div>
</template>

<script lang="ts" setup name="text2">
    import { ref,watch} from 'vue';
    //          二
    // 数据
    let person = ref({
        name:'张杰',
        age:22,
    })
    // 方法
    function hChangeName(){
        person.value.name += '~'
    }
    function hChangeAge(){
        person.value.age += 1
    }
    function hChangePerson(){
        person.value = {name: 'Jason', age: 27}
    }
    /* 
        监视 情况二-1:监视【ref】定义的【基本类型】数据,想监视对象内部属性的变化,需要手动开启(深度监听)
        watch的第一个参数是:被监视的对象
        watch的第二个参数是:监视的回调
        watch的第三个参数是:配置对象(deep 深度监听, immediate 立即监听,等等)
    */
    watch(person, (newVal, oldVal) =>{
        console.log("person值变化",newVal, oldVal);
    },{deep:true, immediate:true})

</script>

情况三  reactive定义的对象类型

        监视 reactive 定义的【对象类型】数据,且默认开启了深度监听

<template>
    <div class="person">
        <h1>情况三:监视【ref】定义的【对象类型】数据</h1>
        <h2>姓名:{{ person.name }}</h2>
        <h2>年龄:{{ person.age }}</h2>
        <button @click="hChangeName">修改名字</button>
        <button @click="hChangeAge">修改年龄</button>
        <button @click="hChangePerson">修改整个人</button>
    </div>
</template>

<script lang="ts" setup name="text2">
    import { reactive,watch} from 'vue';
    //          三
    // 数据
    let person = reactive({
        name:'张杰',
        age:22,
    })
    // 方法
    function hChangeName(){
        person.name += '~'
    }
    function hChangeAge(){
        person.age += 1
    }
    function hChangePerson(){
        Object.assign(person, {name:'Jason Zhang', age: 27})
    }
    // 监视 情况三:监视【ref】定义的【对象类型】数据 默认开启深度监听
    // 可以通过 deep:false 去关闭
    watch(person, (newVal, oldVal) =>{
        console.log("person值变化",newVal, oldVal);
    })

</script>

情况四   ref或reactive定义的对象类型中某个属性

        监视 ref 或 reactive 定义的【对象类型】数据中的某个属性

注意点:

        1. 若该属性值不是【对象类型】,需要写成函数形式;

        2. 若该属性值依然是【对象类型】,可直接编,也可写成函数,建议写成函数;

<template>
    <div class="person">
        <h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
        <h2>姓名:{{ person.name }}</h2>
        <h2>年龄:{{ person.age }}</h2>
        <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
        <button @click="hChangeName">修改名字</button>
        <button @click="hChangeAge">修改年龄</button>
        <button @click="hChangeCar1">修改第一台车</button>
        <button @click="hChangeCar2">修改第二台车</button>
        <button @click="hChangeAllCar">修改整个车</button>
    </div>
</template>

<script lang="ts" setup name="text2">
    import { reactive,watch} from 'vue';
    //          四
    // 数据
    let person = reactive({
        name:'张杰',
        age:22,
        car:{
            c1:'小米su7',
            c2:'保时捷',
        }
    })
    // 方法
    function hChangeName(){
        person.name += '~'
    }
    function hChangeAge(){
        person.age += 1
    }
    function hChangeCar1(){
        person.car.c1 = '小米SU35'
    }
    function hChangeCar2(){
        person.car.c2 = '劳斯莱斯'
    }
    function hChangeAllCar(){
        person.car = {c1: '问界M7', c2: '问界M9', }
    }
    // 监视 情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性,要写成函数式
    watch(()=>person.name, (newVal, oldVal) =>{
        console.log("person.name值变化",newVal, oldVal);
    })
    /* 
        如果直接写,整体car的改变无法监听到
        如果写成函数式,无法检测对象内的变化
        此时加上 deep:true 就可以都检测到
    */
    watch(()=>person.car, (newVal, oldVal) =>{
        console.log("person.name值变化",newVal, oldVal);
    },{deep:true})

</script>

情况五  监视上述多个数据

// 监视 情况五:监视上述多个数据
watch([()=>person.name,()=>person.car.c1], (newVal, oldVal) =>{
    console.log("person.name值变化",newVal, oldVal);
})

watchEffect  监听

        官网:立即运行一个函数,同时响应式的追踪其依赖,并在依赖更改时重新执行该函数

watch 对比 watchEffect

        1. 都能监听响应式数据的变化,不同的是监听数据变化的方法不同

        2. watch:要明确指出监视的数据

        3. watchEffect:不用明确指出监视的数据(函数中用到哪些属性,就监视哪些属性)

<template>
    <div class="person">
        <h2>当水温达到60度时,或水位到达80cm时,给服务器发请求</h2>
        <h2>当前水温:{{ temp }}℃</h2>
        <h2>当前水位:{{ height }}cm</h2>
        <button @click="hChangeTemp">水温+10</button>
        <button @click="hChangeHeight">水位+10</button>
    </div>
</template>

<script lang="ts" setup name="text2">
    import { ref,watch, watchEffect} from 'vue';
    // 数据
    let temp = ref(10)
    let height = ref(5)
    // 方法
    function hChangeTemp(){
        temp.value += 10
    }
    function hChangeHeight(){
        height.value += 10
    }
    
    // 监视 ------ watch 实现
    // watch([temp,height], (value) =>{
    //     // 从value 中获取最新的水温和水位
    //     let [newTemp, newheight] = value
    //     // 逻辑
    //     if(newTemp >=60 || newheight >= 80) {
    //         console.log('发请求');
    //     }
    // })

    // 监视 ------ watchEffect 实现
    watchEffect(() => {
        // 逻辑
        if(temp.value >=60 || height.value >= 80) {
            console.log('发请求');
        }
    })

</script>

 

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 中,`watch` 和 `computed` 的用法和 Vue 2 中略有不同。 ## watch ### 监听单个响应式数据 在 Vue 3 中,你可以使用 `watch` 函数来监听一个响应式数据的变化。例如: ```javascript import { watch } from 'vue'; // 在 setup 函数中使用 watch setup() { const count = ref(0); watch(count, (newValue, oldValue) => { console.log(`count 从 ${oldValue} 变为 ${newValue}`); }); return { count }; } ``` 在上面的例子中,我们使用 `watch` 函数监听了 `count` 的变化,并在回调函数中输出了新旧值。 ### 监听多个响应式数据 如果需要监听多个响应式数据的变化,你可以传入一个对象,对象的属性名是需要监听的数据,属性值是回调函数。例如: ```javascript import { watch, ref } from 'vue'; // 在 setup 函数中使用 watch setup() { const count1 = ref(0); const count2 = ref(0); watch({ count1: (newValue, oldValue) => { console.log(`count1 从 ${oldValue} 变为 ${newValue}`); }, count2: (newValue, oldValue) => { console.log(`count2 从 ${oldValue} 变为 ${newValue}`); } }); return { count1, count2 }; } ``` ### 监听非响应式数据 如果需要监听非响应式数据的变化,你可以使用 `watchEffect` 函数。例如: ```javascript import { watchEffect } from 'vue'; // 在 setup 函数中使用 watchEffect setup() { let count = 0; watchEffect(() => { console.log(`count 变为 ${count}`); }); return { count }; } ``` ## computedVue 3 中,你可以使用 `computed` 函数来创建计算属性。例如: ```javascript import { computed, ref } from 'vue'; // 在 setup 函数中使用 computed setup() { const count = ref(0); const doubleCount = computed(() => { return count.value * 2; }); return { count, doubleCount }; } ``` 在上面的例子中,我们创建了一个计算属性 `doubleCount`,它的值是 `count` 的两倍。当 `count` 改变时,`doubleCount` 也会自动更新。 需要注意的是,计算属性的返回值必须是一个响应式数据。如果返回的是普通数据,那么计算属性就没有意义了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值