Commit cb84e64aabecf9419d2ffdbf0183a97eca5f98f4

Authored by 梁灏
1 parent 75c32d5f

update Tree

src/components/tree2/node.vue renamed to src/components/tree/node.vue
src/components/tree/tree.vue
1 <template> 1 <template>
2 - <ul :class="classes">  
3 - <li v-for="(item, index) in data" :class="itemCls(item)">  
4 - <span :class="arrowCls(item)" @click="setExpand(item.disabled, index)">  
5 - <Icon type="arrow-right-b"></Icon>  
6 - </span>  
7 - <Checkbox  
8 - v-if="showCheckbox"  
9 - :value="item.checked && item.childrenCheckedStatus == 2"  
10 - :disabled="item.disabled || item.disableCheckbox"  
11 - :indeterminate="item.checked && item.childrenCheckedStatus == 1"  
12 - @click.native.prevent="setCheck(item.disabled||item.disableCheckbox, index)"></Checkbox>  
13 - <a :class="titleCls(item)" @click="setSelect(item.disabled, index)">  
14 - <span :class="[prefixCls + '-title']" v-html="item.title"></span>  
15 - </a>  
16 - <transition name="slide-up">  
17 - <Tree  
18 - v-if="!item.isLeaf"  
19 - v-show="item.expand"  
20 - :class="expandCls(item)"  
21 - :data="item.children"  
22 - :name="name+'.'+index"  
23 - :multiple="multiple"  
24 - :show-checkbox="showCheckbox"></Tree>  
25 - </transition>  
26 - </li>  
27 - </ul> 2 + <div :class="prefixCls">
  3 + <Tree-node
  4 + v-for="item in currentData"
  5 + :key="item"
  6 + :data="item"
  7 + visible
  8 + :multiple="multiple"
  9 + :show-checkbox="showCheckbox">
  10 + </Tree-node>
  11 + </div>
28 </template> 12 </template>
29 <script> 13 <script>
30 - import Icon from '../icon/icon.vue';  
31 - import Checkbox from '../checkbox/checkbox.vue';  
32 - import { t } from '../../locale'; 14 + import TreeNode from './node.vue';
  15 + import { findComponentsDownward } from '../../utils/assist';
33 import Emitter from '../../mixins/emitter'; 16 import Emitter from '../../mixins/emitter';
34 - import { findComponentUpward, findComponentDownward } from '../../utils/assist'; 17 + import { t } from '../../locale';
35 18
36 const prefixCls = 'ivu-tree'; 19 const prefixCls = 'ivu-tree';
37 20
38 export default { 21 export default {
39 name: 'Tree', 22 name: 'Tree',
40 - components: { Icon, Checkbox },  
41 mixins: [ Emitter ], 23 mixins: [ Emitter ],
  24 + components: { TreeNode },
42 props: { 25 props: {
43 data: { 26 data: {
44 type: Array, 27 type: Array,
@@ -46,10 +29,6 @@ @@ -46,10 +29,6 @@
46 return []; 29 return [];
47 } 30 }
48 }, 31 },
49 - name: {  
50 - type: String,  
51 - default: '0'  
52 - },  
53 multiple: { 32 multiple: {
54 type: Boolean, 33 type: Boolean,
55 default: false 34 default: false
@@ -67,274 +46,67 @@ @@ -67,274 +46,67 @@
67 }, 46 },
68 data () { 47 data () {
69 return { 48 return {
70 - prefixCls: prefixCls 49 + prefixCls: prefixCls,
  50 + currentData: this.data
71 }; 51 };
72 }, 52 },
73 - computed: {  
74 - classes () {  
75 - if (this.name === '0') {  
76 - return this.prefixCls;  
77 - } else {  
78 - return `${this.prefixCls}-child-tree`;  
79 - }  
80 - }  
81 - },  
82 watch: { 53 watch: {
83 - data () {  
84 - if (this.name === '0') {  
85 - this.setKey();  
86 - this.preHandle();  
87 - } 54 + data (val) {
  55 +
88 } 56 }
89 }, 57 },
90 methods: { 58 methods: {
91 - itemCls (item) {  
92 - return [  
93 - {  
94 - [`${prefixCls}-item-disabled`]: item.disabled  
95 - }  
96 - ];  
97 - },  
98 - arrowCls (item) {  
99 - return [  
100 - `${this.prefixCls}-switcher`,  
101 - {  
102 - [`${this.prefixCls}-switcher-disabled`]: item.disabled,  
103 - [`${this.prefixCls}-noline_close`]: !item.expand && !item.isLeaf,  
104 - [`${this.prefixCls}-noline_open`]: item.expand && !item.isLeaf,  
105 - [`${this.prefixCls}-switcher-noop`]: item.isLeaf  
106 - }  
107 - ];  
108 - },  
109 - titleCls (item) {  
110 - return [  
111 - {  
112 - [`${this.prefixCls}-node-selected`]: item.selected  
113 - }  
114 - ];  
115 - },  
116 - expandCls (item) {  
117 - return [  
118 - {  
119 - [`${this.prefixCls}-child-tree-open`]: item.expand  
120 - }  
121 - ];  
122 - },  
123 - setKey () {  
124 - for (let i = 0; i < this.data.length; i++) {  
125 - this.data[i].name = `${this.name}.${i}`;  
126 - }  
127 - },  
128 - preHandle () {  
129 - for (let [i, item] of this.data.entries()) {  
130 - if (!item.children || !item.children.length) {  
131 -// this.$set(`data[${i}].isLeaf`, true);  
132 -// this.$set(`data[${i}].childrenCheckedStatus`, 2);  
133 - this.$set(this.data[i], 'isLeaf', true);  
134 - this.$set(this.data[i], 'childrenCheckedStatus', 2);  
135 - continue;  
136 - }  
137 - if (item.checked && !item.childrenCheckedStatus) {  
138 -// this.$set(`data[${i}].childrenCheckedStatus`, 2);  
139 - this.$set(this.data[i], 'childrenCheckedStatus', 2);  
140 -// this.$broadcast('parentChecked', true, `${this.name}.${i}`);  
141 - this.broadcast('Tree', 'parentChecked', {  
142 - status: true,  
143 - name: `${this.name}.${i}` 59 + getSelectedNodes () {
  60 + const nodes = findComponentsDownward(this, 'TreeNode');
  61 + return nodes.filter(node => node.data.selected).map(node => node.data);
  62 + },
  63 + updateData () {
  64 + // init checked status
  65 + function reverseChecked(data) {
  66 + if (data.children) {
  67 + let checkedLength = 0;
  68 + data.children.forEach(node => {
  69 + if (node.children) node = reverseChecked(node);
  70 + if (node.checked) checkedLength++;
144 }); 71 });
  72 +// data.checked = checkedLength >= data.children.length;
  73 + if (checkedLength >= data.children.length) data.checked = true;
  74 + return data;
145 } else { 75 } else {
146 - let status = this.getChildrenCheckedStatus(item.children);  
147 -// this.$set(`data[${i}].childrenCheckedStatus`, status);  
148 - this.$set(this.data[i], 'childrenCheckedStatus', status);  
149 -// if (status !== 0) this.$set(`data[${i}].checked`, true);  
150 - if (status !== 0) this.$set(this.data[i], 'checked', true); 76 + return data;
151 } 77 }
152 } 78 }
153 - },  
154 - setExpand (disabled, index) {  
155 - if (!disabled) {  
156 -// this.$set(`data[${index}].expand`, !this.data[index].expand);  
157 - this.$set(this.data[index], 'expand', !this.data[index].expand);  
158 - }  
159 - },  
160 - setSelect (disabled, index) {  
161 - if (!disabled) {  
162 - const selected = !this.data[index].selected;  
163 - if (this.multiple || !selected) {  
164 -// this.$set(`data[${index}].selected`, selected);  
165 - this.$set(this.data[index], 'selected', selected);  
166 - } else {  
167 - for (let i = 0; i < this.data.length; i++) {  
168 - if (i == index) {  
169 -// this.$set(`data[${i}].selected`, true);  
170 - this.$set(this.data[i], 'selected', true);  
171 - } else {  
172 -// this.$set(`data[${i}].selected`, false);  
173 - this.$set(this.data[i], 'selected', false);  
174 - }  
175 - }  
176 - }  
177 -// this.$dispatch('nodeSelected', this, selected);  
178 - const parentTree = findComponentUpward(this, 'Tree');  
179 - if (parentTree) {  
180 - this.dispatch('Tree', 'nodeSelected', {  
181 - ori: this,  
182 - selected: selected 79 +
  80 + function forwardChecked(data) {
  81 + if (data.children) {
  82 + data.children.forEach(node => {
  83 + if (data.checked) node.checked = true;
  84 + if (node.children) node = forwardChecked(node);
183 }); 85 });
  86 + return data;
184 } else { 87 } else {
185 - this.$emit('nodeSelected', {  
186 - ori: this,  
187 - selected: selected  
188 - }); 88 + return data;
189 } 89 }
190 } 90 }
191 - },  
192 - setCheck (disabled, index) {  
193 - if (disabled) return;  
194 - const checked = !this.data[index].checked;  
195 -// this.$set(`data[${index}].checked`, checked);  
196 - this.$set(this.data[index], 'checked', checked);  
197 -// this.$set(`data[${index}].childrenCheckedStatus`, checked ? 2 : 0);  
198 - this.$set(this.data[index], 'childrenCheckedStatus', checked ? 2 : 0);  
199 -// this.$dispatch('childChecked', this, this.name);  
200 - this.dispatch('Tree', 'childChecked', {  
201 - ori: this,  
202 - name: this.name  
203 - });  
204 -// this.$broadcast('parentChecked', checked, `${this.name}.${index}`);  
205 - this.broadcast('Tree', 'parentChecked', {  
206 - status: checked,  
207 - name: `${this.name}.${index}`  
208 - });  
209 - },  
210 - getNodes (data, opt) {  
211 - data = data || this.data;  
212 - let res = [];  
213 - for (let node of data) {  
214 - let tmp = true;  
215 - for (let [key, value] of Object.entries(opt)) {  
216 - if (node[key] != value) {  
217 - tmp = false;  
218 - break;  
219 - }  
220 - }  
221 - if (tmp) {  
222 - res.push(node);  
223 - }  
224 - if (node.children && node.children.length) {  
225 - res = res.concat(this.getNodes(node.children, opt));  
226 - }  
227 - }  
228 - return res;  
229 - },  
230 - getSelectedNodes () {  
231 - return this.getNodes(this.data, {selected: true});  
232 - },  
233 - getCheckedNodes () {  
234 - return this.getNodes(this.data, {checked: true, childrenCheckedStatus: 2});  
235 - },  
236 - getChildrenCheckedStatus (children) {  
237 - let checkNum = 0, child_childrenAllChecked = true;  
238 - for (let child of children) {  
239 - if (child.checked) {  
240 - checkNum++;  
241 - }  
242 - if (child.childrenCheckedStatus !== 2) {  
243 - child_childrenAllChecked = false;  
244 - }  
245 - }  
246 - // select all  
247 - if (checkNum == children.length) {  
248 - return child_childrenAllChecked ? 2 : 1;  
249 - // select some  
250 - } else if (checkNum > 0) {  
251 - return 1;  
252 - } else {  
253 - return 0;  
254 - } 91 + this.currentData = this.data.map(node => reverseChecked(node)).map(node => forwardChecked(node));
  92 + this.broadcast('TreeNode', 'indeterminate');
255 } 93 }
256 }, 94 },
257 mounted () { 95 mounted () {
258 - this.setKey();  
259 - this.preHandle(); 96 + this.updateData();
260 97
261 -// this.$on('nodeSelected', (ori, selected) => {  
262 - this.$on('nodeSelected', (params) => {  
263 - const ori = params.ori;  
264 - const selected = params.selected;  
265 -  
266 - if (this.name !== '0') return true;  
267 - if (!this.multiple && selected) {  
268 - if (this !== ori) {  
269 - for (let i = 0; i < this.data.length; i++) {  
270 -// this.$set(`data[${i}].selected`, false);  
271 - this.$set(this.data[i], 'selected', false);  
272 - }  
273 - }  
274 -// this.$broadcast('cancelSelected', ori);  
275 - this.broadcast('Tree', 'cancelSelected', ori);  
276 - }  
277 - this.$nextTick(() => {  
278 - this.$emit('on-select-change', this.getSelectedNodes()); 98 + this.$on('selected', ori => {
  99 + const nodes = findComponentsDownward(this, 'TreeNode');
  100 + nodes.forEach(node => {
  101 + this.$set(node.data, 'selected', false);
279 }); 102 });
  103 + this.$set(ori, 'selected', true);
280 }); 104 });
281 - this.$on('cancelSelected', ori => {  
282 - console.log(191)  
283 -// this.$broadcast('cancelSelected', ori);  
284 - this.broadcast('Tree', 'cancelSelected', ori);  
285 - if (this !== ori) {  
286 - for (let i = 0; i < this.data.length; i++) {  
287 -// this.$set(`data[${i}].selected`, false);  
288 - this.$set(this.data[i], 'selected', false);  
289 - }  
290 - } 105 + this.$on('on-selected', () => {
  106 + this.$emit('on-select-change', this.getSelectedNodes());
291 }); 107 });
292 -// this.$on('parentChecked', (status, name) => {  
293 - this.$on('parentChecked', (params) => {  
294 - const status = params.status;  
295 - const name = params.name;  
296 -  
297 - if (this.name == name || this.name.startsWith(name + '.')) {  
298 - for (let i = 0; i < this.data.length; i++) {  
299 -// this.$set(`data[${i}].checked`, status);  
300 - this.$set(this.data[i], 'checked', status);  
301 -// this.$set(`data[${i}].childrenCheckedStatus`, status ? 2 : 0);  
302 - this.$set(this.data[i], 'childrenCheckedStatus', status ? 2 : 0);  
303 - }  
304 -// this.$broadcast('parentChecked', status, name);  
305 - this.broadcast('Tree', 'parentChecked', {  
306 - status: status,  
307 - name: name  
308 - });  
309 - }  
310 - });  
311 -// this.$on('childChecked', (ori, name) => {  
312 - this.$on('childChecked', (params) => {  
313 - const ori = params.ori;  
314 - const name = params.name;  
315 -  
316 - if (this.name === '0') {  
317 - this.$nextTick(() => {  
318 - this.$emit('on-check-change', this.getCheckedNodes());  
319 - });  
320 - }  
321 - if (this === ori) return;  
322 - for (let [i,item] of this.data.entries()) {  
323 - if (this.name + '.' + i == name) {  
324 - let temp = this.getChildrenCheckedStatus(item.children);  
325 - if (temp != item.childrenCheckedStatus) {  
326 -// this.$set(`data[${i}].checked`, !!temp);  
327 - this.$set(this.data[i], 'checked', !!temp);  
328 -// this.$set(`data[${i}].childrenCheckedStatus`, temp);  
329 - this.$set(this.data[i], 'childrenCheckedStatus', temp);  
330 -// if (this.name !== '0') this.$dispatch('childChecked', this, this.name);  
331 - if (this.name !== '0') this.dispatch('Tree', 'childChecked', {  
332 - ori: this,  
333 - name: this.name  
334 - });  
335 - }  
336 - }  
337 - } 108 + this.$on('checked', () => {
  109 + this.updateData();
338 }); 110 });
339 } 111 }
340 }; 112 };
src/components/tree2/index.js deleted
1 -import Tree from './tree.vue';  
2 -export default Tree;  
3 \ No newline at end of file 0 \ No newline at end of file
src/components/tree2/tree.vue deleted
1 -<template>  
2 - <div :class="prefixCls">  
3 - <Tree-node  
4 - v-for="item in currentData"  
5 - :key="item"  
6 - :data="item"  
7 - visible  
8 - :multiple="multiple"  
9 - :show-checkbox="showCheckbox">  
10 - </Tree-node>  
11 - </div>  
12 -</template>  
13 -<script>  
14 - import TreeNode from './node.vue';  
15 - import { findComponentsDownward } from '../../utils/assist';  
16 - import Emitter from '../../mixins/emitter';  
17 - import { t } from '../../locale';  
18 -  
19 - const prefixCls = 'ivu-tree';  
20 -  
21 - export default {  
22 - name: 'Tree',  
23 - mixins: [ Emitter ],  
24 - components: { TreeNode },  
25 - props: {  
26 - data: {  
27 - type: Array,  
28 - default () {  
29 - return [];  
30 - }  
31 - },  
32 - multiple: {  
33 - type: Boolean,  
34 - default: false  
35 - },  
36 - showCheckbox: {  
37 - type: Boolean,  
38 - default: false  
39 - },  
40 - emptyText: {  
41 - type: String,  
42 - default () {  
43 - return t('i.tree.emptyText');  
44 - }  
45 - }  
46 - },  
47 - data () {  
48 - return {  
49 - prefixCls: prefixCls,  
50 - currentData: this.data  
51 - };  
52 - },  
53 - watch: {  
54 - data (val) {  
55 -  
56 - }  
57 - },  
58 - methods: {  
59 - getSelectedNodes () {  
60 - const nodes = findComponentsDownward(this, 'TreeNode');  
61 - return nodes.filter(node => node.data.selected).map(node => node.data);  
62 - },  
63 - updateData () {  
64 - // init checked status  
65 - function reverseChecked(data) {  
66 - if (data.children) {  
67 - let checkedLength = 0;  
68 - data.children.forEach(node => {  
69 - if (node.children) node = reverseChecked(node);  
70 - if (node.checked) checkedLength++;  
71 - });  
72 -// data.checked = checkedLength >= data.children.length;  
73 - if (checkedLength >= data.children.length) data.checked = true;  
74 - return data;  
75 - } else {  
76 - return data;  
77 - }  
78 - }  
79 -  
80 - function forwardChecked(data) {  
81 - if (data.children) {  
82 - data.children.forEach(node => {  
83 - if (data.checked) node.checked = true;  
84 - if (node.children) node = forwardChecked(node);  
85 - });  
86 - return data;  
87 - } else {  
88 - return data;  
89 - }  
90 - }  
91 - this.currentData = this.data.map(node => reverseChecked(node)).map(node => forwardChecked(node));  
92 - this.broadcast('TreeNode', 'indeterminate');  
93 - }  
94 - },  
95 - mounted () {  
96 - this.updateData();  
97 -  
98 - this.$on('selected', ori => {  
99 - const nodes = findComponentsDownward(this, 'TreeNode');  
100 - nodes.forEach(node => {  
101 - this.$set(node.data, 'selected', false);  
102 - });  
103 - this.$set(ori, 'selected', true);  
104 - });  
105 - this.$on('on-selected', () => {  
106 - this.$emit('on-select-change', this.getSelectedNodes());  
107 - });  
108 - this.$on('checked', () => {  
109 - this.updateData();  
110 - });  
111 - }  
112 - };  
113 -</script>  
114 \ No newline at end of file 0 \ No newline at end of file
@@ -40,7 +40,7 @@ import Timeline from &#39;./components/timeline&#39;; @@ -40,7 +40,7 @@ import Timeline from &#39;./components/timeline&#39;;
40 import TimePicker from './components/time-picker'; 40 import TimePicker from './components/time-picker';
41 import Tooltip from './components/tooltip'; 41 import Tooltip from './components/tooltip';
42 import Transfer from './components/transfer'; 42 import Transfer from './components/transfer';
43 -import Tree from './components/tree2'; 43 +import Tree from './components/tree';
44 import Upload from './components/upload'; 44 import Upload from './components/upload';
45 import { Row, Col } from './components/grid'; 45 import { Row, Col } from './components/grid';
46 import { Select, Option, OptionGroup } from './components/select'; 46 import { Select, Option, OptionGroup } from './components/select';
src/styles/components/tree2.less deleted
1 -@tree-prefix-cls: ~"@{css-prefix}tree";  
2 -  
3 -.@{tree-prefix-cls} {  
4 - margin: 0;  
5 - padding: 5px;  
6 - font-size: @font-size-small;  
7 - li {  
8 - padding: 0;  
9 - margin: 8px 0;  
10 - list-style: none;  
11 - white-space: nowrap;  
12 - outline: 0;  
13 - a[draggable],  
14 - a[draggable="true"] {  
15 - user-select: none;  
16 - /* Required to make elements draggable in old WebKit */  
17 - -khtml-user-drag: element;  
18 - -webkit-user-drag: element;  
19 - }  
20 - &.drag-over {  
21 - > a[draggable] {  
22 - background-color: @primary-color;  
23 - color: white;  
24 - opacity: 0.8;  
25 - }  
26 - }  
27 - &.drag-over-gap-top {  
28 - > a[draggable] {  
29 - border-top: 2px @primary-color solid;  
30 - }  
31 - }  
32 - &.drag-over-gap-bottom {  
33 - > a[draggable] {  
34 - border-bottom: 2px @primary-color solid;  
35 - }  
36 - }  
37 - &.filter-node {  
38 - > a {  
39 - color: @error-color!important;  
40 - font-weight: bold!important;  
41 - }  
42 - }  
43 - ul {  
44 - margin: 0;  
45 - padding: 0 0 0 18px;  
46 - }  
47 - a {  
48 - display: inline-block;  
49 - margin: 0;  
50 - padding: 0 4px;  
51 - border-radius: @btn-border-radius-small;  
52 - cursor: pointer;  
53 - text-decoration: none;  
54 - vertical-align: top;  
55 - color: @text-color;  
56 - transition: all @transition-time @ease-in-out;  
57 - &:hover {  
58 - background-color: tint(@primary-color, 90%);  
59 - }  
60 - &.@{tree-prefix-cls}-node-selected {  
61 - background-color: tint(@primary-color, 80%);  
62 - }  
63 - }  
64 - .@{checkbox-prefix-cls}-wrapper{  
65 - margin-right: 4px;  
66 - }  
67 - span {  
68 - &.@{tree-prefix-cls}-switcher,  
69 - &.@{tree-prefix-cls}-iconEle {  
70 - display: inline-block;  
71 - text-align: center;  
72 - width: 16px;  
73 - height: 16px;  
74 - line-height: 16px;  
75 - margin: 0;  
76 - vertical-align: middle;  
77 - border: 0 none;  
78 - cursor: pointer;  
79 - outline: none;  
80 - }  
81 - //&.@{tree-prefix-cls}-icon_loading {  
82 - // &:after {  
83 - // display: inline-block;  
84 - // //.iconfont-font("\e6a1");  
85 - // animation: loadingCircle 1s infinite linear;  
86 - // color: @primary-color;  
87 - // }  
88 - //}  
89 - &.@{tree-prefix-cls}-switcher {  
90 - i{  
91 - transition: all @transition-time @ease-in-out;  
92 - }  
93 - &.@{tree-prefix-cls}-switcher-noop {  
94 - //display: none;  
95 - cursor: auto;  
96 - i{  
97 - display: none;  
98 - }  
99 - }  
100 - &.@{tree-prefix-cls}-roots_open,  
101 - &.@{tree-prefix-cls}-center_open,  
102 - &.@{tree-prefix-cls}-bottom_open,  
103 - &.@{tree-prefix-cls}-noline_open {  
104 - i {  
105 - transform: rotate(90deg);  
106 - }  
107 - }  
108 - &.@{tree-prefix-cls}-roots_close,  
109 - &.@{tree-prefix-cls}-center_close,  
110 - &.@{tree-prefix-cls}-bottom_close,  
111 - &.@{tree-prefix-cls}-noline_close {  
112 -  
113 - }  
114 - }  
115 - }  
116 - }  
117 - &-child-tree {  
118 - display: none;  
119 - &-open {  
120 - display: block;  
121 - }  
122 - }  
123 - &-treenode-disabled {  
124 - >span,  
125 - >a,  
126 - >a span {  
127 - color: @input-disabled-bg;  
128 - cursor: not-allowed;  
129 - }  
130 - }  
131 - &-icon__open {  
132 - margin-right: 2px;  
133 - vertical-align: top;  
134 - }  
135 - &-icon__close {  
136 - margin-right: 2px;  
137 - vertical-align: top;  
138 - }  
139 -}  
140 \ No newline at end of file 0 \ No newline at end of file