美文网首页
vue 下拉+tree

vue 下拉+tree

作者: 一叶孤舟1990 | 来源:发表于2020-08-14 08:50 被阅读0次

    组件:SelectTree

    <template>

      <el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle">

        <el-input

          class="selectInput"

          :placeholder="placeholder"

          v-model="filterText">

        </el-input>

        <el-option :value="valueTitle" :label="valueTitle" class="options">

          <el-tree  id="tree-option"

            ref="selectTree"

            :accordion="accordion"

            :data="options"

            :props="props"

            :node-key="props.value"   

            :default-expanded-keys="defaultExpandedKey"

            :filter-node-method="filterNode"

            @node-click="handleNodeClick">

          </el-tree>

        </el-option>

      </el-select>

    </template>

    <script>

    export default {

      name: "el-tree-select",

      props:{

        /* 配置项 */

        props:{

          type: Object,

          default:()=>{

            return {

              value:'id',            // ID字段名

              label: 'title',        // 显示名称

              children: 'children'    // 子级字段名

            }

          }

        },

        /* 选项列表数据(树形结构的对象数组) */

        options:{

          type: Array,     

          default: ()=>{ return [] }

        },

        /* 初始值 */

        value:{

          type: Number,

          default: ()=>{ return null }

        },

        /* 可清空选项 */

        clearable:{

          type:Boolean,

          default:()=>{ return true }

        },

        /* 自动收起 */

        accordion:{

          type:Boolean,

          default:()=>{ return false }

        },

        placeholder:{

          type:String,

          default:()=>{return "检索关键字"}

        }

      },

      data() {

        return {

          filterText: '',

          valueId:this.value,    // 初始值

          valueTitle:'',

          defaultExpandedKey:[]   

        }

      },

      mounted(){

        this.initHandle()

      },

      methods: {

        // 初始化值

        initHandle(){

          if(this.valueId){

            this.valueTitle = this.$refs.selectTree.getNode(this.valueId).data[this.props.label]    // 初始化显示

            this.$refs.selectTree.setCurrentKey(this.valueId)      // 设置默认选中

            this.defaultExpandedKey = [this.valueId]      // 设置默认展开

          }

          this.initScroll()

        },

        // 初始化滚动条

        initScroll(){

          this.$nextTick(()=>{

            let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0]

            let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar')

            scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'

            scrollBar.forEach(ele => ele.style.width = 0)

          })

        },

        // 切换选项

        handleNodeClick(node){

          this.valueTitle = node[this.props.label]

          this.valueId = node[this.props.value]

          this.$emit('getValue',this.valueId)

          this.defaultExpandedKey = []

        },

        // 清除选中

        clearHandle(){

          this.valueTitle = ''

          this.valueId = null

          this.defaultExpandedKey = []

          this.clearSelected()

          this.$emit('getValue',null)

        },

        /* 清空选中样式 */

        clearSelected(){

          let allNode = document.querySelectorAll('#tree-option .el-tree-node')

          allNode.forEach((element)=>element.classList.remove('is-current'))

        },

        filterNode(value, data) {

          if (!value) return true;

          return data.name.indexOf(value) !== -1;

        }

      },

      watch: {

        value(){

          this.valueId = this.value

          this.initHandle()

        },

        filterText(val) {

          this.$refs.selectTree.filter(val);

        }

      },

    };

    </script>

    <!-- Add "scoped" attribute to limit CSS to this component only -->

    <style scoped>

      .el-scrollbar .el-scrollbar__view .el-select-dropdown__item{

        height: auto;

        max-height: 274px;

        padding: 0;

        overflow: hidden;

        overflow-y: auto;

      }

      .el-select-dropdown__item.selected{

        font-weight: normal;

      }

      ul li >>>.el-tree .el-tree-node__content{

        height:auto;

        padding: 0 20px;

      }

      .el-tree-node__label{

        font-weight: normal;

      }

      .el-tree >>>.is-current .el-tree-node__label{

        color: #409EFF;

        font-weight: 700;

      }

      .el-tree >>>.is-current .el-tree-node__children .el-tree-node__label{

        color:#606266;

        font-weight: normal;

      }

      .selectInput{

        padding: 0 5px;

        box-sizing: border-box;

      }

    </style>

    调用:

    <template>

      <div id="app">

        <h1>{{`基于Element-UI组件改造的树形选择器`}}:</h1>

        <!-- 调用树形下拉框组件 -->

        <SelectTree

          :props="props"

          :options="optionData"

          :value="valueId"

          :clearable="isClearable"

          :accordion="isAccordion"

          @getValue="getValue($event)"

        />

        ID为:{{valueId}}

      </div>

    </template>

    <script>

    import SelectTree from "./components/treeSelect.vue";

    export default {

      name: "app",

      components: {

        SelectTree

      },

      data() {

        return {

          isClearable: true, // 可清空(可选)

          isAccordion: true, // 可收起(可选)

          valueId: 1, // 初始ID(可选)

          props: {

            // 配置项(必选)

            value: "id",

            label: "name",

            children: "children"

            // disabled:true

          },

          // 选项列表(必选)

          list: [

            { id: 1, parentId: 0, name: "一级菜单A", rank: 1 },

            { id: 2, parentId: 0, name: "一级菜单B", rank: 1 },

            { id: 3, parentId: 0, name: "一级菜单C", rank: 1 },

            { id: 4, parentId: 1, name: "二级菜单A-A", rank: 2 },

            { id: 5, parentId: 1, name: "二级菜单A-B", rank: 2 },

            { id: 6, parentId: 2, name: "二级菜单B-A", rank: 2 },

            { id: 7, parentId: 4, name: "三级菜单A-A-A", rank: 3 },

            { id: 8, parentId: 7, name: "四级菜单A-A-A-A", rank: 4 },

            { id: 9, parentId: 0, name: "一级菜单C", rank: 1 },

            { id: 10, parentId: 0, name: "一级菜单end", rank: 1 }

          ],

        };

      },

      computed: {

        /* 转树形数据 */

        optionData() {

          let cloneData = JSON.parse(JSON.stringify(this.list)); // 对源数据深度克隆

          return cloneData.filter(father => {

            // 循环所有项,并添加children属性

            let branchArr = cloneData.filter(child => father.id == child.parentId); // 返回每一项的子级数组

            branchArr.length > 0 ? (father.children = branchArr) : ""; //给父级添加一个children属性,并赋值

            return father.parentId == 0; //返回第一层

          });

        }

      },

      methods: {

        // 取值

        getValue(value) {

          this.valueId = value;

          console.log(this.valueId);

        }

      }

    };

    </script>

    <style>

    #app {

      font-family: "Avenir", Helvetica, Arial, sans-serif;

      -webkit-font-smoothing: antialiased;

      -moz-osx-font-smoothing: grayscale;

      text-align: center;

      color: #2c3e50;

      margin-top: 60px;

    }

    </style>

    相关文章

      网友评论

          本文标题:vue 下拉+tree

          本文链接:https://www.haomeiwen.com/subject/lzavrktx.html