// 插槽透传
// <template v-for="slot in Object.keys($slots)" #[slot]>
// <slot :name="slot"></slot>
// </template>
<!-- 1.jsx形式二次封装element-plus组件库组件 -->
<script lang="jsx">
import { ElInput } from 'element-plus';
import { defineComponent, ref, onMounted, computed } from 'vue';
export default defineComponent({
props: {
...ElInput.props,
newProps: {
type: String,
default: '',
}, // 新的props定义
},
emits: [...Object.keys(ElInput.emits), 'newEmit'],
setup(props, { attrs, emit, slots, expose }) {
const elInputRef = ref(null);
const getProps = computed(() =>
Object.entries(ElInput.emits).reduce((prev, current) => {
const key = `on${current[0].charAt(0).toUpperCase() + current[0].slice(1)}`;
prev[key] = e => {
emit(current[0], e);
}; // 组件中emit事件继承
return prev;
// 需要排除class,onClick属性,防止继承
}, Object.assign({}, props, attrs, { onClick: undefined, class: undefined })),
); // 组件中props继承
const exposeObj = {}; // 组件中method方法继承
onMounted(() => {
Object.entries(elInputRef.value).map(([method, fn]) => {
method && (exposeObj[method] = fn);
});
});
expose(exposeObj);
return () => (
<div>
<el-input {...getProps.value} ref={elInputRef}>
{slots}
</el-input>
</div>
);
},
});
</script>
<!-- 2.template形式二次封装element-plus组件库组件 -->
<template>
<div>
<el-input v-bind="getProps" ref="elInputRef">
<template v-for="(value, name) in getSlots" #[name]>
<slot :name="name" />
</template>
</el-input>
</div>
</template>
<script setup>
import { ElInput } from 'element-plus';
import { ref, onMounted, computed, defineProps, defineExpose, useSlots } from 'vue';
const elInputRef = ref(null);
const emit = defineEmits(Object.keys(ElInput.emits));
const getProps = defineProps(
Object.entries(ElInput.emits).reduce((prev, current) => {
const key = `on${current[0].charAt(0).toUpperCase() + current[0].slice(1)}`;
prev[key] = e => current[1]; // 组件中emit事件继承
return prev;
// 需要排除class,onClick属性,防止继承
}, Object.assign({}, ElInput.props, { onClick: undefined, class: undefined })),
); // 组件中props继承
const getSlots = computed(() => useSlots()); // 组件中slots继承
const exposeObj = {}; // 组件中method方法继承
onMounted(() => {
Object.entries(elInputRef.value).map(([method, fn]) => {
method && (exposeObj[method] = fn);
});
});
defineExpose(exposeObj);
</script>
// 对象动态key实现proxy代理双向绑定
computed: {
getModelValue: {
get() {
const { $emit, modelValue } = this;
return new Proxy(modelValue, {
get(target, key) {
return Reflect.get(target, key);
},
set(target, key, value) {
$emit('update:modelValue', Object.assign(target, { [key]: value }));
return true;
},
});
},
set(newVal) {
this.$emit('update:modelValue', newVal);
},
},
},
console