Blame view

src/components/tree/tree.vue 7.65 KB
89f2ba8b   梁灏   init Tree component
1
  <template>
cb84e64a   梁灏   update Tree
2
3
      <div :class="prefixCls">
          <Tree-node
da76a837   Sergio Crisostomo   fix dom rendering...
4
5
              v-for="(item, i) in stateTree"
              :key="i"
cb84e64a   梁灏   update Tree
6
7
8
              :data="item"
              visible
              :multiple="multiple"
56c7cc0e   vanppo   Add new props 'ch...
9
10
              :show-checkbox="showCheckbox"
              :children-key="childrenKey">
cb84e64a   梁灏   update Tree
11
          </Tree-node>
d44420be   Sergio Crisostomo   refactor and make...
12
          <div :class="[prefixCls + '-empty']" v-if="!stateTree.length">{{ localeEmptyText }}</div>
cb84e64a   梁灏   update Tree
13
      </div>
89f2ba8b   梁灏   init Tree component
14
15
  </template>
  <script>
cb84e64a   梁灏   update Tree
16
      import TreeNode from './node.vue';
e2c6ff2b   梁灏   update Rate
17
      import Emitter from '../../mixins/emitter';
e5337c81   梁灏   fixed some compon...
18
      import Locale from '../../mixins/locale';
e81207a2   梁灏   update Tree
19
20
21
  
      const prefixCls = 'ivu-tree';
  
89f2ba8b   梁灏   init Tree component
22
      export default {
34ee7b4a   梁灏   support Tree & ad...
23
          name: 'Tree',
e5337c81   梁灏   fixed some compon...
24
          mixins: [ Emitter, Locale ],
cb84e64a   梁灏   update Tree
25
          components: { TreeNode },
467e2cf9   梁灏   Tree add check-di...
26
27
28
          provide () {
              return { TreeInstance: this };
          },
e81207a2   梁灏   update Tree
29
          props: {
9d79a51f   梁灏   update Tree
30
              data: {
e81207a2   梁灏   update Tree
31
32
33
34
35
                  type: Array,
                  default () {
                      return [];
                  }
              },
e81207a2   梁灏   update Tree
36
37
38
39
40
41
42
43
              multiple: {
                  type: Boolean,
                  default: false
              },
              showCheckbox: {
                  type: Boolean,
                  default: false
              },
467e2cf9   梁灏   Tree add check-di...
44
45
46
47
48
49
50
51
              checkStrictly: {
                  type: Boolean,
                  default: false
              },
              // 当开启 showCheckbox 时,如果开启 checkDirectly,select 将强制转为 check 事件
              checkDirectly: {
                  type: Boolean,
                  default: false
b84c8cc4   malin   增加checkStrictly属性...
52
              },
e81207a2   梁灏   update Tree
53
              emptyText: {
e5337c81   梁灏   fixed some compon...
54
                  type: String
b31aab71   梁灏   Tree add async lo...
55
              },
56c7cc0e   vanppo   Add new props 'ch...
56
57
58
59
              childrenKey: {
                  type: String,
                  default: 'children'
              },
b31aab71   梁灏   Tree add async lo...
60
61
              loadData: {
                  type: Function
174836c4   梁灏   update Tree Rende...
62
63
64
              },
              render: {
                  type: Function
467e2cf9   梁灏   Tree add check-di...
65
66
              },
  
e81207a2   梁灏   update Tree
67
          },
89f2ba8b   梁灏   init Tree component
68
          data () {
e81207a2   梁灏   update Tree
69
              return {
d44420be   Sergio Crisostomo   refactor and make...
70
                  prefixCls: prefixCls,
0a8f9b43   Sergio Crisostomo   Keep original dat...
71
                  stateTree: this.data,
d44420be   Sergio Crisostomo   refactor and make...
72
                  flatState: [],
e81207a2   梁灏   update Tree
73
              };
89f2ba8b   梁灏   init Tree component
74
          },
d44420be   Sergio Crisostomo   refactor and make...
75
          watch: {
76a47814   梁灏   fixed #2128
76
77
78
79
80
81
82
              data: {
                  deep: true,
                  handler () {
                      this.stateTree = this.data;
                      this.flatState = this.compileFlatState();
                      this.rebuildTree();
                  }
d44420be   Sergio Crisostomo   refactor and make...
83
84
              }
          },
e5337c81   梁灏   fixed some compon...
85
86
          computed: {
              localeEmptyText () {
d44420be   Sergio Crisostomo   refactor and make...
87
                  if (typeof this.emptyText === 'undefined') {
e5337c81   梁灏   fixed some compon...
88
89
90
91
                      return this.t('i.tree.emptyText');
                  } else {
                      return this.emptyText;
                  }
d44420be   Sergio Crisostomo   refactor and make...
92
              },
e5337c81   梁灏   fixed some compon...
93
          },
e81207a2   梁灏   update Tree
94
          methods: {
d44420be   Sergio Crisostomo   refactor and make...
95
96
              compileFlatState () { // so we have always a relation parent/children of each node
                  let keyCounter = 0;
0985c87b   vanppo   :bug: Fix issue #...
97
                  let childrenKey = this.childrenKey;
d44420be   Sergio Crisostomo   refactor and make...
98
99
100
101
102
103
                  const flatTree = [];
                  function flattenChildren(node, parent) {
                      node.nodeKey = keyCounter++;
                      flatTree[node.nodeKey] = { node: node, nodeKey: node.nodeKey };
                      if (typeof parent != 'undefined') {
                          flatTree[node.nodeKey].parent = parent.nodeKey;
0985c87b   vanppo   :bug: Fix issue #...
104
                          flatTree[parent.nodeKey][childrenKey].push(node.nodeKey);
d44420be   Sergio Crisostomo   refactor and make...
105
106
                      }
  
0985c87b   vanppo   :bug: Fix issue #...
107
108
109
                      if (node[childrenKey]) {
                          flatTree[node.nodeKey][childrenKey] = [];
                          node[childrenKey].forEach(child => flattenChildren(child, node));
d44420be   Sergio Crisostomo   refactor and make...
110
111
112
113
114
115
116
117
118
                      }
                  }
                  this.stateTree.forEach(rootNode => {
                      flattenChildren(rootNode);
                  });
                  return flatTree;
              },
              updateTreeUp(nodeKey){
                  const parentKey = this.flatState[nodeKey].parent;
b84c8cc4   malin   增加checkStrictly属性...
119
                  if (typeof parentKey == 'undefined' || this.checkStrictly) return;
d44420be   Sergio Crisostomo   refactor and make...
120
121
122
123
124
125
  
                  const node = this.flatState[nodeKey].node;
                  const parent = this.flatState[parentKey].node;
                  if (node.checked == parent.checked && node.indeterminate == parent.indeterminate) return; // no need to update upwards
  
                  if (node.checked == true) {
0985c87b   vanppo   :bug: Fix issue #...
126
                      this.$set(parent, 'checked', parent[this.childrenKey].every(node => node.checked));
d44420be   Sergio Crisostomo   refactor and make...
127
128
129
                      this.$set(parent, 'indeterminate', !parent.checked);
                  } else {
                      this.$set(parent, 'checked', false);
0985c87b   vanppo   :bug: Fix issue #...
130
                      this.$set(parent, 'indeterminate', parent[this.childrenKey].some(node => node.checked || node.indeterminate));
d44420be   Sergio Crisostomo   refactor and make...
131
132
133
134
135
136
137
138
139
                  }
                  this.updateTreeUp(parentKey);
              },
              rebuildTree () { // only called when `data` prop changes
                  const checkedNodes = this.getCheckedNodes();
                  checkedNodes.forEach(node => {
                      this.updateTreeDown(node, {checked: true});
                      // propagate upwards
                      const parentKey = this.flatState[node.nodeKey].parent;
0a8f9b43   Sergio Crisostomo   Keep original dat...
140
                      if (!parentKey && parentKey !== 0) return;
d44420be   Sergio Crisostomo   refactor and make...
141
142
143
144
145
146
147
148
                      const parent = this.flatState[parentKey].node;
                      const childHasCheckSetter = typeof node.checked != 'undefined' && node.checked;
                      if (childHasCheckSetter && parent.checked != node.checked) {
                          this.updateTreeUp(node.nodeKey); // update tree upwards
                      }
                  });
              },
  
cb84e64a   梁灏   update Tree
149
              getSelectedNodes () {
d44420be   Sergio Crisostomo   refactor and make...
150
151
                  /* public API */
                  return this.flatState.filter(obj => obj.node.selected).map(obj => obj.node);
cb84e64a   梁灏   update Tree
152
              },
53754a31   梁灏   fixed #468
153
              getCheckedNodes () {
d44420be   Sergio Crisostomo   refactor and make...
154
155
                  /* public API */
                  return this.flatState.filter(obj => obj.node.checked).map(obj => obj.node);
53754a31   梁灏   fixed #468
156
              },
c1f0fc86   恩升   树控件增加一个方法getCheck...
157
158
159
160
              getCheckedAndIndeterminateNodes () {
                  /* public API */
                  return this.flatState.filter(obj => (obj.node.checked || obj.node.indeterminate)).map(obj => obj.node);
              },
d44420be   Sergio Crisostomo   refactor and make...
161
              updateTreeDown(node, changes = {}) {
05f490ef   Aresn   Update tree.vue
162
163
                  if (this.checkStrictly) return;
  
d44420be   Sergio Crisostomo   refactor and make...
164
165
                  for (let key in changes) {
                      this.$set(node, key, changes[key]);
e81207a2   梁灏   update Tree
166
                  }
0985c87b   vanppo   :bug: Fix issue #...
167
168
                  if (node[this.childrenKey]) {
                      node[this.childrenKey].forEach(child => {
d44420be   Sergio Crisostomo   refactor and make...
169
170
                          this.updateTreeDown(child, changes);
                      });
e81207a2   梁灏   update Tree
171
                  }
d44420be   Sergio Crisostomo   refactor and make...
172
173
174
              },
              handleSelect (nodeKey) {
                  const node = this.flatState[nodeKey].node;
af7d72b4   梁灏   update Tree selected
175
                  if (!this.multiple){ // reset previously selected node
d44420be   Sergio Crisostomo   refactor and make...
176
                      const currentSelectedKey = this.flatState.findIndex(obj => obj.node.selected);
af7d72b4   梁灏   update Tree selected
177
                      if (currentSelectedKey >= 0 && currentSelectedKey !== nodeKey) this.$set(this.flatState[currentSelectedKey].node, 'selected', false);
d44420be   Sergio Crisostomo   refactor and make...
178
179
180
                  }
                  this.$set(node, 'selected', !node.selected);
  
700a3707   qq240814476   tree on-select-ch...
181
                  this.$emit('on-select-change', this.getSelectedNodes(), node);
d44420be   Sergio Crisostomo   refactor and make...
182
183
184
185
186
187
188
189
190
              },
              handleCheck({ checked, nodeKey }) {
                  const node = this.flatState[nodeKey].node;
                  this.$set(node, 'checked', checked);
                  this.$set(node, 'indeterminate', false);
  
                  this.updateTreeUp(nodeKey); // propagate up
                  this.updateTreeDown(node, {checked, indeterminate: false}); // reset `indeterminate` when going down
  
700a3707   qq240814476   tree on-select-ch...
191
                  this.$emit('on-check-change', this.getCheckedNodes(), node);
69a10b78   梁灏   fixed #787
192
              }
d44420be   Sergio Crisostomo   refactor and make...
193
194
195
196
197
198
199
200
201
          },
          created(){
              this.flatState = this.compileFlatState();
              this.rebuildTree();
          },
          mounted () {
              this.$on('on-check', this.handleCheck);
              this.$on('on-selected', this.handleSelect);
              this.$on('toggle-expand', node => this.$emit('on-toggle-expand', node));
e81207a2   梁灏   update Tree
202
          }
89f2ba8b   梁灏   init Tree component
203
      };
d44420be   Sergio Crisostomo   refactor and make...
204
  </script>