聊聊vue3的defineProps、defineEmits、defineExpose

最近在开发中用到了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 属性值,当被点击时可以被访问到。
在这里插入图片描述
结果:
在这里插入图片描述

Vue3定义了一组新的组件选项defineExposedefineEmits,用于支持更好的封装和类型安全。 defineExpose选项允许开发者在子组件中声明需要被父组件访问的实例属性,以便更好的封装子组件细节并提供更好的灵活性。例如,一个表单组件可以将用户输入的信息作为公共属性暴露给父组件,便于父组件进行下一步的业务处理。 在组件内部,我们可以对需要暴露给父组件的属性进行声明: ``` export default { setup() { const formData = reactive({ name: '', age: 18, }) function onSubmit() { // ... } // 定义需要暴露给父组件的属性 defineExpose({ formData, onSubmit, }) return { formData, onSubmit, } }, // ... } ``` 在父组件中,我们可以使用$refs来访问子组件实例属性: ``` <template> <Child ref="child" /> <button @click="submit">提交</button> </template> <script> import { ref } from 'vue' export default { setup() { const child = ref(null) function submit() { // 调用子组件实例方法 child.value.onSubmit() } return { child, submit, } } } </script> ``` 在这个例子中,我们通过在子组件中声明defineExpose选项,将formData和onSubmit暴露给了父组件。而在父组件中,则可以使用$refs来访问这些实例属性。 另外,Vue3还引入了defineEmits选项,用于声明父组件可以触发的自定义事件。这样可以让子组件、指令等更加清晰地定义各自支持的事件类型,避免事件名称冲突,提供更好的类型安全和代码提示。 我们可以在组件内声明需要触发的自定义事件: ``` export default { emits: ['update:modelValue', 'submit'], // ... } ``` 这里我们声明了两个自定义事件update:modelValue和submit,对应的事件处理函数名分别为onUpdateModelValue和onSubmit。在组件内部触发这些自定义事件时,可以直接调用这些处理函数并传入相应的参数: ``` function handleClick() { // 触发自定义事件 emit('submit', formData) } function handleInput(event) { // 触发 update:modelValue 事件 emit('update:modelValue', event.target.value) } ``` 在父组件中,我们可以通过v-on指令监听子组件触发的自定义事件: ``` <template> <Child v-on:submit="onSubmit" v-on:update:modelValue="onUpdateModelValue" /> </template> <script> export default { setup() { function onSubmit(formData) { // ... } function onUpdateModelValue(value) { // ... } return { onSubmit, onUpdateModelValue, } } } </script> ``` 在这个例子中,我们在父组件中通过v-on指令监听子组件的两个自定义事件submit和update:modelValue,并在回调函数中处理这些事件。这样可以让事件传递更加清晰,减少事件名称冲突的可能性。 总之,Vue3的defineExposedefineEmits选项为组件开发带来了更好的封装性和类型安全,有助于提高组件复用性和开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值