SOURCE

// 插槽透传
// <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 命令行工具 X clear

                    
>
console