Vue3自定义组件

By | 2022年12月13日

前言

示例基于环境:vue3typescript

在vue中通过自定义组件可以很好的来进行业务封装和复用。一个组件对外来讲主要有以下几个方面

  1. 属性
  2. 方法
  3. 事件

简单示例如下所示

父组件

<script setup lang="ts">
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue'

const helloWorldRef = ref<InstanceType<typeof HelloWorld>>()
function onClick() {
  alert('catch click event')
}

function letSayHello() {
  helloWorldRef.value.sayHello()
}
</script>

<template>
    <input type="button" value="让自定义组件打招呼" @click="letSayHello" />
      <HelloWorld ref="helloWorldRef" msg="Hello, this is a custom component demo"
      @on-click="onClick"
      />
</template>

子组件

<script setup lang="ts">

// 对外定义属性
defineProps({
  msg:String
})

// 对外定义事件
const emits = defineEmits(['on-click'])

// 对外定义方法
defineExpose({
  sayHello
})
function sayHello() {
  alert('hello')
}

function onClick() {
  emits('on-click')
}
</script>

<template>
  <div class="greetings">
    <h1 class="green" @click="onClick">{{ msg }}</h1>
  </div>
</template>

<style scoped>
h1 {
  font-weight: 500;
  font-size: 2.6rem;
}
</style>

详细介绍

  • defineProps 和 defineEmits API,它们将自动地在 <script setup> 中可用
  • defineProps 和 defineEmits 都是只能在 <script setup> 中使用的编译器宏。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉。
  • 传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的作用域。因此,传入的选项不能引用在 setup 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。

对外属性

对外属性是通过 defineProps 方法来完成的,完整用法如下所示

defineProps({
  msg: {
    // 是否必须属性
    require: true,
    // 属性类型
    type: String,
    // 默认值
    default:''
  } 
  
})

对外方法

vue3中自定义组件可以很方便的对外暴露方法,通过 defineExpose 来完成对外方法的声明

defineExpose({
  sayHello
})
function sayHello() {
  alert('hello')
}

父组件调用方式

const helloWorldRef = ref<InstanceType<typeof HelloWorld>>()

....
 helloWorldRef.value.sayHello()

对外定义事件

通过 defineEmits 来声明对外事件

子组件通过下面的方式完成事件的发布

emits('on-click')

父组件通过注册事件来响应事件

function onClick() {
  alert('catch click event')
}
.....
<HelloWorld  @on-click="onClick" />

结语

我们通过 定义属性 、 定义事件、 定义方法 就基本上可以完成对一个自定义组件的封装,可以完成父组件到子组件的数据传递(通过属性),也可以完成子组件到父组件的数据传递(通过事件) 也可以完成子组件能力的对外暴露(通过方法)

示例代码: https://gitee.com/bitlove/vue-demo/tree/main/custom-component