Commit bd4e3b9b0a2a91a0c19e3ac7c3c2c23396c7c1da

Authored by 梁灏
1 parent c463ab87

update Cascader

update Cascader
src/components/cascader/cascader.vue
@@ -12,11 +12,12 @@ @@ -12,11 +12,12 @@
12 <Dropdown v-show="visible" transition="slide-up"> 12 <Dropdown v-show="visible" transition="slide-up">
13 <div> 13 <div>
14 <Caspanel 14 <Caspanel
  15 + v-ref:caspanel
15 :prefix-cls="prefixCls" 16 :prefix-cls="prefixCls"
16 :data.sync="data" 17 :data.sync="data"
17 :disabled="disabled" 18 :disabled="disabled"
18 - :trigger="trigger"  
19 - @on-update-result="updateResult"></Caspanel> 19 + :change-on-select="changeOnSelect"
  20 + :trigger="trigger"></Caspanel>
20 </div> 21 </div>
21 </Dropdown> 22 </Dropdown>
22 </div> 23 </div>
@@ -74,7 +75,7 @@ @@ -74,7 +75,7 @@
74 renderFormat: { 75 renderFormat: {
75 type: Function, 76 type: Function,
76 default (label, selectedData) { 77 default (label, selectedData) {
77 - return label.join('/'); 78 + return label.join(' / ');
78 } 79 }
79 } 80 }
80 }, 81 },
@@ -118,12 +119,46 @@ @@ -118,12 +119,46 @@
118 this.visible = true; 119 this.visible = true;
119 }, 120 },
120 updateResult (result) { 121 updateResult (result) {
121 - console.log(JSON.stringify(result))  
122 - this.selected = result; 122 + this.tmpSelected = result;
  123 + },
  124 + updateSelected () {
  125 + this.$broadcast('on-find-selected', this.value);
123 } 126 }
124 }, 127 },
125 ready () { 128 ready () {
  129 + this.updateSelected();
  130 + },
  131 + events: {
  132 + // lastValue: is click the final val
  133 + // fromInit: is this emit from update value
  134 + 'on-result-change' (lastValue, changeOnSelect, fromInit) {
  135 + if (lastValue || changeOnSelect) {
  136 + const oldVal = JSON.stringify(this.value);
  137 + this.selected = this.tmpSelected;
  138 +
  139 + let newVal = [];
  140 + this.selected.forEach((item) => {
  141 + newVal.push(item.value);
  142 + });
  143 + this.value = newVal;
126 144
  145 + if (JSON.stringify(this.value) !== oldVal) {
  146 + this.$emit('on-change', this.value);
  147 + }
  148 + }
  149 + if (lastValue && !fromInit) {
  150 + this.handleClose();
  151 + }
  152 + }
  153 + },
  154 + watch: {
  155 + visible (val) {
  156 + if (val) {
  157 + if (this.value.length) {
  158 + this.updateSelected();
  159 + }
  160 + }
  161 + }
127 } 162 }
128 } 163 }
129 </script> 164 </script>
130 \ No newline at end of file 165 \ No newline at end of file
src/components/cascader/casitem.vue
@@ -13,7 +13,8 @@ @@ -13,7 +13,8 @@
13 return [ 13 return [
14 `${this.prefixCls}-menu-item`, 14 `${this.prefixCls}-menu-item`,
15 { 15 {
16 - [`${this.prefixCls}-menu-item-active`]: this.tmpItem.value === this.data.value 16 + [`${this.prefixCls}-menu-item-active`]: this.tmpItem.value === this.data.value,
  17 + [`${this.prefixCls}-menu-item-disabled`]: this.data.disabled
17 } 18 }
18 ] 19 ]
19 } 20 }
src/components/cascader/caspanel.vue
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 :tmp-item="tmpItem" 7 :tmp-item="tmpItem"
8 @click.stop="handleClickItem(item)" 8 @click.stop="handleClickItem(item)"
9 @mouseenter.stop="handleHoverItem(item)"></Casitem> 9 @mouseenter.stop="handleHoverItem(item)"></Casitem>
10 - </ul><Caspanel v-if="sublist && sublist.length" :prefix-cls="prefixCls" :data.sync="sublist" :disabled="disabled" :trigger="trigger" @on-update-result="updateResult"></Caspanel> 10 + </ul><Caspanel v-if="sublist && sublist.length" :prefix-cls="prefixCls" :data.sync="sublist" :disabled="disabled" :trigger="trigger" :change-on-select="changeOnSelect"></Caspanel>
11 </template> 11 </template>
12 <script> 12 <script>
13 import Casitem from './casitem.vue'; 13 import Casitem from './casitem.vue';
@@ -31,11 +31,7 @@ @@ -31,11 +31,7 @@
31 }, 31 },
32 disabled: Boolean, 32 disabled: Boolean,
33 changeOnSelect: Boolean, 33 changeOnSelect: Boolean,
34 - trigger: {  
35 - validator (value) {  
36 - return oneOf(value, ['click', 'hover']);  
37 - }  
38 - }, 34 + trigger: String,
39 prefixCls: String 35 prefixCls: String
40 }, 36 },
41 data () { 37 data () {
@@ -46,33 +42,32 @@ @@ -46,33 +42,32 @@
46 }, 42 },
47 methods: { 43 methods: {
48 handleClickItem (item) { 44 handleClickItem (item) {
49 - if (this.trigger !== 'click') return; 45 + if (this.trigger !== 'click' && item.children) return;
50 this.handleTriggerItem(item); 46 this.handleTriggerItem(item);
51 }, 47 },
52 handleHoverItem (item) { 48 handleHoverItem (item) {
53 - if (this.trigger !== 'hover') return; 49 + if (this.trigger !== 'hover' || !item.children) return;
54 this.handleTriggerItem(item); 50 this.handleTriggerItem(item);
55 }, 51 },
56 - handleTriggerItem (item) { 52 + handleTriggerItem (item, fromInit = false) {
57 if (item.disabled) return; 53 if (item.disabled) return;
58 54
  55 + // return value back recursion
  56 + const backItem = this.getBaseItem(item);
  57 + this.tmpItem = backItem;
  58 + this.emitUpdate([backItem]);
  59 +
59 if (item.children && item.children.length){ 60 if (item.children && item.children.length){
60 this.sublist = item.children; 61 this.sublist = item.children;
61 - // todo 实时选择 62 + this.$dispatch('on-result-change', false, this.changeOnSelect, fromInit);
62 } else { 63 } else {
63 this.sublist = []; 64 this.sublist = [];
64 - // todo 选择 65 + this.$dispatch('on-result-change', true, this.changeOnSelect, fromInit);
65 } 66 }
66 -  
67 - // return value back  
68 - const backItem = this.getBaseItem(item);  
69 -  
70 - this.tmpItem = backItem;  
71 - this.$emit('on-update-result', [backItem]);  
72 }, 67 },
73 updateResult (item) { 68 updateResult (item) {
74 this.result = [this.tmpItem].concat(item); 69 this.result = [this.tmpItem].concat(item);
75 - this.$emit('on-update-result', this.result); 70 + this.emitUpdate(this.result);
76 }, 71 },
77 getBaseItem (item) { 72 getBaseItem (item) {
78 let backItem = Object.assign({}, item); 73 let backItem = Object.assign({}, item);
@@ -81,6 +76,13 @@ @@ -81,6 +76,13 @@
81 } 76 }
82 77
83 return backItem; 78 return backItem;
  79 + },
  80 + emitUpdate (result) {
  81 + if (this.$parent.$options.name === 'Caspanel') {
  82 + this.$parent.updateResult(result);
  83 + } else {
  84 + this.$parent.$parent.updateResult(result);
  85 + }
84 } 86 }
85 }, 87 },
86 watch: { 88 watch: {
@@ -88,8 +90,22 @@ @@ -88,8 +90,22 @@
88 this.sublist = []; 90 this.sublist = [];
89 } 91 }
90 }, 92 },
91 - ready () {  
92 - // todo 初始化时,判断预设的值 93 + events: {
  94 + 'on-find-selected' (val) {
  95 + let value = [...val];
  96 + for (let i = 0; i < value.length; i++) {
  97 + for (let j = 0; j < this.data.length; j++) {
  98 + if (value[i] === this.data[j].value) {
  99 + this.handleTriggerItem(this.data[j], true);
  100 + value.splice(0, 1);
  101 + this.$nextTick(() => {
  102 + this.$broadcast('on-find-selected', value);
  103 + });
  104 + return false;
  105 + }
  106 + }
  107 + }
  108 + }
93 } 109 }
94 } 110 }
95 </script> 111 </script>
96 \ No newline at end of file 112 \ No newline at end of file
test/routers/cascader.vue
1 <template> 1 <template>
2 <div style="margin: 50px;width:300px"> 2 <div style="margin: 50px;width:300px">
3 - <Cascader :data="data" :value="value"></Cascader> 3 + <Cascader :data="data" :value.sync="value" @on-change="change" trigger="click"></Cascader>
4 </div> 4 </div>
5 </template> 5 </template>
6 <script> 6 <script>
@@ -11,7 +11,8 @@ @@ -11,7 +11,8 @@
11 }, 11 },
12 data () { 12 data () {
13 return { 13 return {
14 - value: [], 14 + value: ['jiangsu', 'hhh', 'ddd'],
  15 +// value: [],
15 data: [{ 16 data: [{
16 value: 'zhejiang', 17 value: 'zhejiang',
17 label: 'Zhejiang', 18 label: 'Zhejiang',
@@ -25,6 +26,7 @@ @@ -25,6 +26,7 @@
25 children: [{ 26 children: [{
26 value: 'nanjing', 27 value: 'nanjing',
27 label: 'Nanjing', 28 label: 'Nanjing',
  29 +// disabled: true,
28 children: [{ 30 children: [{
29 value: 'zhonghuamen', 31 value: 'zhonghuamen',
30 label: 'Zhong Hua Men', 32 label: 'Zhong Hua Men',
@@ -48,7 +50,9 @@ @@ -48,7 +50,9 @@
48 50
49 }, 51 },
50 methods: { 52 methods: {
51 - 53 + change (data) {
  54 + console.log(data)
  55 + }
52 } 56 }
53 } 57 }
54 </script> 58 </script>
55 \ No newline at end of file 59 \ No newline at end of file