自定义组件 支持表单校验

在这里插入图片描述


const validatesheet = (rule, value) => {
if ( formState.value.selectItem.length===0) {
return Promise.reject();
}else{
return Promise.resolve();
}
};

const ruleValidate = {

        selectItem: [
    { required:true, message: "请选择表名!",trigger: "change" },
      { validator: validatesheet },
  ],
};
<template>
<div class="mutilselectbg">
      <div class="searchinput" @click.stop="showselect">
      <div class="selecthint">
        <div>已选</div>
        <a-button size="small" @click="clearTagAll()">{{
          selectedList.list.length
            ? "清除" + "(" + selectedList.list.length + ")"
            : ""
        }}</a-button>
      </div>
      <div v-for="item in selectedList.list" :key="item.tableId">
    <a-tooltip  v-if='item.tableName.length>30' :title="item?.dbName+'.'+ item?.tableName">
     <a-tag
      
          closable
          @close="tagBtnCloseFunc(item)"
          @click="tagBtnClickFunc(item)"
          >{{item?.dbName+'.'+  item?.tableName }}</a-tag
        >
    </a-tooltip>
     <a-tag
         v-else
          closable
          @close="tagBtnCloseFunc(item)"
          @click="tagBtnClickFunc(item)"
          >{{item?.dbName+'.'+  item?.tableName }}</a-tag
        >
      </div>
    </div> 
    <div class='selecttable'>
      <div class="search">
        <!--     class="shortinput" -->

           <a-input
          allowClear
          v-model:value.trim="keyword"
          placeholder="请输入表名"
          @change="search({ _fromBar: true, _begin: 0 })"
        ></a-input>

      </div>
      <div class='dialeft'>
        <a-table
          size="small"
          :row-selection="rowSelection"
          :loading="spinning"
          :columns="columns"
          :data-source="dataSource"
          :pagination="false"
          :bordered="bordered"
          :rowKey="(record, index) => record.tableId"
        >
        </a-table>
        <div class="pagination">
          <!-- <span>{{ total }}</span> -->
          <a-pagination
            size="small"
            v-model:current="current"
            v-model:pageSize="pageSize"
            :total="total"
            :showSizeChanger='false'
            :showQuickJumper="true"
            @change="onChange"
          >
          </a-pagination>
        </div>
      </div>
    </div>

  </div>
</template>
<script>
import {
  defineComponent,
  ref,
  watch,
  watchEffect,
  getCurrentInstance,
  reactive,toRefs, nextTick
} from "vue";
import {HTTP_ENUM} from '../utils/enum'
import {Form } from 'ant-design-vue'
export default defineComponent({
  name: "hris-multi-select",
  props: {
    //是否显示边框
    bordered: {
      type: Boolean,
      default: false,
    },
    dbId: Number || String,
    // 选中的id number Array
    selectedItems: Array || Number,
    selectedName: String,
    // 行
    columns: Array,
    //请求地址
    serverId: { type: Function, default: function () {} },
    title: String,
    // 是否显示分页
    pageable: {
      type: Boolean,
      default: true,
    },
  },
  emits: ["update:selectedItems",'change'],
  setup(props, { emit }) {
    const dataSource = ref([]);
    const formItemcontext= Form.useInjectFormItemContext()
    const selectedList = reactive({ list: [] });
    const tableselectedList = reactive({ list: [] });
    const spinning = ref(false);
    const flag = ref(false);
    const pageSize = ref(4);
    const current = ref(1);
    const total = ref(0);
    const keyword = ref();
    const currentInstance = getCurrentInstance();
    const selectArr = ref([]);
    const onChange = (pageNumber) => {
      search();
    };

    const request = (param) => {
      return props.serverId(param);
    };
    // 页面搜索
    const search = (params = {}, fn = (rows) => rows) => {
      const { _begin } = params;
      if (_begin >= 0) {
        current.value = _begin + 1;
      }
      const defaultParams = {
        pageNo: current.value,
        pageSize: pageSize.value,
        keyword: keyword.value,
      };
      spinning.value = true;
      return request(defaultParams)
        .then((res) => {
          let result = res.data;
          if (result.code === HTTP_ENUM.SUCCESS) {
           spinning.value = false;
           dataSource.value = result.data
           total.value = result.total;
            current.value = result.pageNo;
           
          
          }
        })
        .catch((err) => {
          console.log(err);
        })
        .finally(() => {
          spinning.value = false;
        });
    };
    const tagBtnClickFunc = (e) => {
        // let arr= []
        // tableselectedList.list.forEach(
        //     item=> arr.push(item)
        // )
        // return arr
    };
    //     const tagBtnClickFunc = (e) => {
    //     let arr= []
    //     tableselectedList.list.forEach(
    //         item=> arr.push(item)
    //     )
    //     return arr
    // };
    const rowSelection = {
        type:"checkbox",
        hideSelectAll:'true',
         selectedRowKeys:  selectArr,
      onChange: (selectedRowKeys, selectedRows) => {
        // selectArr.value =  selectArr.value.concat(selectedRowKeys)
      },
      onSelect: (record, selected, selectedRows) => {
        if (selected) {
           tableselectedList.list.push(record.tableId);
           let emptyarr=[]
           selectedRows.forEach(element => {
            if(!element){
    
               }else{
               var json ={tableId:element.tableId,tableName:element.tableName,dbName:element.dbName}
               emptyarr.push(json)
               }

           });
           selectedList.list= [...selectedList.list,...emptyarr];
        
          let arr = new Set(tableselectedList.list);
          tableselectedList.list = [...arr]
          let newobj = {};
           selectedList.list =  selectedList.list.reduce((preVal, curVal) => {
            newobj[curVal.tableId]
              ? ""
              : (newobj[curVal.tableId] = preVal.push(curVal));
            return preVal;
          }, []);
          console.log(' selectedList.list==', selectedList.list)

          selectArr.value =  selectArr.value.concat( tableselectedList.list)
          emit("update:selectedItems", selectedList.list);
        }
        if (!selected) {
          let arr = [...selectedList.list];
          arr.splice(arr.findIndex((i) => i.tableId === record.tableId),1);
          selectedList.list = arr;
          let arrlist = [...tableselectedList.list];
          arrlist.splice(arrlist.findIndex((i) => i === record.tableId),1);
          tableselectedList.list = arrlist
          selectArr.value = arrlist
          emit("update:selectedItems", selectedList.list);
        }
      },
      onSelectAll(selected, selectedRows, changeRows) {
      },
    };
    const onSelectChange = (list) => {};
    const showselect = (e) => {
      flag.value = !flag.value;
    };
    const showselectever = (e) => {
      flag.value = true;
    };
    const hideselect = (e) => {
      flag.value = false;
    };
    const { $globalClick } = currentInstance.appContext.config.globalProperties;
    $globalClick(hideselect);
    watch(pageSize, () => {
      search();
    });
        const clearTagAll = () => {
      tableselectedList.list = [];
      selectArr.value = [];
      selectedList.list = [];
      emit("update:selectedItems", selectedList.list);
    };
    const tagBtnCloseFunc = (e) => {
      let arr = [...selectedList.list];
      arr.splice(
        arr.findIndex((i) => i.tableId === e.tableId),
        1
      );
      selectedList.list = arr;
      let arrlist = [...tableselectedList.list];
      arrlist.splice(
        arrlist.findIndex((i) => i === e.employeeNumber),
        1
      );
      tableselectedList.list = arrlist;
      selectArr.value = arrlist;
      emit("update:selectedItems", selectedList.list);
    };
    watch(
      () => tableselectedList.list,
      (newVal) => {
        console.log('tableselectedList.list',newVal)
      },
      {
        immediate: true, // 这个属性是重点啦
        deep: true, // 深度监听的参数
      }
    );
    watch(
      () => props.dbId,
      (newVal) => {
        if (newVal > 0) {
            // current.value=1
            // search();
            // selectedList.list = []
            // tableselectedList.list=[]
            // selectArr.value = []
        }
      },
      {
        immediate: true, // 这个属性是重点啦
        deep: true, // 深度监听的参数
      }
    );
    watch(
      () => props.selectedItems,
      (newVal) => {
          formItemcontext.onFieldChange()
          if (Array.isArray(newVal)&&newVal.length) {
          selectedList.list = newVal;
          let arr = [];
          newVal.forEach((item) => {
            arr.push(item.tableId);
          });
          selectArr.value = arr;
          tableselectedList.list = arr;
        }
      },
      {
        immediate: true, // 这个属性是重点啦
        deep: true, // 深度监听的参数
      }
    );
    watchEffect(() => {
      search();
    });
    return {
         ...toRefs(tableselectedList),
      dataSource,
      keyword,
      onChange,
      total,
      pageSize,
      request,
      current,
      search,
      spinning,
      tagBtnCloseFunc,
      clearTagAll,
      tagBtnClickFunc,
      onSelectChange,
      currentInstance,
      selectedList,
      tableselectedList,
      showselect,
      showselectever,
      flag,
      hideselect,
      rowSelection,
      selectArr
    };
  },
});
</script>
<style lang="less" scoped>
.mutilselectbg {
  display: flex;
  flex-direction: row;

}


.searchinput {
  margin-right: 2px;
  min-width: 40%;
  width: 40%;
  min-height: 200px;
  border: 1px solid #d9d9d9;
  padding: 10px;
  z-index:99;
  overflow-x: auto;
  .selecthint {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    margin-bottom: 4px;
    .hint {
      width: 40px;
    }
  }
}
.selecttable{
    min-width: 60%;
  width: 60%;
}
.search {
  margin-bottom: 16px;
  .shortinput {
    width: 250px !important;
    border-color: #d9d9d9 ;

  }

}


/deep/.ant-form-item-has-error :not(.ant-input-disabled):not(.ant-input-borderless).ant-input, .ant-form-item-has-error :not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper, .ant-form-item-has-error :not(.ant-input-number-affix-wrapper-disabled):not(.ant-input-number-affix-wrapper-borderless).ant-input-number-affix-wrapper, .ant-form-item-has-error :not(.ant-input-disabled):not(.ant-input-borderless).ant-input:hover, .ant-form-item-has-error :not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper:hover, .ant-form-item-has-error :not(.ant-input-number-affix-wrapper-disabled):not(.ant-input-number-affix-wrapper-borderless).ant-input-number-affix-wrapper:hover {

     border-color:  #d9d9d9; 
}

.pagination {
  margin-top: 6px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  width: 500px !important;
}
/deep/ .ant-card-body {
  padding: 2px;

}
.dialeft {
min-height: 200px;

 
}
.selecttag {

  margin-bottom: 4px;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值