聊聊vue3的definePropsdefineEmitsdefineExpose

Posted super舒楠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊vue3的definePropsdefineEmitsdefineExpose相关的知识,希望对你有一定的参考价值。

最近在开发中用到了vue3的defineProps、defineEmits和defineExpose,感觉发现新大陆一般,所以利用闲碎时间对这三个方法做个总结。

defineProps

const props = defineProps<
   foo: String,
   bar?: Number
>()

defineProps 是vue3的写法并且是一个仅 <script setup> 中可用的编译宏命令,并不需要显式地导入;在vue3的非语法糖setup和在vue2中的写法是 props
defineProps的大部分用法是进行父子组件传值。

注意:defineProps() 宏中的参数不可以访问 <script setup>中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。

实例:父组件传值给子组件
父组件通过将值传递给子组件,子组件通过defineProps进行接收,子组件点击后将接收到的值 alert 出来
结果:

defineEmits

const emit = defineEmits<
(e: 'submit', num: number): void
>()

defineEmitsdefineProps 一样也是仅用于 <script setup> ,并且不需要导入;在vue3的非语法糖setup中的写法是 emits
defineEmits 的不同点在于,组件要触发的事件可以显式地通过 defineEmits() 宏来声明。

注意:如果一个原生事件的名字 (例如 click) 被定义在 emits 选项中,则监听器只会监听组件触发的 click 事件而不会再响应原生的 click 事件。

实例:子组件触发父组件的的事件,并且进行传值。
子组件通过触发父组件的 submit 事件,并且将参数6666传递到父组件。

结果:

defineExpose

const isShow = ref<boo(false)
defineExpose( // 宏来显示指定组件中属性暴露出去
  isShow,
);

在使用 <script setup> 的时候,组件的实例是默认关闭的不能够通过模板引用或者$parent 进行被访问的。

通过 defineExpose 可宏来显式指定在 <script setup> 组件中要暴露出去的属性。

实例:向外暴露属性,被使用。
组件向外暴露了 isShow 属性值,当被点击时可以被访问到。

结果:

聊聊VUE中的nextTick

在谈nextTick之前,先要说明一件事,可能在我们平时使用vue时并没有关注到,事实上,vue执行的DOM更新是异步的

举个栗子:

 <template>
     <div class="con">{{msg}}</div>
 <template>
 <script>
     export default{
         data(){
             return{
                 msg:0,
             }
         },
         mounted(){
             this.msg = 1000;                    
             console.log(document.querySelector(".con").innerHTML);
         }
     }
</script>    

 

此时控制台打印的是数值是0;这时候如果你将代码改一下:

 

<template>
     <div class="con">{{msg}}</div>
 <template>
 <script>
     export default{
         data(){
             return{
                 msg:0,
             }
         },
         mounted(){
             this.msg = 1000;                    
             setTimeout(function(){
                 console.log(document.querySelector(".con").innerHTML); 
             },0)
         }
     }
</script>    

 

这时,控制台打印的数值为1000;这也就说明,vue的DOM更新是异步的,官网上是这样描述的:

可能你还没有注意到,Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会一次推入到队列中。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。

 

而这次要谈的nextTick,其实就是上面setTimeout,目的也很简单,就是为了让DOM更新后立即执行一个回调函数:

 

<template>
     <div class="con">{{msg}}</div>
 <template>
 <script>
     export default{
         data(){
             return{
                 msg:0,
             }
         },
         mounted(){
             this.msg = 1000;                    
             this.nextTick(() =>{
                 console.log(document.querySelector(".con").innerHTML); 
             })
         }
     }
</script>    

 

控制台也会打印1000!

以上是关于聊聊vue3的definePropsdefineEmitsdefineExpose的主要内容,如果未能解决你的问题,请参考以下文章

VUE3 之 表单元素

vue3.0 beta 编译优化研究

vue3.0 beta 编译优化研究

vue3.0(双向绑定)源码分析

VUE3 之 计算属性与侦听器

vue3.x新特性之setup函数,看完就会用了