Blame view

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