Vue3 Day4-计算、监视属性

4.1 computed计算属性

简写形式和全写形式

<template>
    <div>
        person.firstName:<input type="text" v-model="person.firstName" />
        <br />
        person.lastName:<input type="text" v-model="person.lastName" />
        <br />
        fullName:<input type="text" v-model="fullName" />
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        computed
    } from 'vue'
​
    let person = reactive({
        firstName: '吴',
        lastName: '老'
    })
​
    // 简写形式:里面是箭头函数
    // let fullName = computed(() => {
    //  return person.firstName + '-' + person.lastName
    // })
​
    // 全写形式:里面是对象写法
    let fullName = computed({
        get: () => {
            return person.firstName + '-' + person.lastName
        },
        set: (val) => {
            let nameArr = val.split('-') //将val字符串转成数组
            person.firstName = nameArr[0] //将改变的第一个名重新赋给person.firstName
            person.lastName = nameArr[1]
        }
    })
</script>
​
<style scoped>
​
</style>

4.2 watch监视属性

1.监视ref定义基本数据类型的响应式数据
<template>
    <div>
        <!-- 情况1:监视ref定义基本数据类型的响应式数据 -->
        <h2>{{num}}</h2>
        <button @click="numAdd">num++</button>
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        watch
    } from 'vue'
​
    let num = ref(12)
    let numAdd = () => {
        num.value++
    }
    watch(num, (newval, oldval) => {
        console.log('oldval', oldval);
        console.log('newval', newval);
    }, {
        immdeiate: true
    })
</script>
​
<style scoped>
​
</style>
2.监视ref定义的某些基本数据类型的响应式数据
<template>
    <div>
        <!-- 情况2:监视ref定义的某些基本数据类型的响应式数据 -->
        <h2>{{num}}</h2>
        <h2>{{msg}}</h2>
        <button @click="infoAdd">info++</button>
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        watch
    } from 'vue'
​
    let num = ref(12)
    let msg = ref('小孩姐')
    let infoAdd = () => {
        num.value++
        msg.value += '@'
    }
​
    // 方式1:分开监听
    // watch(num, (newval, oldval) => {
    //  console.log('oldval', oldval);
    //  console.log('newval', newval);
    // }, {
    //  immdeiate: true
    // })
    // watch(msg, (newval, oldval) => {
    //  console.log('oldval', oldval);
    //  console.log('newval', newval);
    // }, {
    //  immdeiate: true
    // })
​
    // 方式2:合并监听
    watch([num, msg], (newval, oldval) => {
        console.log('oldval', oldval);
        console.log('newval', newval);
    }, {
        immediate: true
    })
</script>
​
<style scoped>
​
</style>
3.监视ref定义的对象数据类型的响应式数据
<template>
    <div>
        <!-- 情况3:监视ref定义的对象数据类型的响应式数据 -->
        <h2>{{info.name}}</h2>
        <h2>{{info.age}}</h2>
        <button @click="infoAdd">info++</button>
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        watch
    } from 'vue'
​
    let info = ref({
        name: '小孩姐',
        age: 12
    })
    let infoAdd = () => {
        info.value.name += '@'
        info.value.age++
    }
​
    // 监视ref定义的对象类型,必须添加deep深度监听;如果想监听到新老值,那必须监听里面的某个值(箭头函数写法),或者用数组的方法来监听某些值
    watch([() => info.value.name, () => info.value.age], (newval, oldval) => {
        console.log("oldval=>", oldval);
        console.log("newval=>", newval);
    }, {
        deep: true
    })
</script>
​
<style scoped>
​
</style>
4.监视reactive定义的响应式数据
<template>
    <div>
        <!-- 情况4:监视reactive定义的响应式数据 -->
        <h2>{{info.name}}</h2>
        <h2>{{info.age}}</h2>
        <h2>{{info.job.work.year}}</h2>
        <button @click="infoAdd">info++</button>
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        watch
    } from 'vue'
​
    let info = reactive({
        name: '小孩姐',
        age: 12,
        job: {
            work: {
                year: 3
            }
        }
    })
    let infoAdd = () => {
        info.name += '@'
        info.age++
        info.job.work.year++
    }
​
    // 子情况1:监视reactive定义的响应式数据中的某些属性,deep无法关闭它是自动开启的
    // watch([() => info.name, () => info.age, () => info.job.work.year], (newval, oldval) => {
    //  console.log('oldval=>', oldval);
    //  console.log('newval=>', newval);
    // }, {
    //  immediate: true
    // })
​
    // 子情况2:监视的内容下面还有更深层次的内容 那么就需要用到deep,否则无效
    watch([() => info.job], (newval, oldval) => {
        console.log('oldval=>', oldval);
        console.log('newval=>', newval);
    }, {
        immediate: true,
        deep: true
    })
</script>
​
<style scoped>
​
</style>

4.3 watchEffect的使用

watchEffect能够立即监听 同时是深度监听并可以监听到新老值

<template>
    <div>
        <!-- watchEffect的使用 -->
        <h2>{{info.name}}</h2>
        <h2>{{info.age}}</h2>
        <h2>{{info.job.work.year}}</h2>
        <button @click="infoAdd">info++</button>
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        watch,
        watchEffect
    } from 'vue'
​
    let info = reactive({
        name: '小孩姐',
        age: 12,
        job: {
            work: {
                year: 3
            }
        }
    })
    let infoAdd = () => {
        info.name += '@'
        info.age++
        info.job.work.year++
    }
    // watchEffect能够立即监听 同时是深度监听并可以监听到新老值
    watchEffect(() => {
        let val1 = info.age
        let val2 = info.job.work.year
        console.log('val1', val1);
        console.log('val2', val2);
    })
</script>
​
<style scoped>
​
</style>

4.4 watch对比watchEffect

1.watch 和 watchEffect 都能监听响应式数据的变化,不同的是它们监听数据变化的方式不同。watch 会明确监听某一个响应数据,而 watchEffect 则是隐式的监听回调函数中响应数据。 2.watch 在响应数据初始化时是不会执行回调函数的,watchEffect 在响应数据初始化时就会立即执行回调函数。

注意:

  • onInvalidate:副作用清理函数

  • watchPostEffect() 是watchEffect() 使用 flush: 'post' 选项时的别名

<template>
    <div>
        <h2 ref="hbu">{{num}}</h2>
        <button @click="infoAdd">info++</button>
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        watch,
        watchEffect,
        watchPostEffect
    } from 'vue'
​
    let num = ref(12)
    let hbu = ref()
    let infoAdd = () => {
        num.value++
    }
​
    //onInvalidate:副作用清理函数
    // watch(num, (newval, oldval, onInvalidate) => {
    //  console.log('小孩哥');
    //  console.log('DOM节点:', hbu.value.innerText);
    //  onInvalidate(() => {
    //      console.log('我是清理副作用的代码');
    //  })
    // }, {
    //  flush: 'post'
    // })
​
    // watchEffect写法:
    // watchEffect(onInvalidate => {
    //  console.log(num.value);
    //  console.log('DOM节点:', hbu.value.innerText);
    //  onInvalidate(() => {
    //      console.log('我是清理副作用的代码');
    //  })
    // }, {
    //  flush: 'post'
    // })
​
    // watchPostEffect() 是watchEffect() 使用 flush: 'post' 选项时的别名
    //  watchPostEffect写法:
    watchPostEffect(onInvalidate => {
        console.log(num.value);
        console.log('DOM节点:', hbu.value.innerText);
        onInvalidate(() => {
            console.log('我是清理副作用的代码');
        })
    })
</script>
​
<style scoped>
​
</style>

4.5 nextTick以及watchPostEffect的使用

两者都可以立即监视到数据的变化

<template>
    <div>
        <button ref="hbu" @click="change">{{content}}</button>
    </div>
</template>
​
<script setup>
    import {
        ref,
        reactive,
        watch,
        watchEffect,
        watchPostEffect,
        nextTick
    } from 'vue'
​
    let content = ref('改变我吧')
    let hbu = ref(null)
    let change = () => {
        content.value = '我是改变后的'
        // console.log(hbu.value.innerText);  //改变我吧
​
        // 1.nextTick()
        // nextTick(() => {
        //  console.log(hbu.value.innerText); //我是改变后的
        // })
    }
​
    // 2.watchPostEffect()
    watchPostEffect(() => {
        console.log('watchEffect=>', hbu.value.innerText);
        console.log('watchEffect=>', content.value);
    })
</script>
​
<style scoped>
​
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值