zoukankan      html  css  js  c++  java
  • Element-UI 实现下拉树

    组件调用

     1 <template>
     2   <!-- 行模式 -->
     3   <el-form inline>
     4     <el-form-item label="inline 默认:">
     5       <select-tree :options="options" v-model="selected" />
     6     </el-form-item>
     7     <el-form-item label="inline 定义宽度:">
     8       <select-tree width="200" :options="options" v-model="selected" />
     9     </el-form-item>
    10   </el-form>
    11   <!-- 块模式 -->
    12   <el-form>
    13     <el-form-item label="自适应:">
    14       <select-tree v-model="selected" :options="options" :props="defaultProps" />
    15     </el-form-item>
    16   </el-form>
    17 </template>
    18 
    19 <script>
    20 import SelectTree from '@/components/widget/SelectTree.vue';
    21 
    22 export default {
    23   name: 'about',
    24   components: {
    25     SelectTree,
    26   },
    27   data() {
    28     return {
    29       // 默认选中值
    30       selected: 'A',
    31       // 数据默认字段
    32       defaultProps: {
    33         parent: 'parentId',   // 父级唯一标识
    34         value: 'id',          // 唯一标识
    35         label: 'label',       // 标签显示
    36         children: 'children', // 子级
    37       },
    38       // 数据列表
    39       options: [
    40         {
    41           parentId: '0',
    42           id: 'A',
    43           label: 'label-A',
    44           children: [
    45             {
    46               parentId: 'A',
    47               id: 'A-1',
    48               label: 'label-A-1',
    49             },
    50           ],
    51         },
    52         {
    53           parentId: '0',
    54           value: 'B',
    55           label: 'label-B',
    56           children: [],
    57         },
    58       ],
    59     };
    60   },
    61 };
    62 </script>

    SelectTree.vue

      1 <!-- 树状选择器 -->
      2 <template>
      3   <el-popover
      4     ref="popover"
      5     placement="bottom-start"
      6     trigger="click"
      7     @show="onShowPopover"
      8     @hide="onHidePopover">
      9     <el-tree
     10       ref="tree"
     11       class="select-tree"
     12       highlight-current
     13       :style="`min- ${treeWidth}`"
     14       :data="data"
     15       :props="props"
     16       :expand-on-click-node="false"
     17       :filter-node-method="filterNode"
     18       :default-expand-all="false"
     19       @node-click="onClickNode">
     20     </el-tree>
     21     <el-input
     22       slot="reference"
     23       ref="input"
     24       v-model="labelModel"
     25       clearable
     26       :style="` ${width}px`"
     27       :class="{ 'rotate': showStatus }"
     28       suffix-icon="el-icon-arrow-down"
     29       :placeholder="placeholder">
     30     </el-input>
     31   </el-popover>
     32 </template>
     33 
     34 <script>
     35 export default {
     36   name: 'Pagination',
     37   props: {
     38     // 接收绑定参数
     39     value: String,
     40     // 输入框宽度
     41      String,
     42     // 选项数据
     43     options: {
     44       type: Array,
     45       required: true,
     46     },
     47     // 输入框占位符
     48     placeholder: {
     49       type: String,
     50       required: false,
     51       default: '请选择',
     52     },
     53     // 树节点配置选项
     54     props: {
     55       type: Object,
     56       required: false,
     57       default: () => ({
     58         parent: 'parentId',
     59         value: 'rowGuid',
     60         label: 'areaName',
     61         children: 'children',
     62       }),
     63     },
     64   },
     65   // 设置绑定参数
     66   model: {
     67     prop: 'value',
     68     event: 'selected',
     69   },
     70   computed: {
     71     // 是否为树状结构数据
     72     dataType() {
     73       const jsonStr = JSON.stringify(this.options);
     74       return jsonStr.indexOf(this.props.children) !== -1;
     75     },
     76     // 若非树状结构,则转化为树状结构数据
     77     data() {
     78       return this.dataType ? this.options : this.switchTree();
     79     },
     80   },
     81   watch: {
     82     labelModel(val) {
     83       if (!val) {
     84         this.valueModel = '';
     85       }
     86       this.$refs.tree.filter(val);
     87     },
     88     value(val) {
     89       this.labelModel = this.queryTree(this.data, val);
     90     },
     91   },
     92   data() {
     93     return {
     94       // 树状菜单显示状态
     95       showStatus: false,
     96       // 菜单宽度
     97       treeWidth: 'auto',
     98       // 输入框显示值
     99       labelModel: '',
    100       // 实际请求传值
    101       valueModel: '0',
    102     };
    103   },
    104   created() {
    105     // 检测输入框原有值并显示对应 label
    106     if (this.value) {
    107       this.labelModel = this.queryTree(this.data, this.value);
    108     }
    109     // 获取输入框宽度同步至树状菜单宽度
    110     this.$nextTick(() => {
    111       this.treeWidth = `${(this.width || this.$refs.input.$refs.input.clientWidth) - 24}px`;
    112     });
    113   },
    114   methods: {
    115     // 单击节点
    116     onClickNode(node) {
    117       this.labelModel = node[this.props.label];
    118       this.valueModel = node[this.props.value];
    119       this.onCloseTree();
    120     },
    121     // 偏平数组转化为树状层级结构
    122     switchTree() {
    123       return this.cleanChildren(this.buildTree(this.options, '0'));
    124     },
    125     // 隐藏树状菜单
    126     onCloseTree() {
    127       this.$refs.popover.showPopper = false;
    128     },
    129     // 显示时触发
    130     onShowPopover() {
    131       this.showStatus = true;
    132       this.$refs.tree.filter(false);
    133     },
    134     // 隐藏时触发
    135     onHidePopover() {
    136       this.showStatus = false;
    137       this.$emit('selected', this.valueModel);
    138     },
    139     // 树节点过滤方法
    140     filterNode(query, data) {
    141       if (!query) return true;
    142       return data[this.props.label].indexOf(query) !== -1;
    143     },
    144     // 搜索树状数据中的 ID
    145     queryTree(tree, id) {
    146       let stark = [];
    147       stark = stark.concat(tree);
    148       while (stark.length) {
    149         const temp = stark.shift();
    150         if (temp[this.props.children]) {
    151           stark = stark.concat(temp[this.props.children]);
    152         }
    153         if (temp[this.props.value] === id) {
    154           return temp[this.props.label];
    155         }
    156       }
    157       return '';
    158     },
    159     // 将一维的扁平数组转换为多层级对象
    160     buildTree(data, id = '0') {
    161       const fa = (parentId) => {
    162         const temp = [];
    163         for (let i = 0; i < data.length; i++) {
    164           const n = data[i];
    165           if (n[this.props.parent] === parentId) {
    166             n.children = fa(n.rowGuid);
    167             temp.push(n);
    168           }
    169         }
    170         return temp;
    171       };
    172       return fa(id);
    173     },
    174     // 清除空 children项
    175     cleanChildren(data) {
    176       const fa = (list) => {
    177         list.map((e) => {
    178           if (e.children.length) {
    179             fa(e.children);
    180           } else {
    181             delete e.children;
    182           }
    183           return e;
    184         });
    185         return list;
    186       };
    187       return fa(data);
    188     },
    189   },
    190 };
    191 </script>
    192 
    193 <style>
    194   .el-input.el-input--suffix {
    195     cursor: pointer;
    196     overflow: hidden;
    197   }
    198   .el-input.el-input--suffix.rotate .el-input__suffix {
    199     transform: rotate(180deg);
    200   }
    201   .select-tree {
    202     max-height: 350px;
    203     overflow-y: scroll;
    204   }
    205   /* 菜单滚动条 */
    206   .select-tree::-webkit-scrollbar {
    207     z-index: 11;
    208      6px;
    209   }
    210   .select-tree::-webkit-scrollbar-track,
    211   .select-tree::-webkit-scrollbar-corner {
    212     background: #fff;
    213   }
    214   .select-tree::-webkit-scrollbar-thumb {
    215     border-radius: 5px;
    216      6px;
    217     background: #b4bccc;
    218   }
    219   .select-tree::-webkit-scrollbar-track-piece {
    220     background: #fff;
    221      6px;
    222   }
    223 </style>
  • 相关阅读:
    Hadoop作业提交多种方案具体流程详解
    教你一步搭建Flume分布式日志系统
    Hadoop详细配置
    linux 运行springboot sqoop项目
    SQL+ 正则表达式
    SQL+ 正则表达式
    DB2中实现正则表达式
    DB2中实现正则表达式
    spring4整合cxf3
    spring4整合cxf3
  • 原文地址:https://www.cnblogs.com/yuwenjing0727/p/10214490.html
Copyright © 2011-2022 走看看