element系列 - select 改造

659 阅读1分钟

系列

element系列 - input 改造

element系列 - select 改造

element系列 - form 改造

element系列 - tree 改造

element系列 - pagination 改造

需求

el-input 后面可以append任意元素,需求是 el-select 也能支持后面跟其他元素

image.png

github项目地址

过程

  • mixins 混入钩子
  • new VueVue.extends$mount 获得dom
  • appendChild$el
  • beforeDestroy 中清除 $destroy$offremoveChild
import Vue from "vue";
import { Select } from "element-ui";
const elSelectSuffixHack = {
  install: (Vue) => {
    const selectSuffixHack = {
      props: {
        rightScopedSlots: {
          type: Object,
        },
      },
      mounted() {
        if (this.rightScopedSlots) {
          this._selectSuffixTips = new Vue(this.rightScopedSlots).$mount();
          this.$el.appendChild(this._selectSuffixTips.$el);
        }
      },
      beforeDestroy() {
        const selectSuffixTips = this._selectSuffixTips;
        if (selectSuffixTips) {
          selectSuffixTips.$destroy();
          selectSuffixTips.$off();
          selectSuffixTips.$el.parentNode.removeChild(selectSuffixTips.$el);
        }
      },
    };

    Object.assign(Select, {
      mixins: [...(Select.mixins || []), selectSuffixHack],
    });

    Vue.use(Select);
  },
};
Vue.use(elSelectSuffixHack);

调用

  • 注意,给el-select 扩展了rightScopedSlots属性
<script>
import { Select, Option } from "element-ui";
export default {
  comments: { Select, Option },
  data() {
    return {
      options: [
        {
          value: "选项1",
          label: "黄金糕",
        },
        {
          value: "选项2",
          label: "双皮奶",
        },
      ],
      value: "",
    };
  },
  render() {
    return (
      <Select
        v-model={this.value}
        rightScopedSlots={{
          render() {
            return <span>这是额外添加的内容</span>;
          },
        }}
      >
        {this.options.map((it) => (
          <Option key={it.label} value={it.value} label={it.label}></Option>
        ))}
      </Select>
    );
  },
};
</script>

效果

image.png