Blame view

src/components/tree/tree.vue 6.87 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
              compileFlatState () { // so we have always a relation parent/children of each node
                  let keyCounter = 0;
                  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;
                          flatTree[parent.nodeKey].children.push(node.nodeKey);
                      }
  
                      if (node.children) {
                          flatTree[node.nodeKey].children = [];
                          node.children.forEach(child => flattenChildren(child, node));
                      }
                  }
                  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) {
                      this.$set(parent, 'checked', parent.children.every(node => node.checked));
                      this.$set(parent, 'indeterminate', !parent.checked);
                  } else {
                      this.$set(parent, 'checked', false);
                      this.$set(parent, 'indeterminate', parent.children.some(node => node.checked || node.indeterminate));
                  }
                  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...
126
                      if (!parentKey && parentKey !== 0) return;
d44420be   Sergio Crisostomo   refactor and make...
127
128
129
130
131
132
133
134
                      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
135
              getSelectedNodes () {
d44420be   Sergio Crisostomo   refactor and make...
136
137
                  /* public API */
                  return this.flatState.filter(obj => obj.node.selected).map(obj => obj.node);
cb84e64a   梁灏   update Tree
138
              },
53754a31   梁灏   fixed #468
139
              getCheckedNodes () {
d44420be   Sergio Crisostomo   refactor and make...
140
141
                  /* public API */
                  return this.flatState.filter(obj => obj.node.checked).map(obj => obj.node);
53754a31   梁灏   fixed #468
142
              },
d44420be   Sergio Crisostomo   refactor and make...
143
144
145
              updateTreeDown(node, changes = {}) {
                  for (let key in changes) {
                      this.$set(node, key, changes[key]);
e81207a2   梁灏   update Tree
146
                  }
d44420be   Sergio Crisostomo   refactor and make...
147
148
149
150
                  if (node.children) {
                      node.children.forEach(child => {
                          this.updateTreeDown(child, changes);
                      });
e81207a2   梁灏   update Tree
151
                  }
d44420be   Sergio Crisostomo   refactor and make...
152
153
154
              },
              handleSelect (nodeKey) {
                  const node = this.flatState[nodeKey].node;
af7d72b4   梁灏   update Tree selected
155
                  if (!this.multiple){ // reset previously selected node
d44420be   Sergio Crisostomo   refactor and make...
156
                      const currentSelectedKey = this.flatState.findIndex(obj => obj.node.selected);
af7d72b4   梁灏   update Tree selected
157
                      if (currentSelectedKey >= 0 && currentSelectedKey !== nodeKey) this.$set(this.flatState[currentSelectedKey].node, 'selected', false);
d44420be   Sergio Crisostomo   refactor and make...
158
159
160
                  }
                  this.$set(node, 'selected', !node.selected);
  
cb84e64a   梁灏   update Tree
161
                  this.$emit('on-select-change', this.getSelectedNodes());
d44420be   Sergio Crisostomo   refactor and make...
162
163
164
165
166
167
168
169
170
              },
              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
171
                  this.$emit('on-check-change', this.getCheckedNodes());
69a10b78   梁灏   fixed #787
172
              }
d44420be   Sergio Crisostomo   refactor and make...
173
174
175
176
177
178
179
180
181
          },
          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
182
          }
89f2ba8b   梁灏   init Tree component
183
      };
d44420be   Sergio Crisostomo   refactor and make...
184
  </script>