vue3 相关的API汇总

35 阅读7分钟

一、computed

1.什么是computed

computed 表示计算属性,通常用于处理数据,简化书写在模板中的复杂逻辑。使用 computed 可以将数据处理成我们想要的格式,无需在模板中使用复杂冗长的计算表达式。

computed有两个方法,分别是set()和get()。它可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。

2.computed的使用

1)定义路由:

<!--routers/router.ts-->
{
      path: '/test',
      name: 'test',
      component: () => import('~/views/test/index_computed.vue'),
      meta: {
        title: '测试computed'
      }
    }
复制代码

2)编写代码: 示例一:

<!--views/test/index_computed.vue-->
<template>
  <div>{{ reverseMsg }}</div>   //dlrowolleh
</template>

<script setup lang='ts'>
import { ref, reactive, computed } from "vue";    //1.引入computed
const msg = ref("helloworld");
const reverseMsg = computed(() => {
       return msg.value.split("").reverse().join("");    //dlrowolleh
});
复制代码

示例2:

<!--views/test/index_computed.vue-->
<template>
  <div>{{ plus }}</div>      <!-- 8,触发plus1里的set函数 -->  
  <div>{{ count1 }}</div>    <!-- 3,触发plus1里的set函数 -->
  <div>{{ plus1 }}</div>     <!-- 6,触发plus1里的get函数 -->
</template>

<script setup lang='ts'>
// 创建一个只读的计算属性ref对象
const count = ref(4);
const plus = computed(() => {
  return count.value * 2;        //8,此处只读取了count变量里的值
});

// 创建一个可写的计算属性ref对象。默认下触发get函数,set函数会将声明的变量值进行重置
const count1 = ref(4);
const plus1 = computed({
  get: () => count1.value * 2,  //4)打印plus1,再次触发get函数时,count1.value的值是新赋予的3,所以plus1的值为6,而非8
  set: (val) => {              //2)触发plus1里的set函数
    count1.value = val - 1;    //3)count1.value的值由4-->3
  }
});
plus1.value = 4;               //1)将plus1的val值设置为4
</script>
复制代码

3.为什么要有computed

模板中逻辑过重,不易维护,所以使用计算属性computed来简化书写响应式状态的复杂逻辑。

二、Watch

作用:watch侦听器,可侦听响应式变量ref、reactive的数据变化。一旦数据发生变化,就自动执行监听回调。

语法

watch(source, (cur, pre) => {})

参数

watch有三个参数:

第一个参数是侦听器的(source),用于指定要侦听的响应式变量。这个来源可以是一个 ref一个响应式对象或是由以上类型的值组成的数组。

第二个参数是在发生变化时要调用的回调函数。该回调函数有三个参数,分别是cur(新值)、pre(旧值)以及一个回调函数。

第三个可选的参数是一个对象。如果需要深度监听,则deep:true。常见用法有{deep:true}、{ immediate: true }。

示例:当reactive对象嵌套对象时,此刻的deep生效。

const user = reactive({
   name:"tom",
   age:18,
   gender:"male",
   hobby:{
     sing:"唱歌",
     dangce:"跳舞"
   }
})
watch(()=>user.hobby,(cur,pre)=>{
  console.log(cur,pre);
},{deep:true})
复制代码

当watch 监听多个数据时需用中括号[ ]括起来,值与值之间用逗号分隔。

watch的使用:

1.watch侦听ref响应式数据 (侦听单个数据源)

<template>
  <div>
    <p>
      {{ message }}
    </p>
    <button @click="changeMsg">
      改变message
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
const message = ref('helloWorld');
const changeMsg = () => {
  message.value = '你好世界';
};
// 监听 message 变量,如果有发生变化,自动执行后面的回调函数
watch(message, (cur, pre) => {
  changeMsg();
  console.log(cur,pre); // 你好世界 helloWorld
},{deep:true});
</script>
复制代码

2.watch侦听reactive响应式数据中某个属性或某一些数据的变化

<template>
  <div>
    <p>
      {{ user }}       <!-- ['KoKo', 18, 'male']-->
      {{ user.name }}  <!-- KoKo -->
    </p>
    <button @click="changeName">
      修改姓名
    </button>
  </div>
</template>

<script setup lang="ts">
import { reactive, watch } from 'vue';

const user = reactive({
  name: 'tom',
  age: 18,
  gender: 'male'
});
const changeName = () => {
  user.name = 'KoKo';
};
//监听 user 变量里的数据,如果有发生变化,自动执行后面的回调函数
//监听 [user.name, user.age,user.gender] 多个响应式数据,其中一个数据发生变化,就会触发 watch 回调函数
watch([() => user.name, () => user.age, () => user.gender], (cur, pre) => {
  changeName();
  console.log(cur,pre); // ['KoKo', 18, 'male'] ['tom', 18, 'male']
});
</script>
复制代码

3.stop停止监听

<script setup lang="ts">
//如果在组件销毁之前想要停止掉某个监听,可以使用stop停止监听
const stopWatch = watch(source,(cur,pre) => {
      console.log("新值:", cur, "老值:", pre);
}, {deep:true});
// 当不再需要此侦听器时:
stopWatch()

//或使用定时器
//setTimeout(()=>{
    // 停止监听
//    stopWatch()
//  }, 2000);
</script>
复制代码

watch进阶总结使用:

1.watch侦听ref响应式数据

<template>
  <div>test</div>
</template>

<script setup lang='ts'>
import { ref, reactive, watch, onMounted } from 'vue';
// watch侦听ref响应式数据
const c = ref({
  name: 'c',
  prop: 'prop'
});
const d = ref({
  name: 'd',
  prop: 'prop'
});
const c1 = ref({
  name: 'c1',
  prop: {
    name: 'c1',
    prop: 'prop'
  }
});
const d1 = ref({
  name: 'd1',
  prop: {
    name: 'd1',
    prop: 'prop'
  }
});

onMounted(() => {
  // watch侦听ref数据
  c.value.name = 'c-1';
  d.value.name = 'd-1';
  c1.value.prop.name = 'c1-1';
  d1.value.prop.name = 'd1-1';
});

// 1.watch侦听ref定义的一个或多个响应式数据,需要手动开启deep,否则无法侦听
watch(c, (cur, pre) => {
  console.log(cur, pre); // {name: 'c-1', prop: 'prop'} {name: 'c-1', prop: 'prop'}
}, { deep: true });
watch([c, d], (cur, pre) => {
  console.log(cur, pre); // [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}] [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}]
}, { deep: true });
// 2.watch侦听ref定义的一个响应式数据的一个或多个属性-基本数据
watch(() => c.value.name, (cur, pre) => {
  console.log(cur, pre); // c-1 c
});
watch([() => c.value.name, () => d.value.name], (cur, pre) => {
  console.log(cur, pre); // ['c-1', 'd-1'] ['c', 'd']
});
// 3.watch侦听ref定义的一个响应式数据的一个或多个属性-引用数据类型,无法获取preValue,需要手动开启deep,否则无法侦听
watch(() => c1.value.prop, (cur, pre) => {
  console.log(cur, pre); // {name:'c1-1',prop:'prop'}  {name:'c1-1',prop:'prop'}
}, { deep: true });
watch([() => c1.value.prop, () => d1.value.prop], (cur, pre) => {
  console.log(cur, pre); // [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}] [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}]
}, { deep: true });

</script>
复制代码

2.watch侦听reactive响应式数据

<template>
  <div>test</div>
</template>

<script setup lang='ts'>
import { ref, reactive, watch, onMounted } from 'vue';
// watch侦听reactive响应式数据
const c = reactive({
  name: 'c',
  prop: 'prop'
});
const d = reactive({
  name: 'd',
  prop: 'prop'
});
const c1 = reactive({
  name: 'c1',
  prop: {
    name: 'c1',
    prop: 'prop'
  }
});
const d1 = reactive({
  name: 'd1',
  prop: {
    name: 'd1',
    prop: 'prop'
  }
});

onMounted(() => {
  // watch侦听reactive数据
  c.name = 'c-1';
  d.name = 'd-1';
  c1.prop.name = 'c1-1';
  d1.prop.name = 'd1-1';
});

// 1.watch侦听reactive定义的一个或多个响应式数据,会自动开启深度监听但无法获取preValue
watch(c, (cur, pre) => {
  console.log(cur, pre); // {name: 'c-1', prop: 'prop'} {name: 'c-1', prop: 'prop'}
});
watch([c, d], (cur, pre) => {
  console.log(cur, pre); // [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}] [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}]
});
// 2.watch侦听reactive定义的一个响应式数据的一个或多个属性-基本数据
watch(() => c.name, (cur, pre) => {
  console.log(cur, pre); // c-1 c
});
watch([() => c.name, () => d.name], (cur, pre) => {
  console.log(cur, pre); // ['c-1', 'd-1'] ['c', 'd']
});
// 3.watch侦听reactive定义的一个响应式数据的一个或多个属性-引用数据类型,无法获取preValue,需要手动开启deep,否则无法侦听
watch(() => c1.prop, (cur, pre) => {
  console.log(cur, pre); // {name:'c1-1',prop:'prop'}  {name:'c1-1',prop:'prop'}
}, { deep: true });
watch([() => c1.prop, () => d1.prop], (cur, pre) => {
  console.log(cur, pre); // [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}] [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}]
}, { deep: true });

</script>

三、watchEffect

作用:深度监听响应式变量ref、reactive的数据变化。

语法

watchEffect(( ) => { })

参数

watchEffect有两个参数:

第一个参数是在发生变化时要调用的回调函数。

第二个参数是一个可选的选项。有{flush: 'post'}{flush: 'sync'}

watchEffect的使用

watchEffect不需要指明侦听的对象。当侦听的回调中用到哪个属性,就侦听哪个属性。

1.watchEffect侦听ref响应式数据

1)watchEffect侦听ref定义的一个或多个响应式数据,可以获取preValue

2)watchEffect侦听ref定义的一个响应式数据的一个或多个属性-基本数据类型,可以获取preValue

3)watchEffect侦听ref定义的一个响应式数据的一个或多个属性-引用数据类型,可以获取preValue。当没有具体到某个属性时,watchEffect可以侦听引用数据类型的所有属性,也能获取到preValue

<!--text.vue-->
<template>
  <div>test</div>
</template>

<script setup lang='ts'>
import { ref, reactive, watchEffect, onMounted } from 'vue';
// watchEffect侦听reactive响应式数据
// 基本数据类型
const c = ref({
  name: 'c',
  prop: 'prop'
});
const d = ref({
  name: 'd',
  prop: 'prop'
});
// 引用数据类型
const c1 = ref({
  name: 'c1',
  prop: {
    name: 'c1',
    prop: 'prop'
  }
});
const d1 = ref({
  name: 'd1',
  prop: {
    name: 'd1',
    prop: 'prop'
  }
});

onMounted(() => {
  // watchEffect侦听ref数据
  c.value.name = 'c-1';
  d.value.name = 'd-1';
  c1.value.prop.name = 'c1-1';
  d1.value.prop.name = 'd1-1';
});

// 1.watchEffect侦听ref定义的一个或多个响应式数据,可以获取preValue
watchEffect(() => {
  // watchEffect不需要指明侦听的对象。当侦听的回调中用到哪个属性,就侦听哪个属性。
  console.log(c.value); // {name: 'c', prop: 'prop'} {name: 'c-1', prop: 'prop'}
  console.log(c.value.name); // c c-1
});
watchEffect(() => {
  console.log([c.value.name, d.value.name]); // ['c', 'd'] ['c-1', 'd-1']
});
// 2.watchEffect侦听ref定义的一个响应式数据的一个或多个属性-基本数据类型,可以获取preValue
watchEffect(() => {
  console.log(c.value.name); //  c c-1
});
watchEffect(() => {
  console.log([c.value.name, c.value.prop]); //  ['c', 'prop'] ['c-1', 'prop']
});
// 3.watchEffect侦听ref定义的一个响应式数据的一个或多个属性-引用数据类型,可以获取preValue
// 当具体到引用数据类型的某个属性时,能获取preValue
watchEffect(() => {
  console.log(c1.value.prop.name); // c1 c1-1
});
watchEffect(() => {
  console.log([c1.value.prop.name, c1.value.prop.prop]); // ['c1','prop'}] ['c1-1','prop']
});
// 当没有具体到某个属性时,可以侦听引用数据类型的所有属性。能获取preValue
watchEffect(() => {
  console.log(c1.value.prop); // {name: 'c1', prop: 'prop'} {name: 'c1-1', prop: 'prop'}
});
watchEffect(() => {
  console.log([c1.value.prop, d1.value.prop]); // [{name: 'c1-1', prop: 'prop'} {name: 'd1-1', prop: 'prop'}]
});
</script>
复制代码

2.watchEffect侦听reactive响应式数据

1)watchEffect侦听reactive定义的一个或多个响应式数据,可以获取preValue

2)watchEffect侦听reactive定义的一个响应式数据的一个或多个属性-基本数据类型,可以获取preValue

3)watchEffect侦听reactive定义的一个响应式数据的一个或多个属性-引用数据类型,可以获取preValue。当没有具体到某个属性时,watchEffect可以侦听引用数据类型的所有属性,也能获取到preValue

<!--text.vue-->
<template>
  <div>test</div>
</template>

<script setup lang='ts'>
import { ref, reactive, watchEffect, onMounted } from 'vue';
// watchEffect侦听reactive响应式数据
// 基本数据类型
const c = reactive({
  name: 'c',
  prop: 'prop'
});
const d = reactive({
  name: 'd',
  prop: 'prop'
});
// 引用数据类型
const c1 = reactive({
  name: 'c1',
  prop: {
    name: 'c1',
    prop: 'prop'
  }
});
const d1 = reactive({
  name: 'd1',
  prop: {
    name: 'd1',
    prop: 'prop'
  }
});

onMounted(() => {
  // watchEffect侦听reactive数据
  c.name = 'c-1';
  d.name = 'd-1';
  c1.prop.name = 'c1-1';
  d1.prop.name = 'd1-1';
});

// 1.watchEffect侦听reactive定义的一个或多个响应式数据,可以获取preValue
watchEffect(() => {
  // watchEffect不需要指明侦听的对象。当侦听的回调中用到哪个属性,就侦听哪个属性。
  console.log(c); // {name: 'c', prop: 'prop'} {name: 'c-1', prop: 'prop'}
  console.log(c.name); // c c-1
});
watchEffect(() => {
  console.log([c.name, d.name]); // ['c', 'd'] ['c-1', 'd-1']
});
// 2.watchEffect侦听reactive定义的一个响应式数据的一个或多个属性-基本数据类型,可以获取preValue
watchEffect(() => {
  console.log(c.name); //  c c-1
});
watchEffect(() => {
  console.log([c.name, c.prop]); //  ['c', 'prop'] ['c-1', 'prop']
});
// 3.watchEffect侦听reactive定义的一个响应式数据的一个或多个属性-引用数据类型,可以获取preValue
// 当具体到引用数据类型的某个属性时,能获取preValue
watchEffect(() => {
  console.log(c1.prop.name); // c1 c1-1
});
watchEffect(() => {
  console.log([c1.prop.name, c1.prop.prop]); // ['c1','prop'}] ['c1-1','prop']
});
// 当没有具体到某个属性时,它可以侦听引用数据类型的所有属性,能获取preValue
watchEffect(() => {
  console.log(c1.prop); // {name: 'c1', prop: 'prop'} {name: 'c1-1', prop: 'prop'}
});
watchEffect(() => {
  console.log([c1.prop, d1.prop]); // [{name: 'c1-1', prop: 'prop'} {name: 'd1-1', prop: 'prop'}]
});
</script>
复制代码

注意:

1.当watchEffect侦听引用数据类型时,它可以不需要指明具体的某个属性,便能侦听到该对象的所有属性。

2.watchEffect不需要指明侦听的对象。当侦听的回调中用到哪个属性,就侦听哪个属性。

watchEffect的参数

  • flush: 'post':默认情况下,侦听器将在组件渲染之前执行。通过设置 flush: 'post'可以使侦听器延迟到组件渲染之后再执行。
  • flush: 'sync':通过设置flush: 'sync'可以在响应式依赖发生改变时立即触发侦听器。

四、defineProps

作用:父组件向子组件传值,子组件通过defineProps接收该值。

//父组件index.vue
<template>
    <div>parent</div>
    <son :value1="toSonValue" :method1="toSonMethod" />   //声明变量value1,绑定父组件的变量名toSonValue
</template>
    
<script setup lang='ts'>
import { ref } from 'vue';
import son from './son.vue';            
const toSonValue = ref('toSonValue');   
const toSonMethod = () => {             
    console.log('toSonMethod');
}
</script>

//子组件son.vue
<template>
    <div>son</div>
    <div>{{ value1 }}</div>
</template>
    
<script setup lang='ts'>
import { onMounted } from 'vue';

// 父组件往子组件传值value1,method1,其中method1是可选的
const props = defineProps<{      //子组件通过defineProps接收父组件传过来的value1和method1
    value1: string,              
    method1?: () => void         //可选的
}>()
onMounted(() => {
    props.method1!(); // toSonMethod
})
</script>
复制代码

defineProps步骤:

1.新增一个子组件son.vue

2.在父组件通过import son from './son.vue'; 引入子组件

3.在父组件中声明变量toSonValue和toSonMethod

4.在父组件引入的子组件标签中,声明变量value1、method1,来绑定父组件toSonValue、toSonMethod两个变量名

5.在子组件中,声明变量props,该变量通过defineProps接收父组件传过来的value1和method1

五、defineEmits

作用:子组件向父组件传值,通过defineEmits触发父组件的自定义事件进行传值。

//子组件son.vue
<template>
    <div @click="sonClick">son</div>    //1.对son进行事件绑定
</template>
<script setup lang='ts'>
// defineEmits 定义子组件的自定义事件,及参数
const emit = defineEmits<{             //3.emit函数通过defineEmits 定义子组件的事件名和参数类型去触发父组件的自定义事件getSonValue
    (e: 'sonSelfEvent', sonValue: string): void    //返回一个void类型的数据
}>()
const sonClick = () => {                //2.当点击son,将会执行sonClick()
    emit('sonSelfEvent', 'sonValue')    //此处是自定义的事件名及参数
}
</script>

//父组件index.vue
<template>
    <div>parent</div>
    <son @son-self-event="getSonValue" />    //对父组件自定义的getSonValue()进行事件绑定
</template>
    
<script setup lang='ts'>
import son from './son.vue';
const getSonValue = (value: string) => {   //4.触发父组件的自定义事件getSonValue
    console.log(value); // sonValue        //接收子组件传过来的value值并将它打印出来
}
</script>
复制代码

defineEmits步骤:

1.新增一个子组件son.vue

2.在父组件通过import son from './son.vue'; 引入子组件

3.在父组件中声明自定义事件getSonValue

4.在父组件引入的子组件标签中,声明变量son-self-event,来绑定父组件自定义的getSonValue()方法

5.在子组件中,声明变量emit,该变量通过defineEmits定义子组件的事件名和参数类型去触发父组件的自定义事件getSonValue(即:defineEmits接收父组件传过来的getSonValue()方法)

6.在子组件中,声明sonClick方法对son进行事件绑定

7.当点击son,将会执行sonClick方法里,emit函数自定义的事件名及参数

注意:在Vue3中不需要对defineProps、defineEmits进行引入,直接使用即可。

六、vue3的插槽 slot

作用:向一个组件传递内容,可使用插槽。通过插槽来分发内容,即插槽作为分发内容的出口。使用<slot>作为想要插入内容的占位符。

插槽的基本使用:

<!--父组件index.vue-->
<template>
    <div>parent</div>
    <div>
        //匿名插槽
        <son><button>按钮</button></son>    //插入什么内容由父组件决定       
        <son><input type="text"></son>
    </div>
    <div>
        //具名插槽
        <son>
           <!--v-slot只能添加在<template>上-->
           <template v-solt:button><button>按钮</button></template>   //根据定义的名字找到子组件中对应的插槽,然后进行替换
           <template v-solt:input><input type="text"></template>
        </son>
    </div>
</template>

<script setup>
import son from './son.vue';
</script>


<!--子组件son.vue-->
<template>
    <div>son</div>
    <div>
        //匿名插槽使用方式
        <slot></slot>
    </div>
    <div>
        <!--如果有多个值,同时放入组件进行替换时,一起作为替换元素-->
        //具名插槽使用方式
        <slot name="button" />
        <slot name="input" />
    </div>
</template>

<script setup>
import { useSlots } from 'vue'   //引入方式
const slots = useSlots()         //使用方式
</script>
复制代码

在向具名插槽提供内容的时候,可以在一个<template>元素上使用v-slot指令,并以v-slot指令参数的形式提供其名称。

如上例所示<template>元素中的所有内容都将会被传入响应的插槽。

注意:v-slot只能添加在<template>

七、vue的useSlots( )

示例:

<script setup>
import { useSlots } from 'vue'   //引入方式
const slots = useSlots()         //使用方式
</script>
复制代码

实际应用:

<template>
<slot v-if="slotDefault" />
    <div v-else>
      <el-icon v-if="props.type==='image'||props.type==='video'">
        <Plus />
      </el-icon>
      <el-button
        v-else
        type="primary"
      >
        <slot name="icon" />     //匿名插槽
        <div class="el-upload__btn">
          {{ props.btnText }}
        </div>
      </el-button>
    </div>
</template>

<script setup>
import { useSlots } from 'vue'   //引入方式
const slotDefault = !!useSlots().default;  //使用方式
</script>

八、Vue3的生命周期

生命周期的概念理解:vue实例从创建、挂载、更新到销毁这一整个过程叫做生命周期。

类型

选项式API组合式API生命周期钩子(setup)
beforeCreateNot needed
createdNot needed
beforeMountonBeforeMount注册一个钩子,在组件被挂载之前被调用
mountedonMounted注册一个回调函数,在组件挂载完成后执行
beforeUpdateonBeforeUpdate注册一个钩子,在组件即将因为响应式状态变更而更新其 DOM 树之前调用
updatedonUpdated注册一个回调函数,在组件因为响应式状态变更而更新其 DOM 树之后调用
beforeUnmountonBeforeUnmount注册一个钩子,在组件实例被卸载之前调用
unmountedonUnmounted注册一个回调函数,在组件实例被卸载之后调用
  • 钩子:表示一个函数

  • 组合式API(即setup() 内部)调用的生命周期钩子里是没有beforeCreate 和 created函数的。

原因是:

setup选项在组件被创建之前执行,不需要使用this,this不会指向示例。beforeCreate 和 created能做的事情在 setup也能实现。

setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。 

生命周期执行示例

<template>
    <div class="count">
    <!-- 使用v-if来演示卸载页面元素 -->
    <div v-if="isShow"> 
      <el-tag :key="count">数量显示:{{ count }}</el-tag>
      <el-button type="primary" size="small" @click="count++">加 1</el-button>
    </div>
    <el-button type="danger" size="small" @click="isShow = false"
      >卸载</el-button
    >
  </div>
</template>

<script setup lang="ts">
import {ref,beforeCreate,created,onBeforeMount,onMounted,onBeforeUpdated,onUpdated,onBeforeUnmount,onUnmounted} from 'vue';

const count = ref(0);
const isShow = ref(true);

beforeCreate(()=>{   //无调用
    console.log("beforeCreate");   
});
created(()=>{   //无调用
    console.log("created");   
});
onBeforeMount(()=>{  //进入页面时触发调用
    console.log("onBeforeMount开始调用");   
});
onMounted(()=>{   //进入页面时触发调用
    console.log("onMounted开始调用");
    
})
onBeforeUpdated(()=>{  //点击“加1”按钮时调用
    console.log("onBeforeUpdated开始调用");
    
})
onUpdated(() => {
  console.log("onUpdated 开始调用");  //点击“加1”按钮时调用
});

onBeforeUnmount(() => {
  console.log("onBeforeUnmount 开始调用");  //点击“卸载”按钮时触发
});

onUnmounted(() => {
  console.log("onUnmounted 开始调用");  //点击“卸载”按钮时触发
});
</script>

<style></style>

九、nextTick

使用nextTick获取最新的 DOM 元素内容

示例:

<template>
    <div ref="test">{{name}}</div>
    <el-button @click="changeName">按钮</el-button>
</template>

<script setup>
    import { ref, nextTick } from 'vue'
    const name = ref("tom")
    const test = ref(null)  //test.value是个DOM元素

    function changeName(){
        name.value = 'Jack'               //既希望名字发生改变的同时又获取到内容,给div定义一个ref
        console.log(test.value.innerText) //获取DOM元素里的内容,加.innerText即可获取  tom
                                          //当数据发生改变时,页面上视图重新渲染展示出的Jack,但实际上控制台拿到的数据还是tom
    }
    //拿到最新的渲染结果,引入nextTick
    //将函数定义为异步函数
    async function changeName(){
        name.value = 'Jack'
        console.log('before',test.value.innerText) //tom
        await nextTick()                  //在nextTick异步执行完之后,再去打印,便能获取到最新的渲染结果
        console.log('after',test.value.innerText) // Jack
    }
    return { name, test, handleClick }
</script>