likes
comments
collection
share

升级版多选框

作者站长头像
站长
· 阅读数 40

前言:

大家好,这里是藤原豆腐店,相信大家都有用过ElementUI的CheckBox多选框和Select选择器,如果是有层级的多项框,这两个就不是那么好用了

升级版多选框升级版多选框

下面这个升级版多项框,整合了Select和CheckBox,同时支持搜索,二级标签多选和已选列表展示等功能

升级版多选框

主体结构

<template>
  <div>
    <el-popover
      :popper-class="`select-tag-popover ${popperClass}`"
      placement="bottom-start"
      title=""
      width="570"
      trigger="click"
      @show="toShowPopover"
      @hide="toHidePopover"
      @after-leave="toHideAfterPopover">
      <!-- 标签选项列表 -->
      <div :class="['select-vertical-wrap', `vertical-${themeColor}`]">
        <!--	左半边  -->
        <div class="left-wrap">
          <!-- 操作区域 -->
          <div class="operate-area"></div>
          <!-- 选择标签区域 -->
          <div class="group-area"></div>
        </div>
        <!--	右半边  -->
        <div class="left-wrap">
          <!-- 操作区域 -->
          <div class="operate-area"></div>
          <!-- 选择标签区域 -->
          <div class="group-area"></div>
          <!-- 垂直方向:已选标签 -->
          <div class="selected-area"></div>
        </div>
      </div>
      <!-- 下拉选择框 -->
      <template slot="reference">
        <div :class="['select-horizontal-wrap', `horizontal-${themeColor}`, isShowSelect ? 'horizontal-click' : '']" @click="selectEmit">
          <div class="main-wrap"></div>
          <div class="icon-wrap"></div>
        </div>
      </template>
    </el-popover>
  </div>
</template>

el-popover作为标签选择器的容器

通过popper-class配置popover样式

.select-tag-popover {
  padding: 0;
  /deep/ .el-checkbox {
    display: flex;
    align-items: center;
  }
  /deep/ .el-checkbox .el-checkbox__input.is-checked .el-checkbox__inner {
    background-color: #4471e1;
    border-color: #4471e1;
    &::after {
      border-color: #fff;
    }
  }
  /deep/ .el-checkbox .el-checkbox__input.is-indeterminate .el-checkbox__inner {
    background-color: #4471e1;
    border-color: #4471e1;
    &::after {
      border-color: #fff;
    }
  }
}

同时可以通过props项:popperClass,用于定制标签显示框的样式

popperClass: { // popperClass
  type: String,
  default: ''
},

el-popover的几个内置方法

// 显示popover触发
toShowPopover() {
  this.isShowSelect = true
  this.$emit('toShowPopover')
},
// 隐藏popover触发
toHidePopover() {
  this.isShowSelect = false
  this.$emit('toHidePopover')
},
// 隐藏popover动画之后触发
toHideAfterPopover() {
  this.searchWord = '' //清空关键词
  this.renderList = this.groupList	//将数据添加渲染列表
  this.$emit('toHideAfterPopover')
},

isShowSelect用于控制Popover显示的效果

// 水平方向选择框-点击效果
.horizontal-click {
  border: 1px solid #409EFF;
}
.icon-wrap {
  width: 35px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-left: 1px solid #DCDFE6;
  .arrow{
    transition: transform .3s,-webkit-transform .3s;
    transform:rotateZ(0deg);
  }
  .up{
    transform:rotateZ(-180deg) !important;
  }
}

标签选择器主体

<!-- 标签选项列表 -->
<div :class="['select-vertical-wrap', `vertical-${themeColor}`]">
  <div class="left-wrap">
    <!-- 操作区域 -->
    <div class="operate-area">
      <!-- 搜索 -->
      <el-input
        class="search-wrap"
        placeholder="搜索"
        v-model="searchWord"
        @input="onSearchInput"
        @keyup.enter.native="toSearch">
        <i slot="suffix" class="el-input__icon el-icon-search" @click="toSearch"></i>
      </el-input>
      <div class="checked-all-wrap">
        <!-- 全选 -->
        <el-checkbox :indeterminate="isI" :value="isAll" @change="handleCheckAllGroupChange">全选</el-checkbox>
        <!-- 标签总数 -->
        <div class="total-tag">共{{total}}项</div>
      </div>
    </div>
    <!-- 选择标签区域 -->
    <div class="group-area">
      <div class="group-cell" v-for="(group, index) in renderList" :key="index">
        <div class="group-top">
          <!-- 收起、展开标签组 -->
          <img
            class="icon-put"
            :class="{'right': group.isPut}"
            :src="`xx/images/icon-down.png`"
            @click="toChangePut(group)"
            />
          <!-- 标签组名称 -->
          <el-checkbox :indeterminate="group.isI" :value="group.isAll" @change="handleCheckAllChange(group, $event)">
            {{group.tagGroupName}}
          </el-checkbox>
        </div>
        <!-- 组下标签列表 -->
        <div class="group-content" :class="{'hidden': group.isPut}" v-for="(tag, n) in group.tags" :key="n">
          <el-checkbox :value="tag.isSelected" @change="handleCheckChange(group, tag, $event)" :disabled="!!tag.disabled">
            <div class="tag-name">{{tag.name}}</div>
          </el-checkbox>
        </div>
      </div>
    </div>
  </div>
  <div class="right-wrap">
    <!-- 操作区域 -->
    <div class="operate-area">
      <!-- 已选项 -->
      <div class="count">
        已选
        <div class="blue">{{selectedList.length}}</div>

      </div>
      <!-- 清空 -->
      <div class="delete" @click="toDeleteAll">清空</div>
    </div>
    <!-- 垂直方向:已选标签 -->
    <div class="selected-area">
      <div class="selected-cell" v-for="(tag, k) in selectedList" :key="k">{{tag.name}}</div>
    </div>
  </div>
</div>
// 垂直方向选择框-选项列表
.select-vertical-wrap {
  display: flex;
  height: 100%;
  // height: 360px;
  // overflow: hidden;
  /deep/ .el-checkbox {
    display: flex;
    align-items: center;
  }
  /deep/ .el-checkbox, .el-checkbox__input{
    white-space: normal !important; 
  }
  /deep/ .el-checkbox .el-checkbox__input.is-checked .el-checkbox__inner {
    background-color: #4471e1;
    border-color: #4471e1;
    &::after {
      border-color: #fff;
    }
  }
  /deep/ .el-checkbox .el-checkbox__input.is-indeterminate .el-checkbox__inner {
    background-color: #4471e1;
    border-color: #4471e1;
    &::after {
      border-color: #fff;
    }
    &::before {
      background-color: #fff;
    }
  }
  .disable{
    cursor: not-allowed;
  }
}
data() {
  return {
    renderList: [], // 渲染列表
    groupList: [], // 标签组列表
    searchList: [], // 搜索列表
    isShowSelect: false,
    searchWord: '', // 搜索关键词
    isI: false, // 是否显示 -
    isAll: false, // 是否全选
  }
},

左半边的核心功能

样式实现

.left-wrap {
  width: 50%;
  border-right: 1px solid #ebebeb;
  /* 操作区域 */
  .operate-area {
    padding: 10px 10px 0;
    border-bottom: 1px solid #ebebeb;
    .search-wrap {
      .el-icon-search {
        cursor: pointer;
      }
    }
    .checked-all-wrap {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 15px 0;
      .total-tag {
        font-size: 12px;
        color: #999;
      }
    }
  }
  /* 选择标签区域 */
  .group-area {
    max-height: 320px;
    overflow-x: hidden;
    overflow-y: scroll;
    padding: 15px 0;
    @include scrollbarColor(#ddd);
    .group-cell {
      display: flex;
      flex-direction: column;
      margin-bottom: 15px;
      &:last-child {
        margin-bottom: 0;
      }
      .group-top {
        display: flex;
        align-items: center;
        padding: 0 10px;
        .icon-put {
          cursor: pointer;
          margin-right: 10px;
          margin-bottom: 2px;
        }
        .right {
          transform: rotate(-90deg)
        }
        .up {
          margin-bottom: 5px;
        }
      }
      .group-content {
        display: flex;
        align-items: center;
        padding: 10px 3px 0 56px;
        .tag-name {
          max-width: 210px;
          font-size: 14px;
          color: #333;
          // text-overflow: ellipsis;
          // white-space: nowrap;
          // overflow: hidden;
        }
      }
      .hidden {
        height: 0;
        display: none;
      }
    }
  }
}

勾选

勾选全选

 // 监听 全选所有
handleCheckAllGroupChange(val) {
  this.renderList.forEach(g => {
    g.isAll = val
    g.isI = false
    // 选择所有未禁用的父标签
    g.tags && g.tags.forEach(t => {
      if(!t.disabled){
        t.isSelected = val
      }
    })
  });
},

勾选标签组

// 监听 选择标签组
handleCheckAllChange(group, val) {
  group.isI = false //控制全选框的样式
  group.isAll = val	//标签组选择设置为true
  // 存在子标签的话
  group.tags && group.tags.forEach(t => {
    // 选择当前标签组所有未禁用的子标签
    if(!t.disabled){
      t.isSelected = val
    }
  })
},

勾选单个标签

// 监听 选择标签
handleCheckChange(group, tag, val) {
  // 更改当前标签状态
  tag.isSelected = val
  // 判断当前标签组是否已全选
  group.isAll = group.tags && group.tags.filter(m => !m.disabled).every(m => m.isSelected)
  // 判断全选框的样式
  group.isI = !!(group.tags && group.tags.filter(m => !m.disabled).some(m => m.isSelected) && !group.isAll)
},

搜索

升级版多选框

<el-input
  class="search-wrap"
  placeholder="搜索"
  v-model="searchWord"
  @input="onSearchInput"
  @keyup.enter.native="toSearch">
  <i slot="suffix" class="el-input__icon el-icon-search" @click="toSearch"></i>
</el-input>
// 搜索输入值改变回调
onSearchInput(val) {
  if (!val) {
    // 重置标签组数据
    this.renderList = this.groupList
  }
},
// 搜索
toSearch() {
  if (!this.groupList.length) return
  let searchList = []
  this.groupList.forEach(g => {
    // 搜索标签组
    const isMacthGroup = g.tagGroupName && g.tagGroupName.includes(this.searchWord)
    // 搜索标签项
    const isMacthTag = g.tags && g.tags.some(t => t.name.includes(this.searchWord))
    // 只要匹配到就显示整个标签组
    if (isMacthGroup || isMacthTag) {
      g.isPut = false
      searchList.push(g)
    }
  });
  // 更新标签组列表
  this.renderList = searchList
},

右半边的核心功能

样式实现

 .right-wrap {
    width: 50%;
   /* 操作区域 */
    .operate-area {
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-bottom: 1px solid #ebebeb;
      padding: 10px 15px;
      .count {
        display: flex;
        align-items: center;
        font-size: 14px;
        color: #333;
        .blue {
          font-size: 14px;
          color: #2C6FEA;
        }
      }
      .delete {
        font-size: 14px;
        color: #2C6FEA;
        cursor: pointer;
        &:active {
          opacity: 0.7;
        }
      }
    }
   /*  垂直方向:已选标签  */
    .selected-area {
      max-height: 400px;
      // max-height: 321px;
      display: flex;
      flex-direction: column;
      box-sizing: border-box;
      overflow-y: scroll;
      overflow-x: hidden;
      padding: 15px;
      @include scrollbarColor(#ddd);
      .selected-cell {
        font-size: 14px;
        color: #333;
        margin-bottom: 15px;
        &:last-child {
          margin-bottom: 0;
        }
      }
    }
  }

清空已选择

 // 清空
toDeleteAll() {
  this.groupList.forEach(g => {
    g.isI = false
    g.isAll = false
    g.tags && g.tags.forEach(t => {
      t.isSelected = false
    })
  })
}

这里通过props配置项也可以执行清空操作

isClear: { // 是否清空
  type: Boolean,
  default: false
},
watch: {
  isClear(nVal) {
      this.toDeleteAll()
  },
},

数据展示

显示已选择列表

<!-- 垂直方向:已选标签 -->
<div class="selected-area">
  <div class="selected-cell" v-for="(tag, k) in selectedList" :key="k">{{tag.name}}</div>
</div>
computed:{
// 已选择的标签列表
  selectedList() {
    // 处理全选框样式
    this.handleAllBtnStyle()
    // 已选对象列表
    const selectedList = this.groupList.reduce(
      (pre, cur) => 
      cur.tags && cur.tags.length ? pre.concat(cur.tags.filter(m => m.isSelected)) : pre, 
      []
    )
     // 已选id列表
    const outPutIdList = selectedList.map(m => m.id)
    this.$emit('toGetTagIdList', outPutIdList)
    return selectedList
  }
}
 // 处理全选按钮样式
handleAllBtnStyle() {
  let leftSelectedCount = 0 // 左侧列表中已选个数(包括搜索+未搜索情况下)
  let leftDisabledCount = 0 // 左侧列表中已禁用个数(包括搜索+未搜索情况下)
  // 遍历列表
  this.renderList.forEach(g => {
    if (g.tags && g.tags.length) {
      const isSelectedList = g.tags.filter(t => {
        // 统计已禁用的个数
        leftDisabledCount += t.disabled ? 1 : 0
        // 返回已选的
        return t.isSelected
      })
      leftSelectedCount += isSelectedList.length
    }
  })
  // 判断是否全选(已选的 = 总数-已禁用的)
  this.isAll = !!(leftSelectedCount && leftSelectedCount === (this.total - leftDisabledCount))
  this.isI = !!(leftSelectedCount && leftSelectedCount < (this.total - leftDisabledCount))
},

select显示框

此处模仿el-select的多选样式

升级版多选框

<template slot="reference">
  <!-- 下拉选择框 -->
  <div :class="['select-horizontal-wrap', `horizontal-${themeColor}`, isShowSelect ? 'horizontal-click' : '']" @click="selectEmit">
    <div class="main-wrap">
      <!-- 水平方向:已选标签 -->
      <div class="list-wrap" v-if="selectedList.length">
        <div class="list-cell" v-for="(item, index) in selectedList" :key="index">
          <div class="cell-name">{{item.name}}</div>
          <img class="icon-delete" src="@/images/icon-close-1.png" @click.stop="toDelete(item)"/>
        </div>
      </div>
      <!-- 占位符 -->
      <div class="place-name" v-else>请选择</div>
      <!-- 已选个数 -->
      <div class="count" v-if="selectedList.length">{{selectedList.length}}</div>
    </div>
    <div class="icon-wrap">
      <img :class="['arrow',{'up':isShowSelect}]" src="@/images/icon-down.png"  />
    </div>
  </div>
</template>

样式实现

// 水平方向选择框-选项列表
.select-horizontal-wrap {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 100%;
  border: 1px solid #DCDFE6;
  box-sizing: border-box;
  background: #fff;
  cursor: pointer;
  border-radius: 4px;
  .main-wrap {
    min-width: 0;
    height: 100%;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-right: 10px;
    /* 列表框 */
    .list-wrap {
      min-width: 0;
      height: calc(100% - 2px);
      display: flex;
      align-items: center;
      overflow-x: scroll;
      flex: 1;
      // 隐藏滚动条及其轨道
      scrollbar-color: transparent transparent;
      scrollbar-track-color: transparent;
      -ms-scrollbar-track-color: transparent;
      scrollbar-width: none;
      // 隐藏滚动条(适配多个浏览器)
      &::-webkit-scrollbar {
        height: 0;
        display: none;
      }
      &::-moz-scrollbar {
        display: none;
      }
      &::-ms-scrollbar {
        display: none;
      }
      &::-o-scrollbar {
        display: none;
      }
      .list-cell {
        height: 100%;
        display: flex;
        align-items: center;
        background: #f7f8f9;
        border-left: 1px solid #DCDFE6;
        border-right: 1px solid #DCDFE6;
        box-sizing: border-box;
        border-radius: 2px;
        flex-shrink: 0;
        margin-right: 6px;
        padding: 4px 7px;
        &:first-child {
          border-left: none;
        }
        .cell-name {
          font-size: 12px;
          color: #333;
        }
        .icon-delete {
          width: 12px;
          height: 12px;
          margin-left: 5px;
          cursor: pointer;
          &:active {
            opacity: 0.7;
          }
        }
      }
    }
    .place-name {
      font-size: 14px;
      color: #c0c4cc;
      margin-left: 10px;
    }
    .count {
      width: 24px;
      height: 24px;
      background: #f7f8f9;
      border-radius: 50%;
      font-size: 12px;
      color: #333;
      line-height: 24px;
      text-align: center;
      margin-left: 10px;
    }
  }
  /* 下拉图标 */
  .icon-wrap {
    width: 35px;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    border-left: 1px solid #DCDFE6;
    .arrow{
      transition: transform .3s,-webkit-transform .3s;
      transform:rotateZ(0deg);
    }
    .up{
      transform:rotateZ(-180deg) !important;
    }
  }
}
// 水平方向选择框-点击效果
.horizontal-click {
  border: 1px solid #409EFF;
}
// 水平方向选择框-蓝色主题
.horizontal-blue {
  background: #1e2846;
  border: 1px solid #39415d;
  /deep/ .main-wrap {
    .place-name {
      color: #434D6B;
      font-size: 14px;
    }
    .list-wrap {
      height: calc(100% - 8px);
      padding-left: 5px;
      .list-cell {
        background: #27314f;
        border: none;
        border-radius: 4px;
        padding: 5px 7px;
        .cell-name {
          line-height: 1;
          color: #fff;
        }
        .icon-delete {
          width: 10px;
          height: 10px;
        }
      }
    }
    .count {
      color: #A4A8B4;
      background: #27304F;
      margin-left: 5px;
    }
  }
  .icon-wrap {
    border-left: 1px solid #434D6B;
  }
}

删除单个标签项

// 删除
toDelete(item) {
  const groupIndex = item.groupIndex
  const group = this.groupList[groupIndex]
  item.isSelected = false
  group.isAll = group.tags.every(m => m.isSelected)
  group.isI = !!(group.tags.some(m => m.isSelected) && !group.isAll)
  this.$emit('toDelete', item)
},

点击下拉框

// 点击下拉框
selectEmit(){
  this.$emit('visibleChange')
}

数据请求

通过type跟tagsParams传入接口请求参数,通过watch监听触发对应的方法

这里也可以改为在外面触发接口,传数据进来

props: {
    type: { // 下拉标签列表参数:type:视频:1,音频:2,文案:3,图片
      type: Number,
      default: 1
    },
    tagsParams: { // 下拉标签列表:请求体
      type: Object,
      default: () => ({})
    },
}
 watch: {
    type: {
      handler(nVal) {
        this.getList()
      },
      immediate: true
    },
    tagsParams: {
      handler(nVal) {
        this.getList()
      },
      deep: true,
      // immediate: true
    },
 }
// 获取标签列表
async getList() {
  try {
    this.getPopperTagList()
  } catch (error) {
    console.error(error)
    this.$message.error(error)
  }
},
// 获取下拉标签列表请求参数
getTagsParams() {
  let params = {}
  if (this.tagsParams && Object.keys(this.tagsParams).length) {
    params = this.tagsParams
  } else {
    params = {
      scope: this.type
    }
  }
  return params
},
// 获取下拉标签列表
async getPopperTagList() {
  try {
    const params = this.getTagsParams()
    const res = await getTagList(params)
    if (res && res.data && res.data.code === 0) {
      let { data } = res.data
      this.handleSelectList(data)
    } else {
      this.$message.error(res && res.data && res.data.msg)
    }
  } catch (error) {
    console.error(error)
    this.$message.error(error)
  }
},

回显标签组的数据

ids: { // 传入标签组id列表
  type: Array,
  default: () => ([])
},
watch:{
  ids: {
    handler(nVal) {
      this.echoIdList = nVal //存储传入标签组id
      this.getList()
    },
    deep: true,
    immediate: true
  },
}

对标签组id列表进行匹配

// 获取 { groupId: [id] } 回显标签对象
getEchoTagObj(echoIds = [], tagsList = []) {
  let idObj = {}
  if (!echoIds.length) return idObj
  // 回显ids是组id的对象数组
  const isExistGroupId = echoIds.some(m => m.tagGroupId)
  // 回显ids是标签id的数组
  const isExistTagId = !isExistGroupId && echoIds.some(m => (m !== null && Number(m) > 0))
  if (isExistGroupId) {
    idObj = echoIds.reduce((pre, cur) => {
      let group = { ...pre }
      if (cur.tagGroupId && cur.tags && cur.tags.length) {
        // 将只存有id的映射数组传给group
        group[cur.tagGroupId] = cur.tags.map(m => m.id)
      }
      return group
    }, {})
    // 回显ids是标签id的对象数组
  } else if (isExistTagId) {
    idObj = this.getEchoObjByTagIds(echoIds, tagsList)
  }
  // 返回只有id的数组
  return idObj
},
// 根据回显的标签id数组,返回 { groupId: [id] }对象
getEchoObjByTagIds(echoIds, tagsList) {
  let idObj = {}
  tagsList.forEach((group) => {
    if (group.tagGroupId && group.tags && group.tags.length) {
      const tagIds = echoIds
      const matchingTags = group.tags.filter(tag => tagIds.includes(tag.id));
      if (matchingTags.length) {
        // 将只存有id的映射数组传给group
        idObj[group.tagGroupId] = matchingTags.map(tag => tag.id);
      }
    }
  })
  return idObj
},

处理标签列表

 // 处理标签列表
  handleSelectList(data){
    if(!data)return
    const echoTagObj = this.getEchoTagObj(this.echoIdList, data)
    console.log('idlist',echoTagObj)
    // 遍历标签列表,寻找回想对象
    data && data.forEach((g, i) => {
      // 将对象的属性名转成数组
      const groupIdsArr = Object.keys(echoTagObj) || []
      const isExistEcho = groupIdsArr.includes(String(g.tagGroupId))
      // 当前组id存在回显对象中
      if (isExistEcho) {
        const idsArr = echoTagObj[g.tagGroupId]
        g.isI = g.tags && idsArr && idsArr.length && idsArr.length < g.tags.length || false
        g.isAll = g.tags && idsArr && idsArr.length === g.tags.length || false
        g.tags && g.tags.forEach(t => {
          t.isSelected = idsArr.includes(t.id)
          t.groupIndex = i
        })
      } else {
        g.isI = false
        g.isAll = false
        g.tags && g.tags.forEach(t => {
          t.isSelected = false
          t.groupIndex = i
        })
      }
      g.isPut = false
    });
    this.renderList = data
    this.groupList = data
  },

父组件配合el-form使用

升级版多选框

<el-form-item label="标签:" label-width="72px" prop="tagIds">
  <div class="right-content">
    <SelectTag
      ref="selectTag"
      class="my-select-tag"
      popperClass="blue-select-tag-popover"
      themeColor="white"
      :tagsParams="tagsApiParams"
      @toGetTagIdList="toGetTagIdList"
      @visibleChange="visibleChange"
      />
  </div>
</el-form-item>

自定义css样式

.right-content{
  .my-select-tag {
    overflow-x: hidden;
    width: 470px;
    height: 32px;
    border-radius: 4px;
  }
}
.blue-select-tag-popover {
  border: none;
  .popper__arrow {
    border-bottom-color: #27314f !important;
    border-top-color: #27314f !important;
    &::after {
      border-bottom-color: #27314f !important;
      border-top-color: #27314f !important;
    }
  }
  @media (width: 1280px) {
    .option-list .left-wrap .group-area {
      max-height: 160px !important;
    }
    .option-list .right-wrap .selected-area {
      max-height: 240px !important;
    }
  }
  @media (width: 1440px) {
    .option-list .left-wrap .group-area {
      max-height: 160px !important;
    }
    .option-list .right-wrap .selected-area {
      max-height: 240px !important;
    }
  }
  @media (width: 1920px) {
    .option-list .left-wrap .group-area {
      max-height: 320px !important;
    }
    .option-list .right-wrap .selected-area {
      max-height: 400px !important;
    }
  }
}

标签是必选项时,使用自定义校验规则进行校验


data() {
  var validatePass = (rule, value, callback) => {
    // 只在提交的时候显示提示
    if (value.length==0 && this.isAudit) {
      callback(new Error('请选择标签'));
    } else {
      callback();
    }
  };
  return(){
    isAudit:false//是否点击提交
    // 审核弹窗表单规则
    auditRules:{
      tagIds: [
        { required: true,validator: validatePass,trigger: 'change'}
      ],
    },
  }
}

获取标签选择数据

// 获取选择的标签id列表
toGetTagIdList(ids) {
  this.auditForm.tagIds = ids
},

点击下拉框时,清空选择框的必选校验提示

// 点击下拉框
visibleChange(){
  this.$refs.auditForm.clearValidate("tagIds");
},

重置表单数据需要调用多选框方法清空已选标签

// 重置
toReset(type) {
  this.$refs.selectTag.toDeleteAll();//重置标签选项
  this.$refs.auditForm.resetFields();//重置表单
  this.isAudit=false
},
转载自:https://juejin.cn/post/7267837037785415735
评论
请登录