vue组件的二次封装

用iview、elementUi做项目的时候,经常会遇到组件功能不能满足业务需求的时候,这时候需要在原有的组件上进行二次封装

业务需求

iview的下拉菜单多选是这样子的
vue组件的二次封装_第1张图片
iview是没有全选功能的,现在要加一个全选,反选,取消
vue组件的二次封装_第2张图片

实现方法

新建selects.vue

template部分核心是v-bind="$attrs" 继承组件的所有属性并且赋值,还有v-slot组件插槽

<Select v-model="list" :max-tag-count="2" v-bind="$attrs" style="min-width:250px" @on-change="SelectChange">
    <Option v-if="isShowBtn" disabled value="">
    <Row :gutter="10">
      <Col span="8">
        <Button long size="small" @click.native="SelectBtn('1')">全选Button>
      Col>
      <Col span="8">
        <Button long size="small" @click.native="SelectBtn('2')">反选Button>
      Col>
      <Col span="8">
        <Button long size="small" @click.native="SelectBtn('3')">取消Button>
      Col>
    Row>
     Option>
    <slot v-slot:Option>slot>
  Select>

核心部分是this.$slots.default,能获取到slot里面的值,v-model默认传的是value,监听的事件是input事件,只需要判断父级组件是否穿了多选multiple这个关键字,就可以判断是否显示这几个按钮啦

export default {
  name: "Selects",
  props: {
    value:{
      type:Array,
      default:() => []
    }
  },
  data() {
    return {
      isShowBtn:false,
      list:null
    };
  },
  watch:{
    value:{
      handler:function(e) {
        this.list = e
      },
      immediate: true
    }
  },
  mounted: function () {
    if(this.$attrs['multiple']=="") {
      this.isShowBtn=true
    }
  },
  methods: {
    SelectChange(e) {
      this.$emit("input", this.list );
    },
    SelectBtn(e) {
      if(e==1) {
        // 全选
        this.list =this.$slots.default.map(item => item.key)
      }else if(e==2) {
        // 反选
        let list = this.$slots.default.map(item => item.key)
        this.list =list.filter(item => !this.list.includes(item))
      }else if(e==3) {
        // 取消
        this.ptlist =null
      }
      this.$emit('input', this.ptlist)
    },
  },
};

其他类似的组件都可以用同样的方式封装,思路大概都是这样子的

你可能感兴趣的:(vue)