vue3 ts defineProps、defineEmits、defineExpose、defineOptions、defineSlots

发布时间:2024年01月10日

请添加图片描述



前言

本章我们来讲解vue3 ts 中 defineProps、defineEmits、defineExpose、defineOptions、defineSlots的使用及作用。
在Vue3中,defineProps、defineEmits、defineExpose、defineOptions、defineSlots是一组新的功能函数,用于定义组件的属性、事件、暴露、选项和插槽。

defineProps:用于定义组件的属性。通过调用该函数,可以声明组件的属性,并且将属性的类型、默认值等信息进行声明。这样,可以在组件内部通过props属性来接收父组件传递的属性值。

defineEmits:用于定义组件的事件。通过调用该函数,可以声明组件所触发的事件,并且将事件的名称、参数等信息进行声明。这样,可以在组件内部通过$emit方法来触发自定义事件。

defineExpose:用于定义组件的暴露。通过调用该函数,可以将组件内部的属性或方法暴露给父组件。这样,父组件可以直接访问和调用子组件的内部属性和方法。

defineOptions:用于定义组件的选项。通过调用该函数,可以定义组件的各种选项,如生命周期钩子函数、组件的配置项等。

defineSlots:用于定义组件的插槽。通过调用该函数,可以在组件中定义插槽,并且将插槽的名称、内容等信息进行声明。这样,可以在组件的模板中通过标签来插入父组件传入的内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、defineProps

defineProps是Vue 3中的一个函数,它的作用是定义组件的属性,类似于Vue 2中的props选项。

使用defineProps可以明确指定组件需要接收的属性以及它们的类型、默认值等。这样一来,在组件的使用处,我们就能清晰地看到它所需要的属性,并且能够按照指定的类型进行验证。

使用场景包括但不限于以下情况:

  • 当需要明确指定组件的属性及其类型、默认值时,可以使用defineProps来定义。
  • 当需要在组件的使用处清晰地看到其需要的属性,并按约定的类型进行验证时,可以使用defineProps来定义。
  • 当组件的属性较多且复杂时,使用defineProps可以更好地管理和组织属性的定义。

使用场景示例代码如下:

<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
  </div>
</template>

<script setup>
import { defineProps } from 'vue';

defineProps({
  title: String,
  description: {
    type: String,
    default: 'This is the component description.',
  },
});
</script>

在上面的示例中,我们使用了 <script setup> 语法糖来编写组件的逻辑部分。在 defineProps 中我们定义了两个属性:titledescriptiontitle 的类型被指定为 String,而 description 的类型被指定为 String,并且还定义了一个默认值。

在模板部分,我们直接使用 {{ title }}{{ description }} 来输出 props 的值。

这样,当我们在父组件中使用这个组件时,就可以通过给 titledescription 属性传入不同的值来动态渲染组件的内容了。

<template>
  <div>
    <CustomComponent title="This is a custom title" />
    <CustomComponent title="Another title" description="This is another description" />
  </div>
</template>

<script>
import CustomComponent from './CustomComponent.vue';

export default {
  components: {
    CustomComponent,
  },
};
</script>

在父组件中,我们将 CustomComponent 引入,并通过 titledescription 属性传入不同的值。根据传入的值,CustomComponent 会渲染不同的标题和描述。

二、defineEmits

在Vue3中,defineEmits是一个用于定义组件的事件的函数。它允许你明确列出组件可以触发的事件,使得组件的使用者更容易理解和使用。

使用<script setup>语法糖,你可以在组件的顶层中使用defineEmits函数来定义事件。

下面是一个示例代码,展示了如何使用defineEmits<script setup>来定义组件的事件并在组件中触发这些事件:

<template>
  <button @click="onButtonClick">Click me!</button>
</template>

<script setup>
import { defineEmits } from 'vue';

// 定义组件的事件
const emits = defineEmits(['buttonClick']);

// 触发事件
const onButtonClick = () => {
  emits('buttonClick', 'Button clicked!');
};
</script>

在上面的示例中,我们通过调用defineEmits函数来定义了一个名为buttonClick的事件。然后,我们在onButtonClick函数中使用emits来触发这个事件,并传递了一个字符串参数作为事件的payload。

通过使用defineEmits函数,我们明确了组件可以触发的事件,使得组件使用者能够更容易地了解和使用这些事件。另外,这也提供了一种类型安全的方式来检查事件触发的参数类型。

三、defineExpose

在 Vue 3 中,defineExpose 函数用于在组合式 API组件中向父组件暴露方法或属性。它的作用是将一些内部方法或属性暴露给组件外部,使得父组件可以直接访问到。

使用 defineExpose 的场景是,当我们在组合式 API 组件内部定义了一些需要在父组件中使用的方法或属性时,可以通过 defineExpose 将它们暴露出去。

以下是一个使用 defineExpose 的示例代码:

<template>
  <div>
    <button @click="increaseCounter">Increase Counter</button>
    <p>Counter: {{ counter }}</p>
  </div>
</template>

<script setup>
import { ref, defineExpose } from 'vue';

const counter = ref(0);

const increaseCounter = () => {
  counter.value += 1;
};

defineExpose({
  counter, // 将 counter 暴露给父组件
  increaseCounter, // 将 increaseCounter 方法暴露给父组件
});
</script>

在上面的代码中,我们定义了一个名为 counter 的响应式变量,并通过 increaseCounter 方法将其递增。然后,通过 defineExpose 函数将 counter 变量和 increaseCounter 方法暴露给父组件。

在父组件中,我们可以通过使用组合式 API 组件的 <script setup> 中的 <script> 块的 expose 属性来访问这些暴露出的属性和方法:

<template>
  <div>
    <ChildComponent ref="childRef" />
    <button @click="increaseChildCounter">Increase Child Counter</button>
    <p>Child Counter: {{ childCounter }}</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';

const childRef = ref(null);
let childCounter = null;

onMounted(() => {
  childCounter = childRef.value.counter; // 访问子组件暴露的 counter 变量
});

const increaseChildCounter = () => {
  childRef.value.increaseCounter(); // 调用子组件暴露的 increaseCounter 方法
};
</script>

在父组件中,我们通过 <ChildComponent ref="childRef" /> 的方式引入子组件,并使用 ref 引用子组件实例。然后我们可以通过 childRef.value.counter 访问到子组件暴露的 counter 变量,并通过 childRef.value.increaseCounter() 调用子组件暴露的 increaseCounter 方法。

四、defineOptions( Vue3.3 新特性)

defineOptions 这个宏可以用来直接在 script setup 中声明组件选项,而不必使用单独的 script 块。用来定义 Options API 的选项。

以下是一个使用 defineOptions 的示例代码:
创建父级ParentLevel.vue文件

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

<script setup>
import SubLevel from './SubLevel.vue'
console.log('SubLevel', SubLevel);
</script>

创建子级SubLevel.vue文件

<template>
    <div>子级</div>
</template>

<script setup>
defineOptions({
    name: 'subLevel',
    test: '测试'
})
</script>

在上面的代码中,我们创建了一个父级ParentLevel.vue文件,并在文件中引入了SubLevel .vue,并使用console.log 打印出SubLevel 的信息。在子级SubLevel.vue文件,使用了defineOptions宏 内容为 { name: ‘subLevel’, test: ‘测试’}。
在这里插入图片描述
而在vue3.3之前 是无法暴露出自定义的数据的

五、defineSlots(Vue3.3 新特性)

Vue 3.3 新增了 defineSlots 宏。我们可以使用 defineSlots 自己定义插槽的类型。这个宏在简单的组件中几乎用不到,但对于一些复杂的组件非常有用,尤其是这个特性与泛型组件一起使用。或是在 Volar 无法正确地推测出类型时,我们可以手动指定。

<script setup lang="ts">
const slots = defineSlots<{
  	// default 是插槽名称
    // 函数的第一个TS对象类型参数是插槽期望接收的 props 的TS类型
    // 返回值类型目前被忽略,可以是 any,未来可能利用它来检查插槽内容
  default(props: { test: number}): any
}>()
</script>
文章来源:https://blog.csdn.net/weixin_49014702/article/details/135508909
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。