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-width: ${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: ${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     width: 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     width: 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     width: 6px;
217     background: #b4bccc;
218   }
219   .select-tree::-webkit-scrollbar-track-piece {
220     background: #fff;
221     width: 6px;
222   }
223 </style>

原文地址:https://www.cnblogs.com/yuwenjing0727/p/10214490.html

时间: 2024-11-09 00:37:39

Element-UI 实现下拉树的相关文章

WPF 组织机构下拉树多选,递归绑定方式现实

原文:WPF 组织机构下拉树多选,递归绑定方式现实 使用HierarchicalDataTemplate递归绑定现实 XAML代码: <UserControl x:Class="SunCreate.CombatPlatform.Client.MultiSelOrgTree" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas

Extjs下拉树代码测试总结

http://blog.csdn.net/kunoy/article/details/8067801 首先主要代码源自网络,对那些无私的奉献者表示感谢! 笔者对这些代码做了二次修改,并总结如下: Extjs3.x版本下拉树代码: [javascript] view plaincopy Ext.ux.TreeCombo = Ext.extend(Ext.form.ComboBox, { constructor : function(cfg) { cfg = cfg || {}; Ext.ux.Tr

EXTJS下拉树ComboBoxTree参数提交及回显方法

http://blog.csdn.net/wjlht/article/details/6085245 使用extjs可以构造出下拉数,但是不方便向form提交参数,在此,笔者想到一个办法,很方便ComboBoxTree向form提交. 原理: 在form中增加一个隐藏的字段,当在comboBoxTree中选定值后自动在隐藏字段中赋值. 为实现此方法,需要重载comboBoxTree中collapse事件方法. Ext.ux.ComboBoxTree = function(){    this.t

c# - Winform DatagridView上显示下拉树

Winform的DatagridView是不支持下拉树的,所以需要扩展 废话不多说,直接贴代码 首先需要对comBox扩展,下拉内容变成TreeView using System.Drawing;using System.Windows.Forms;namespace WindowsApplication23{ public class ComboBoxTreeView : ComboBox { private const int WM_LBUTTONDOWN = 0x201, WM_LBUTT

Asp.net下拉树实现(Easy UI ComboTree)

场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门.(叶子节点全被选中时,只取父节点) 知识点:ComboTree.一般处理程序.递归.Json 效果如图 数据库表设计:unit_main unit_id unit_name parent_id desc 部门ID 部门名称 父ID 说明 节点类设计: 1 public class Unit 2 { 3 public decimal id { get; set

jQuery UI的下拉框显示不全解决方法

解决前,显示不全,select下拉框某些选项无法看到: <script type="text/javascript"> $("#cond_EPARCHY_CODE").selectmenu(); </script> 解决后: <style> .overflow { height: 200px; } </style> <script type="text/javascript"> $(&q

解决element生成的下拉菜单,不在父级之下,而是在body之下,通过父级控制该下拉菜单的样式,达到不跟别的地方冲突的目的

项目中存在多个下拉菜单,每个下拉菜单的样式可能不同 不能直接拿到element里面的类名来修改,这样会导致全局统一 在下拉菜单上定义一个父级类名,通过这个父级类名来定义这些下拉菜单的样式,达到私有化 遇到问题,生成的下拉菜单跟父类不在同一个节点,无法通过父级类来指定样式 解决方案:在下拉菜单的结构上添加 ref,页面加载后动态添加父级类名 原文地址:https://www.cnblogs.com/wuhefeng/p/12530803.html

iOS开发——UI篇&amp;下拉弹出列表选择项效果

下拉弹出列表选择项效果 右边菜单中的按键,点击弹出一个列表可选择,选择其中一个,响应相应的事件并把文字显示在右边的菜单上:弹出下拉效果使用LMDropdownView插件,可以用POD进行加载pod ‘LMDropdownView’:LMDropdownView是把想要的视图赋给它: 源代码地址:https://github.com/JxbSir/YiYuanYunGou 效果如下: 1:在主页面先定义按键跟绑定视图(没写全的都是属性中定义了比如btnRigth,dropdownView等):

iOS UI开发--下拉放大

1. 要实现的效果,左图为下拉前,右图为下拉后   2.首先最容易想到的是往tableHeaderView上,放一张图片. 但是tableHeaderView的宽度是固定的,这就意味着不容易做缩放效果; 顶部的上边界始终和tableView的上边界挨着,这就意味着下拉前只显示部分图片的效果,不容易实现. 3.最终方案:给tableView添加一张图片作为子视图, 并且图片应该在cell的下面,一开始图片只显示一部分 4. 示例代码 4.1 在ViewDidload方法中: UIImage *a

js 自动生成下拉树

toTree:function(treeDatas) {       var that = this;       var rs = [];  for(var i=0; i<treeDatas.length; i++) { var pid = -1; if(treeDatas[i].hasOwnProperty("pid")){ pid = treeDatas[i].pid; } rs.push({id: treeDatas[i].id, name: treeDatas[i].s