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 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 12 </template>
29 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 16 import Emitter from '../../mixins/emitter';
34   - import { findComponentUpward, findComponentDownward } from '../../utils/assist';
  17 + import { t } from '../../locale';
35 18  
36 19 const prefixCls = 'ivu-tree';
37 20  
38 21 export default {
39 22 name: 'Tree',
40   - components: { Icon, Checkbox },
41 23 mixins: [ Emitter ],
  24 + components: { TreeNode },
42 25 props: {
43 26 data: {
44 27 type: Array,
... ... @@ -46,10 +29,6 @@
46 29 return [];
47 30 }
48 31 },
49   - name: {
50   - type: String,
51   - default: '0'
52   - },
53 32 multiple: {
54 33 type: Boolean,
55 34 default: false
... ... @@ -67,274 +46,67 @@
67 46 },
68 47 data () {
69 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 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 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 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 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 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 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 0 \ No newline at end of file
src/index.js
... ... @@ -40,7 +40,7 @@ import Timeline from &#39;./components/timeline&#39;;
40 40 import TimePicker from './components/time-picker';
41 41 import Tooltip from './components/tooltip';
42 42 import Transfer from './components/transfer';
43   -import Tree from './components/tree2';
  43 +import Tree from './components/tree';
44 44 import Upload from './components/upload';
45 45 import { Row, Col } from './components/grid';
46 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 0 \ No newline at end of file