Răsfoiți Sursa

tree support accordion

baiyaaaaa 8 ani în urmă
părinte
comite
2072156e5b

+ 104 - 10
examples/docs/en-US/tree.md

@@ -2,21 +2,36 @@
   const data = [{
     label: 'Level one 1',
     children: [{
-      label: 'Level two 1-1'
+      label: 'Level two 1-1',
+      children: [{
+        label: 'Level three 1-1-1'
+      }]
     }]
   }, {
     label: 'Level one 2',
     children: [{
-      label: 'Level two 2-1'
+      label: 'Level two 2-1',
+      children: [{
+        label: 'Level three 2-1-1'
+      }]
     }, {
-      label: 'Level two 2-2'
+      label: 'Level two 2-2',
+      children: [{
+        label: 'Level three 2-2-1'
+      }]
     }]
   }, {
     label: 'Level one 3',
     children: [{
-      label: 'Level two 3-1'
+      label: 'Level two 3-1',
+      children: [{
+        label: 'Level three 3-1-1'
+      }]
     }, {
-      label: 'Level two 3-2'
+      label: 'Level two 3-2',
+      children: [{
+        label: 'Level three 3-2-1'
+      }]
     }]
   }];
 
@@ -107,21 +122,36 @@ Basic tree structure.
         data: [{
           label: 'Level one 1',
           children: [{
-            label: 'Level two 1-1'
+            label: 'Level two 1-1',
+            children: [{
+              label: 'Level three 1-1-1'
+            }]
           }]
         }, {
           label: 'Level one 2',
           children: [{
-            label: 'Level two 2-1'
+            label: 'Level two 2-1',
+            children: [{
+              label: 'Level three 2-1-1'
+            }]
           }, {
-            label: 'Level two 2-2'
+            label: 'Level two 2-2',
+            children: [{
+              label: 'Level three 2-2-1'
+            }]
           }]
         }, {
           label: 'Level one 3',
           children: [{
-            label: 'Level two 3-1'
+            label: 'Level two 3-1',
+            children: [{
+              label: 'Level three 3-1-1'
+            }]
           }, {
-            label: 'Level two 3-2'
+            label: 'Level two 3-2',
+            children: [{
+              label: 'Level three 3-2-1'
+            }]
           }]
         }],
         defaultProps: {
@@ -214,6 +244,69 @@ Used for node selection. In the following example, data for each layer is acquir
 ```
 :::
 
+### Accordion
+
+Only one node among the same level can be expanded at one time.
+
+::: demo
+```html
+<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
+
+<script>
+  export default {
+    data() {
+      return {
+        data: [{
+          label: 'Level one 1',
+          children: [{
+            label: 'Level two 1-1',
+            children: [{
+              label: 'Level three 1-1-1'
+            }]
+          }]
+        }, {
+          label: 'Level one 2',
+          children: [{
+            label: 'Level two 2-1',
+            children: [{
+              label: 'Level three 2-1-1'
+            }]
+          }, {
+            label: 'Level two 2-2',
+            children: [{
+              label: 'Level three 2-2-1'
+            }]
+          }]
+        }, {
+          label: 'Level one 3',
+          children: [{
+            label: 'Level two 3-1',
+            children: [{
+              label: 'Level three 3-1-1'
+            }]
+          }, {
+            label: 'Level two 3-2',
+            children: [{
+              label: 'Level three 3-2-1'
+            }]
+          }]
+        }],
+        defaultProps: {
+          children: 'children',
+          label: 'label'
+        }
+      };
+    },
+    methods: {
+      handleNodeClick(data) {
+        console.log(data);
+      }
+    }
+  };
+</script>
+```
+:::
+
 ### Attributes
 | Attribute      | Description          | Type      | Accepted Values       | Default  |
 |---------- |-------------- |---------- |--------------------------------  |-------- |
@@ -233,6 +326,7 @@ Used for node selection. In the following example, data for each layer is acquir
 | check-strictly | whether checked state of a node not affects its father and child nodes when `show-checkbox` is `true` | boolean | — | false |
 | default-checked-keys | array of keys of initially checked nodes | array | — | — |
 | filter-node-method | this function will be executed on each node when use filter method. if return `false`, tree node will be hidden. | Function(value, data, node) | — | — |
+| accordion | whether only one node among the same level can be expanded at one time | boolean | — | false |
 
 ### props
 | Attribute      | Description          | Type      | Accepted Values       | Default  |

+ 104 - 10
examples/docs/zh-CN/tree.md

@@ -14,21 +14,36 @@
   const data = [{
     label: '一级 1',
     children: [{
-      label: '二级 1-1'
+      label: '二级 1-1',
+      children: [{
+        label: '三级 1-1-1'
+      }]
     }]
   }, {
     label: '一级 2',
     children: [{
-      label: '二级 2-1'
+      label: '二级 2-1',
+      children: [{
+        label: '三级 2-1-1'
+      }]
     }, {
-      label: '二级 2-2'
+      label: '二级 2-2',
+      children: [{
+        label: '三级 2-2-1'
+      }]
     }]
   }, {
     label: '一级 3',
     children: [{
-      label: '二级 3-1'
+      label: '二级 3-1',
+      children: [{
+        label: '三级 3-1-1'
+      }]
     }, {
-      label: '二级 3-2'
+      label: '二级 3-2',
+      children: [{
+        label: '三级 3-2-1'
+      }]
     }]
   }];
 
@@ -119,21 +134,36 @@
         data: [{
           label: '一级 1',
           children: [{
-            label: '二级 1-1'
+            label: '二级 1-1',
+            children: [{
+              label: '三级 1-1-1'
+            }]
           }]
         }, {
           label: '一级 2',
           children: [{
-            label: '二级 2-1'
+            label: '二级 2-1',
+            children: [{
+              label: '三级 2-1-1'
+            }]
           }, {
-            label: '二级 2-2'
+            label: '二级 2-2',
+            children: [{
+              label: '三级 2-2-1'
+            }]
           }]
         }, {
           label: '一级 3',
           children: [{
-            label: '二级 3-1'
+            label: '二级 3-1',
+            children: [{
+              label: '三级 3-1-1'
+            }]
           }, {
-            label: '二级 3-2'
+            label: '二级 3-2',
+            children: [{
+              label: '三级 3-2-1'
+            }]
           }]
         }],
         defaultProps: {
@@ -226,6 +256,69 @@
 ```
 :::
 
+### 手风琴模式
+
+每次只打开一个同级树节点展开
+
+::: demo
+```html
+<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
+
+<script>
+  export default {
+    data() {
+      return {
+        data: [{
+          label: '一级 1',
+          children: [{
+            label: '二级 1-1',
+            children: [{
+              label: '三级 1-1-1'
+            }]
+          }]
+        }, {
+          label: '一级 2',
+          children: [{
+            label: '二级 2-1',
+            children: [{
+              label: '三级 2-1-1'
+            }]
+          }, {
+            label: '二级 2-2',
+            children: [{
+              label: '三级 2-2-1'
+            }]
+          }]
+        }, {
+          label: '一级 3',
+          children: [{
+            label: '二级 3-1',
+            children: [{
+              label: '三级 3-1-1'
+            }]
+          }, {
+            label: '二级 3-2',
+            children: [{
+              label: '三级 3-2-1'
+            }]
+          }]
+        }],
+        defaultProps: {
+          children: 'children',
+          label: 'label'
+        }
+      };
+    },
+    methods: {
+      handleNodeClick(data) {
+        console.log(data);
+      }
+    }
+  };
+</script>
+```
+:::
+
 ### Attributes
 | 参数      | 说明          | 类型      | 可选值                           | 默认值  |
 |---------- |-------------- |---------- |--------------------------------  |-------- |
@@ -245,6 +338,7 @@
 | check-strictly | 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false | boolean | — | false |
 | default-checked-keys | 默认勾选的节点的 key 的数组 | array | — | — |
 | filter-node-method | 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏 | Function(value, data, node) | — | — |
+| accordion | 是否每次只打开一个同级树节点展开 | boolean | — | false |
 
 ### props
 | 参数      | 说明          | 类型      | 可选值                           | 默认值  |

+ 19 - 1
packages/tree/src/tree-node.vue

@@ -35,7 +35,8 @@
           :render-content="renderContent"
           v-for="child in node.childNodes"
           :key="getNodeKey(child)"
-          :node="child">
+          :node="child"
+          @click.native="handleChildNodeClick(child)">
         </el-tree-node>
       </div>
     </collapse-transition>
@@ -45,10 +46,15 @@
 <script type="text/jsx">
   import CollapseTransition from 'element-ui/src/transitions/collapse-transition';
   import ElCheckbox from 'element-ui/packages/checkbox';
+  import emitter from 'element-ui/src/mixins/emitter';
 
   export default {
     name: 'ElTreeNode',
 
+    componentName: 'ElTreeNode',
+
+    mixins: [emitter],
+
     props: {
       node: {
         default() {
@@ -156,6 +162,10 @@
         if (!this.node.indeterminate) {
           this.node.setChecked(ev.target.checked, !this.tree.checkStrictly);
         }
+      },
+
+      handleChildNodeClick(node) {
+        this.broadcast('ElTreeNode', 'tree-node-click', node);
       }
     },
 
@@ -186,6 +196,14 @@
         this.expanded = true;
         this.childNodeRendered = true;
       }
+
+      if(this.tree.accordion) {
+        this.$on('tree-node-click', node => {
+          if(this.node !== node) {
+            this.node.collapse();
+          }
+        });
+      }
     }
   };
 </script>

+ 43 - 35
packages/tree/src/tree.vue

@@ -5,7 +5,8 @@
       :node="child"
       :props="props"
       :key="getNodeKey(child)"
-      :render-content="renderContent">
+      :render-content="renderContent"
+      @click.native="handleChildNodeClick(child)">
     </el-tree-node>
     <div class="el-tree__empty-block" v-if="!root.childNodes || root.childNodes.length === 0">
       <span class="el-tree__empty-text">{{ emptyText }}</span>
@@ -16,10 +17,25 @@
 <script type="text/ecmascript-6">
   import TreeStore from './model/tree-store';
   import {t} from 'element-ui/src/locale';
+  import emitter from 'element-ui/src/mixins/emitter';
 
   export default {
     name: 'ElTree',
 
+    mixins: [emitter],
+
+    components: {
+      ElTreeNode: require('./tree-node.vue')
+    },
+
+    data() {
+      return {
+        store: null,
+        root: null,
+        currentNode: null
+      };
+    },
+
     props: {
       data: {
         type: Array
@@ -64,40 +80,8 @@
       highlightCurrent: Boolean,
       currentNodeKey: [String, Number],
       load: Function,
-      filterNodeMethod: Function
-    },
-
-    created() {
-      this.isTree = true;
-
-      this.store = new TreeStore({
-        key: this.nodeKey,
-        data: this.data,
-        lazy: this.lazy,
-        props: this.props,
-        load: this.load,
-        currentNodeKey: this.currentNodeKey,
-        checkStrictly: this.checkStrictly,
-        defaultCheckedKeys: this.defaultCheckedKeys,
-        defaultExpandedKeys: this.defaultExpandedKeys,
-        autoExpandParent: this.autoExpandParent,
-        defaultExpandAll: this.defaultExpandAll,
-        filterNodeMethod: this.filterNodeMethod
-      });
-
-      this.root = this.store.root;
-    },
-
-    data() {
-      return {
-        store: null,
-        root: null,
-        currentNode: null
-      };
-    },
-
-    components: {
-      ElTreeNode: require('./tree-node.vue')
+      filterNodeMethod: Function,
+      accordion: Boolean
     },
 
     computed: {
@@ -156,7 +140,31 @@
       },
       setChecked(data, checked, deep) {
         this.store.setChecked(data, checked, deep);
+      },
+      handleChildNodeClick(node) {
+        this.broadcast('ElTreeNode', 'tree-node-click', node);
       }
+    },
+
+    created() {
+      this.isTree = true;
+
+      this.store = new TreeStore({
+        key: this.nodeKey,
+        data: this.data,
+        lazy: this.lazy,
+        props: this.props,
+        load: this.load,
+        currentNodeKey: this.currentNodeKey,
+        checkStrictly: this.checkStrictly,
+        defaultCheckedKeys: this.defaultCheckedKeys,
+        defaultExpandedKeys: this.defaultExpandedKeys,
+        autoExpandParent: this.autoExpandParent,
+        defaultExpandAll: this.defaultExpandAll,
+        filterNodeMethod: this.filterNodeMethod
+      });
+
+      this.root = this.store.root;
     }
   };
 </script>

+ 15 - 0
test/unit/specs/tree.spec.js

@@ -354,4 +354,19 @@ describe('Tree', () => {
       done();
     }, 100);
   });
+
+  it('accordion', done => {
+    vm = getTreeVm(':props="defaultProps" accordion');
+    const firstNode = vm.$el.querySelector('.el-tree-node__content');
+    const secondNode = vm.$el.querySelector('.el-tree-node:nth-child(2) .el-tree-node__content');
+    firstNode.click();
+    setTimeout(() => {
+      expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.true;
+      secondNode.click();
+      setTimeout(() => {
+        expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.false;
+        done();
+      }, DELAY);
+    }, DELAY);
+  });
 });

Fișier diff suprimat deoarece este prea mare
+ 220 - 226
yarn.lock


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff