组件二次封装模板
封装步骤详解
1. 基础结构搭建
vue
<template>
<div>
<!-- 组件结构 -->
</div>
</template>
- 创建基础的 Vue 组件结构
- 使用
<script setup>
语法糖 - 启用 TypeScript 支持
2. 类型定义
typescript
import { ElInput, type InputProps } from 'element-plus'
type InputInstance = Partial<InputProps> & {
其他属性: string
}
- 导入 Element Plus 的 Input 组件及其类型
- 使用
Partial<InputProps>
继承所有 Input 属性 - 扩展
其他属性
属性用于显示描述文本
3. 属性和实例处理
typescript
const props = defineProps<InputInstance>()
- 使用
defineProps
定义组件属性
4. 组件渲染实现
vue
<div>{{ props.description }}</div>
<component :is="h(ElInput, { ...props, ...$attrs, ref: changeRef }, $slots)"></component>
- 渲染描述文本
- 使用
h
函数动态渲染 ElInput 组件 - 通过扩展运算符传递所有属性
- 处理插槽内容
5. 实例暴露处理
typescript
const changeRef = inputInstence => {
vm.exposed = vm.exposeProxy = inputInstence || {}
}
- 实现 ref 的转发
- 确保内部 ElInput 实例的方法被正确暴露
完整代码
vue
<template>
<div>
<div>{{ props.description }}</div>
<component :is="h(ElInput, { ...props, ...$attrs, ref: changeRef }, $slots)"></component>
</div>
</template>
<script setup lang="ts">
import { h, getCurrentInstance } from 'vue'
import { ElInput, type InputProps } from 'element-plus'
type InputInstance = Partial<InputProps> & {
description: string
}
const props = defineProps<InputInstance>()
const vm = getCurrentInstance()
const changeRef = inputInstence => {
vm.exposed = vm.exposeProxy = inputInstence || {}
}
</script>
<style lang="scss" scoped></style>
使用示例
vue
<template>
<MyInput v-model="value" description="这是一个输入框" placeholder="请输入内容" @change="handleChange" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import MyInput from './MyInput.vue'
const value = ref('')
const handleChange = (val: string) => {
console.log('输入值变化:', val)
}
</script>