浏览代码

add callbacks on tree

Leopoldthecoder 8 年之前
父节点
当前提交
ed8168bc2c
共有 4 个文件被更改,包括 72 次插入17 次删除
  1. 1 0
      CHANGELOG.md
  2. 47 12
      examples/docs/zh-cn/tree.md
  3. 2 4
      packages/tree/src/model/tree.js
  4. 22 1
      packages/tree/src/tree-node.vue

+ 1 - 0
CHANGELOG.md

@@ -12,6 +12,7 @@
 - 为 Notification 和 Message 的不同 type 添加独立的调用方法
 - 为 Message Box 和 Dialog 添加 lockScroll 属性,用于定义是否在弹框出现时将 body 滚动锁定
 - 新增 Input textarea 类型的 rows, autosize 属性
+- 为 Tree 添加 getCheckedNodes 方法和 node-click、check-change 回调
 
 ### 1.0.0-rc.5
 

+ 47 - 12
examples/docs/zh-cn/tree.md

@@ -58,16 +58,21 @@
 
   export default {
     methods: {
+      handleCheckChange(data, checked, indeterminate) {
+        console.log(data, checked, indeterminate);
+      },
+      handleNodeClick(data) {
+        console.log(data);
+      },
       loadNode(node, resolve) {
-        console.log(node);
         if (node.level === -1) {
-          return resolve([{ name: 'Root1' }, { name: 'Root2' }]);
+          return resolve([{ name: 'region1' }, { name: 'region2' }]);
         }
         if (node.level > 4) return resolve([]);
         var hasChild;
-        if (node.data.name === 'Root1') {
+        if (node.data.name === 'region1') {
           hasChild = true;
-        } else if (node.data.name === 'Root2') {
+        } else if (node.data.name === 'region2') {
           hasChild = false;          
         } else {
           hasChild = Math.random() > 0.5;
@@ -111,7 +116,7 @@
 
 ::: demo
 ```html
-<el-tree :data="data" :props="defaultProps"></el-tree>
+<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
 
 <script>
   export default {
@@ -154,7 +159,14 @@
 
 ::: demo
 ```html
-<el-tree :data="regions" :props="props" :load="loadNode" lazy show-checkbox></el-tree>
+<el-tree
+  :data="regions"
+  :props="props"
+  :load="loadNode"
+  lazy
+  show-checkbox
+  @check-change="handleCheckChange">
+</el-tree>
 
 <script>
   export default {
@@ -173,18 +185,27 @@
       };
     },
     methods: {
-      getCheckedNodes() {
-        console.log(this.$refs.tree.getCheckedNodes(true));
+      handleCheckChange(data, checked, indeterminate) {
+        console.log(data, checked, indeterminate);
+      },
+      handleNodeClick(data) {
+        console.log(data);
       },
-
       loadNode(node, resolve) {
-        console.log(node);
         if (node.level === -1) {
-          return resolve([{ name: 'Root1' }, { name: 'Root2' }]);
+          return resolve([{ name: 'region1' }, { name: 'region2' }]);
         }
-        var hasChild = Math.random() > 0.5;
         if (node.level > 4) return resolve([]);
 
+        var hasChild;
+        if (node.data.name === 'region1') {
+          hasChild = true;
+        } else if (node.data.name === 'region2') {
+          hasChild = false;
+        } else {
+          hasChild = Math.random() > 0.5;
+        }
+
         setTimeout(function() {
           var data;
           if (hasChild) {
@@ -213,6 +234,7 @@
 | data     | 展示数据 | array | — | — |
 | props | 配置选项,具体看下表 | object | — | — |
 | load | 加载子树数据的方法 | function(node, resolve) | — | — |
+| show-checkbox | 节点是否可被选择 | boolean | — | false |
 
 ### props
 
@@ -220,3 +242,16 @@
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | label | 指定节点标签为节点对象的某个属性值 | string | — | — |
 | children | 指定子树为节点对象的某个属性值 | string | — | — |
+
+### 方法
+`Tree` 拥有如下方法,返回目前被选中的节点数组:
+
+| 方法名 | 说明 | 参数 |
+|------|--------|------|
+| getCheckedNodes | 若节点可被选择(即 `show-checkbox` 为 `true`),<br>则返回目前被选中的节点所组成的数组 | 接收一个 boolean 类型的参数,若为 `true` 则<br>仅返回被选中的叶子节点,默认值为 `false` |
+
+### Events
+| 事件名称      | 说明    | 回调参数      |
+|---------- |-------- |---------- |
+| node-click  | 节点被点击时的回调 | 传递给 `data` 属性的数组中该节点所对应的对象 |
+| check-change  | 节点选中状态发生变化时的回调 | 共三个参数,依次为:传递给 `data` 属性的数组中该节点所对应的对象、<br>节点本身是否被选中、节点的子树中是否有被选中的节点 |

+ 2 - 4
packages/tree/src/model/tree.js

@@ -28,12 +28,10 @@ export default class Tree {
   getCheckedNodes(leafOnly) {
     const checkedNodes = [];
     const walk = function(node) {
-      const children = node.children;
+      const children = node.root ? node.root.children : node.children;
 
       children.forEach(function(child) {
-        if ((!leafOnly && child.checked) || (leafOnly && !child.hasChild && child.checked)) {
-          checkedNodes.push(child.data);
-        } else {
+        if ((!leafOnly && child.checked) || (leafOnly && child.isLeaf && child.checked)) {
           checkedNodes.push(child.data);
         }
 

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

@@ -46,11 +46,31 @@
         $tree: null,
         expanded: false,
         childrenRendered: false,
-        showCheckbox: false
+        showCheckbox: false,
+        oldChecked: null,
+        oldIndeterminate: null
       };
     },
 
+    watch: {
+      'node.indeterminate'(val) {
+        this.handleSelectChange(this.node.checked, val);
+      },
+
+      'node.checked'(val) {
+        this.handleSelectChange(val, this.node.indeterminate);
+      }
+    },
+
     methods: {
+      handleSelectChange(checked, indeterminate) {
+        if (this.oldChecked !== checked && this.oldIndeterminate !== indeterminate) {
+          this.$tree.$emit('check-change', this.node.data, checked, indeterminate);
+        }
+        this.oldChecked = checked;
+        this.indeterminate = indeterminate;
+      },
+
       handleExpandIconClick(event) {
         let target = event.target;
         if (target.tagName.toUpperCase() !== 'DIV' &&
@@ -65,6 +85,7 @@
             this.childrenRendered = true;
           });
         }
+        this.$tree.$emit('node-click', this.node.data);
       },
 
       handleUserClick() {