本文介绍: vue+element UI实现全选、反选、联级、搜索下拉选框;vuetreeselect插件实现全选、反选、联级、搜索下拉选框

halo小伙伴们,在开发过程是否遇到需要下拉选框添加操作按钮的,如全选、反选、联级、搜索下拉选框呢?如图所示
在这里插入图片描述
这里我们需要借助vuetreeselect插件(官方地址
一步安装vuetreeselect插件

npm install --save @riophae/vue-treeselect

第二步封装下拉框组件

<template>
  <div class="store-tree-select store-tree-wrap">
  	// 以下的属性可以自己查阅vue-treeselect官方文档进行查看
    <xy-tree-select
        :placeholder="placeholder"
        value-consists-of="ALL_WITH_INDETERMINATE"
        noChildrenText="暂无数据"
        searchPromptText="请输入搜索关键字"
        noResultsText="无搜索结果"
        :normalizer="normalizer"
        :disable-branch-nodes="false"
        :auto-load-root-options="loading"
        :multiple="multiple"
        :limit="limit"
        :limitText="limitTextFun"
        :maxHeight="500"
        :disabled="disabled"
        :options="data"
        :value="currentValue"
        v-model="currentValue"
        :default-expand-level="defaultExpandLevel"
        :flat="flat"
        :auto-deselect-descendants="cascade"
        :auto-select-descendants="cascade"
        @open="treeSelectOpen"
        @close="treeSelectClose"
        @input="input">
      // 这里顶部控制按钮
      <div slot="before-list" v-if="multiple == true" style="padding:0 0 4px 6px;"&gt;
        <div class="before-list-item" @click="selAll"&gt;
          <i class="el-icon-finished"&gt;</i&gt; 全选
        </div>
        <div class="before-list-item" @click="selBack">
          <i class="el-icon-refresh-left"></i> 反选
        </div>
        <div class="before-list-item" @click="doSelLink">
          <i class="el-icon-link"></i>&amp;nbsp;<span ref="linkText">联级</span>
        </div>
      </div>
    </xy-tree-select>
  </div>
</template>

<script>
// 这里引入安装好的vue-treeselect插件
import TreeSelect from '@riophae/vue-treeselect'
// 这里记得要连样式一起引入
import '@riophae/vue-treeselect/dist/vue-treeselect.css'

export default {
  components: {
    xyTreeSelect: TreeSelect,
  },
  mounted() {
  	// 获取下拉框数据
    this.loadData();
  },
  props: {
    placeholder: {
      default: '请选择组织'
    },
    limit:{
      default:1
    },
    //是否多选
    multiple: {
      default: false
    },
    //是否禁用
    disabled: {
      default: false
    },
    //树类型:BLOC,BRAND,AREA
    type: {
      type: String,
      default: undefined,
    },
    //是否加载默认true
    lazy: {
      type: Boolean,
      default: true,
    },
    //是否自动加载
    autoLoadData: {
      default: true
    },
    //初始值
    value: {
      default: null
    },
    // 加载时应自动扩展多少分支节点设置 Infinity 为默认使所有分支节点扩展
    defaultExpandLevel: {
      default: 2
    },
    flat:{
      default:true
    },
    //设置一开始的列表用于默认选中时候提示‘无该门店权限
    list:{
      default:Array,
    },
  },
  watch: {
    value(val) {
      this.currentValue = val;
    },
    list(val){
      if(val.length>=0){
        this.data = val
      }
    },
    // 监听点击的联级反联级切换文本内容,在computed中操作也是可以
    openStatu(val){
      if(val){
        if(this.cascade){
          this.$nextTick(()=>{
            this.$refs.linkText.innerHTML = '联级'
          })
        }else {
          this.$nextTick(()=>{
            this.$refs.linkText.innerHTML = '反联级'
          })
        }
      }
    }
  },
  
  data() {
    return {
      loading: true,
      normalizer(node) {
        return {
          id: node.id,
          // 由于小编这里有显示判断,所以根据字段进行了部分文本渲染判断
          label: node.title==undefined?'无该门店权限' : node.title + (node.type == 1 ? '(品牌)' : node.type == 2 ? '(区域)' : '(门店)'),
          children: node.subs != null ? node.subs : undefined,
          isDisabled: node.disabled,
        }
      },
      itemDisabled_:false,
      data: [],
      currentValue: this.value,
      cascade: true, // false表示不级联  true表示级联

      allDataIds:[],
      selLink:true,
      openStatu:false,
    }
  },
  
  methods: {
  	// 联级按钮操作
    doSelLink(){
      this.$nextTick(() => {
        this.selLink = !this.selLink
        this.cascade = this.selLink
      })
      if(!this.cascade){
        this.$nextTick(()=>{
          this.$refs.linkText.innerHTML = '联级'
        })
      }else {
        this.$nextTick(()=>{
          this.$refs.linkText.innerHTML = '反联级'
        })
      }
    },
    // 反选
    selBack(){
      // console.log("已经选了的",this.currentValue)
      let hasSel = this.currentValue;     //已经选中列表
      if(hasSel.length<=0){
        return;
      }
      let allList = this.allDataIds;      //全部的列表
      let readyList = [];                 //准备放新的
      readyList = hasSel.filter(x => allList.indexOf(x) == -1)
          .concat(allList.filter(x => hasSel.indexOf(x) == -1));
      this.currentValue = readyList
    },
    //全选
    selAll(){
      this.currentValue = this.allDataIds
    },
    
    funChildren(arr) {
      let childs = arr
      for (let i = childs.length; i--; i > 0) {
        if (childs[i].subs) {
          this.allDataIds.push(childs[i].id)
          this.funChildren(childs[i].subs)
        } else {
          this.allDataIds.push(childs[i].id)
        }
      }
      return this.allDataIds
    },
    clearInput() {
      this.currentValue = null;
    },
    input(value) {
      this.$emit('selectChange', value);
    },
    /**
     *当所选元素超过定义限制处理显示消息功能。
     */
    limitTextFun(count) {
      return '+' + count
    },
    loadData(){
      this.allDataIds = []
      this.data = this.$store.state.UserAreasTree.UserAreasTreeData;
      this.funChildren(this.data)
    },
    /**
     *菜单打开时,获取结构的值, 这样可以每次都获取一下最新的
     */
    treeSelectOpen() {//UserAreasTree.js
      /*let data = this.$store.state.UserAreasTree.UserAreasTreeData;
      this.data = this.publicFun.deleteChildren(data, 'subs');*/
      this.allDataIds = []
      this.data = this.$store.state.UserAreasTree.UserAreasTreeData;
      this.funChildren(this.data)
      this.openStatu = true
    },
    treeSelectClose(){
      this.openStatu = false
    }
  },
}
</script>


<style>
.before-list-item{
  float:left;
  width: 33.33%;
  text-align: center;
  cursor: pointer
}

.before-list-item:hover{
  color: #2d8cf0;
}
.vue-treeselect__control .vue-treeselect__limit-tip {
  padding-top: 2px;
}

.vue-treeselect__control {
  height: 32px;
}

.vue-treeselect--has-value .vue-treeselect__multi-value {
  margin-bottom: 0;
}

.vue-treeselect__multi-value-item-container {
  padding-top: 2px;
}
.store-tree-wrap{
  line-height: 20px;
}


</style>

第三步,在需要组件页面引入组件

// 使用组件
<xy-form-tree-select :value="filterForm.areaIds" :multiple="true" @selectChange="selectArea"/>
        
// 引入组件
import xyFormTreeSelect from "../../common/XyTreeSelectControl";

// 回调方法
selectArea(val) {
   this.filterForm.areaIds = val;
},

好啦,快去试试看可不可行吧,如果有更好方法小伙伴们记得跟小编分享一下你们的开发经验哦!

原文地址:https://blog.csdn.net/XujiRe/article/details/129692860

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_37122.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注