Blame view

src/components/tree/tree.vue 6.97 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 },
e81207a2   梁灏   update Tree
26
          props: {
9d79a51f   梁灏   update Tree
27
              data: {
e81207a2   梁灏   update Tree
28
29
30
31
32
                  type: Array,
                  default () {
                      return [];
                  }
              },
e81207a2   梁灏   update Tree
33
34
35
36
37
38
39
40
              multiple: {
                  type: Boolean,
                  default: false
              },
              showCheckbox: {
                  type: Boolean,
                  default: false
              },
e81207a2   梁灏   update Tree
41
              emptyText: {
e5337c81   梁灏   fixed some compon...
42
                  type: String
b31aab71   梁灏   Tree add async lo...
43
              },
56c7cc0e   vanppo   Add new props 'ch...
44
45
46
47
              childrenKey: {
                  type: String,
                  default: 'children'
              },
b31aab71   梁灏   Tree add async lo...
48
49
              loadData: {
                  type: Function
174836c4   梁灏   update Tree Rende...
50
51
52
              },
              render: {
                  type: Function
e81207a2   梁灏   update Tree
53
54
              }
          },
89f2ba8b   梁灏   init Tree component
55
          data () {
e81207a2   梁灏   update Tree
56
              return {
d44420be   Sergio Crisostomo   refactor and make...
57
                  prefixCls: prefixCls,
0a8f9b43   Sergio Crisostomo   Keep original dat...
58
                  stateTree: this.data,
d44420be   Sergio Crisostomo   refactor and make...
59
                  flatState: [],
e81207a2   梁灏   update Tree
60
              };
89f2ba8b   梁灏   init Tree component
61
          },
d44420be   Sergio Crisostomo   refactor and make...
62
          watch: {
76a47814   梁灏   fixed #2128
63
64
65
66
67
68
69
              data: {
                  deep: true,
                  handler () {
                      this.stateTree = this.data;
                      this.flatState = this.compileFlatState();
                      this.rebuildTree();
                  }
d44420be   Sergio Crisostomo   refactor and make...
70
71
              }
          },
e5337c81   梁灏   fixed some compon...
72
73
          computed: {
              localeEmptyText () {
d44420be   Sergio Crisostomo   refactor and make...
74
                  if (typeof this.emptyText === 'undefined') {
e5337c81   梁灏   fixed some compon...
75
76
77
78
                      return this.t('i.tree.emptyText');
                  } else {
                      return this.emptyText;
                  }
d44420be   Sergio Crisostomo   refactor and make...
79
              },
e5337c81   梁灏   fixed some compon...
80
          },
e81207a2   梁灏   update Tree
81
          methods: {
d44420be   Sergio Crisostomo   refactor and make...
82
83
              compileFlatState () { // so we have always a relation parent/children of each node
                  let keyCounter = 0;
0985c87b   vanppo   :bug: Fix issue #...
84
                  let childrenKey = this.childrenKey;
d44420be   Sergio Crisostomo   refactor and make...
85
86
87
88
89
90
                  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 #...
91
                          flatTree[parent.nodeKey][childrenKey].push(node.nodeKey);
d44420be   Sergio Crisostomo   refactor and make...
92
93
                      }
  
0985c87b   vanppo   :bug: Fix issue #...
94
95
96
                      if (node[childrenKey]) {
                          flatTree[node.nodeKey][childrenKey] = [];
                          node[childrenKey].forEach(child => flattenChildren(child, node));
d44420be   Sergio Crisostomo   refactor and make...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
                      }
                  }
                  this.stateTree.forEach(rootNode => {
                      flattenChildren(rootNode);
                  });
                  return flatTree;
              },
              updateTreeUp(nodeKey){
                  const parentKey = this.flatState[nodeKey].parent;
                  if (typeof parentKey == 'undefined') return;
  
                  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 #...
113
                      this.$set(parent, 'checked', parent[this.childrenKey].every(node => node.checked));
d44420be   Sergio Crisostomo   refactor and make...
114
115
116
                      this.$set(parent, 'indeterminate', !parent.checked);
                  } else {
                      this.$set(parent, 'checked', false);
0985c87b   vanppo   :bug: Fix issue #...
117
                      this.$set(parent, 'indeterminate', parent[this.childrenKey].some(node => node.checked || node.indeterminate));
d44420be   Sergio Crisostomo   refactor and make...
118
119
120
121
122
123
124
125
126
                  }
                  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...
127
                      if (!parentKey && parentKey !== 0) return;
d44420be   Sergio Crisostomo   refactor and make...
128
129
130
131
132
133
134
135
                      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
136
              getSelectedNodes () {
d44420be   Sergio Crisostomo   refactor and make...
137
138
                  /* public API */
                  return this.flatState.filter(obj => obj.node.selected).map(obj => obj.node);
cb84e64a   梁灏   update Tree
139
              },
53754a31   梁灏   fixed #468
140
              getCheckedNodes () {
d44420be   Sergio Crisostomo   refactor and make...
141
142
                  /* public API */
                  return this.flatState.filter(obj => obj.node.checked).map(obj => obj.node);
53754a31   梁灏   fixed #468
143
              },
d44420be   Sergio Crisostomo   refactor and make...
144
145
146
              updateTreeDown(node, changes = {}) {
                  for (let key in changes) {
                      this.$set(node, key, changes[key]);
e81207a2   梁灏   update Tree
147
                  }
0985c87b   vanppo   :bug: Fix issue #...
148
149
                  if (node[this.childrenKey]) {
                      node[this.childrenKey].forEach(child => {
d44420be   Sergio Crisostomo   refactor and make...
150
151
                          this.updateTreeDown(child, changes);
                      });
e81207a2   梁灏   update Tree
152
                  }
d44420be   Sergio Crisostomo   refactor and make...
153
154
155
              },
              handleSelect (nodeKey) {
                  const node = this.flatState[nodeKey].node;
af7d72b4   梁灏   update Tree selected
156
                  if (!this.multiple){ // reset previously selected node
d44420be   Sergio Crisostomo   refactor and make...
157
                      const currentSelectedKey = this.flatState.findIndex(obj => obj.node.selected);
af7d72b4   梁灏   update Tree selected
158
                      if (currentSelectedKey >= 0 && currentSelectedKey !== nodeKey) this.$set(this.flatState[currentSelectedKey].node, 'selected', false);
d44420be   Sergio Crisostomo   refactor and make...
159
160
161
                  }
                  this.$set(node, 'selected', !node.selected);
  
cb84e64a   梁灏   update Tree
162
                  this.$emit('on-select-change', this.getSelectedNodes());
d44420be   Sergio Crisostomo   refactor and make...
163
164
165
166
167
168
169
170
171
              },
              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
  
53754a31   梁灏   fixed #468
172
                  this.$emit('on-check-change', this.getCheckedNodes());
69a10b78   梁灏   fixed #787
173
              }
d44420be   Sergio Crisostomo   refactor and make...
174
175
176
177
178
179
180
181
182
          },
          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
183
          }
89f2ba8b   梁灏   init Tree component
184
      };
d44420be   Sergio Crisostomo   refactor and make...
185
  </script>