1. 发现nextTick必须放在修改一个响应式数据之后,才会在onUpdated之后被调用,如果nextTick是放在所有对响应式数据修改之前,则nextTick里面的回调函数会在onBeforeUpdate方法执行前就被调用了。可是nextTick必须等到onUpdated执行完成之后执行,才能拿到渲染得到的dom
  2. 下面发请求的时候是没有使用async的(Promise的语法糖),它里面的then函数对serverRef的修改,会再一次触发组件重新渲染,也就是onBeforeUpdate和onUpdated又被回调了一次,也就是说,下面的toggleColor这个方法,触发了2次渲染。
---onBeforeMounted---
RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: null, _value: null}
---mounted---
RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: span, _value: span}
halo world
---onBeforeUpdate---
---onUpdated---
RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: button, _value: button}
nextTick1
res ojbk
---onBeforeUpdate---
---onUpdated---
nextTick2
<template>
    <div style="display: flex;">
        <ul class="ul-list">
            <li v-for="i in num" :id="'li'+i" >{{ i }}</li>
        </ul>
        <div class="div-desc">
            <input type="text" v-model="n">
            <button @click="handleClick">修改num</button>
            <br>
            <br>
            <button @click="toggleColor">切换span颜色</button>
            <span ref="spanRef" :style="{color:colorRef}">span</span>
            *{{ serverResp }}*
            <button v-if="isShow" ref="btnRef">dd</button>
        </div>
    </div>
</template>
<script lang="ts" setup>
    import { ref,reactive,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,nextTick,getCurrentInstance } from 'vue'
    const { proxy } = getCurrentInstance()
    let num = ref(10)
    let n = ref(10)
    const btnRef = ref(null)
    let isShow = ref(false)
    let serverResp = ref('')
    const spanRef = ref(null)
    const handleClick = () => {
        num.value = parseInt(n.value)
    }
    const colorRef = ref('')
    const toggleColor = () => {
        debugger
        proxy.Request({
            url:'http://localhost:8083/test'
        }).then(res=>{
            debugger
            console.log('res',res);
            serverResp.value = res
            nextTick(()=>{ // 要放在对响应式数据修改之后
                debugger
                console.log('nextTick2');
            })
        })
        debugger
        isShow.value = true
        nextTick(()=>{  // 要放在对(至少一个)响应式数据修改之后,
                        // 否则这里函数调用将拿不到btnRef,必须要等到onUpdated回调之后,执行nextTick里面的回调才能拿到btnRef
            debugger
            console.log(btnRef); 
            console.log('nextTick1');
        })
        if(colorRef.value === 'red') {
            colorRef.value = 'blue'
        } else {
            colorRef.value = 'red'
        }
        num.value = num.value - 1
        debugger
        console.log('halo world');
    }
    onBeforeMount(() => {
        console.log('---onBeforeMounted---')
        console.log(spanRef);
    })
    onMounted(()=>{
        console.log('---mounted---')
        console.log(spanRef);
        spanRef.value.style.color = 'cyan'
    }) 
    onBeforeUpdate(()=>{
        debugger
        console.log('---onBeforeUpdate---')
    })
    onUpdated(()=>{
        debugger
        console.log('---onUpdated---')
    })
</script>
<style lang="scss">
    .ul-list {
        width: 100px;
    }
    .div-list { 
        width: 300px;
    }
</style>

vue3使用nextTick

发表回复