Vue3 组件封装

168 阅读1分钟

组件事件和透传 attrs

其实有一个小技巧,就是Vue3默认属性是可以透传的,就是组件里面什么都不写,最后在父组件中使用这个组件的时候,属性会透传到组件中的根元素上; 了解这个特性就可以这样封装组件:

<!-- 组件 -->
<template>
  <el-dialog>
  </el-dialog>
</template>

<!-- 父组件 -->
<template>
  <div>
    <MyComponent 
        v-model="visible"
        width="500px"
    />
  </div>
</template>

通常我们会封装一个Dialog组件来解耦业务,这个时候直接将Dialog作为根元素,然后可以将v-modelwidth属性透传到Dialog组件上;

组件方法

Vue2中,我们可以通过this.$refs.xxx来获取到组件的实例,然后调用组件的方法;

Vue3中,我们可以通过ref来获取到组件的实例,然后调用组件的方法;

对于setup语法,如果需要使用组件的方法,可以使用getCurrentInstance来获取到组件的实例,然后将方法挂载到exposed上;

<template>
  <div>
    <el-input ref="input" />
  </div>
</template>

<script setup>
import { getCurrentInstance, onMounted, ref } from "vue";

const instance = getCurrentInstance();
const input = ref(null);
onMounted(() => {
  Object.values(input.value).forEach((value) => {
    if (typeof value === "function") {
      instance.exposed[value.name] = (...args) => value(...args);
    }
  });
});
</script>

这种方式不太稳定,因为exposedVue3的一个私有属性,不建议使用;

setup语法中如果需要暴露组件的内部方法,需要使用defineExpose来暴露;

<script setup>
// ... 省略其他代码

defineExpose({
  focus: () => {
    input.value.focus();
  },
});
</script>