组件二次封装
以 el-input
为例,二次封装一个 my-input
组件。
需要考虑的三个问题
props
如何穿透- 插槽如何穿透
- 组件方法如何暴露给父组件
实现
思路:使用动态组件,用 h
函数创建组件,并传入 props
和 slots
。
MyInput.vue
<script setup lang="ts">
import { h, getCurrentInstance } from "vue";
import { ElInput, type InputProps } from "element-plus";
const props = defineProps<Partial<InputProps>>();
const vm = getCurrentInstance();
/** 向父组件暴露组件实例,父组件可以调用组件实例的方法 */
function changeRef(inputInstance) {
if (!vm) return;
vm.exposeProxy = vm.exposed = inputInstance || {};
}
</script>
<template>
<div>
<p>二次封装 el-input 的自定义内容</p>
<component :is="h(ElInput, { ...$attrs, ...props, ref: changeRef }, $slots)"></component>
</div>
</template>
Parent.vue
<script setup lang="ts">
import { ref, useTemplateRef } from "vue";
import MyInput from "@/components/MyInput.vue";
import type { InputInstance } from "element-plus";
const msg = ref("hello, world");
const inputRef = useTemplateRef<InputInstance>("input-ref");
setTimeout(() => {
if (!inputRef.value) return;
console.log("🚀🚀🚀 inputRef.value: ", inputRef.value);
inputRef.value.clear();
}, 2000);
</script>
<template>
<main>
<MyInput ref="input-ref" v-model="msg">
<template #append>append</template>
</MyInput>
</main>
</template>