Skip to content

组件二次封装模板

封装步骤详解

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>

Released under the MIT License.