Commit f7ffdac56931b17211074c0ac0c41b5a25c946b1

Authored by 梁灏
1 parent 13a940ee

Cascader support loadData async

examples/routers/cascader.vue
1 <template> 1 <template>
2 - <div style="width: 300px;margin: 100px;">  
3 - <Cascader :data="data2" v-model="v1" change-on-select></Cascader>  
4 - </div> 2 + <Row>
  3 + <i-col span="4">
  4 + <Button @click="handleLoad">load</Button>
  5 + </i-col>
  6 + <i-col span="6">
  7 + <!--<Cascader :data="data2" v-model="v1" change-on-select></Cascader>-->
  8 + <Cascader :data="data2" v-model="v1" :loadData="loadData"></Cascader>
  9 + </i-col>
  10 + </Row>
5 </template> 11 </template>
6 <script> 12 <script>
7 export default { 13 export default {
8 data () { 14 data () {
9 return { 15 return {
10 - v1: ['zhejiang'], 16 + v1: [],
11 data2: [{ 17 data2: [{
12 value: 'zhejiang', 18 value: 'zhejiang',
13 label: '浙江', 19 label: '浙江',
14 - children: [{  
15 - value: 'hangzhou',  
16 - label: '杭州',  
17 - children: [{  
18 - value: 'xihu',  
19 - label: '西湖'  
20 - }]  
21 - }] 20 + children: [],
  21 + loading: false
22 }, { 22 }, {
23 value: 'jiangsu', 23 value: 'jiangsu',
24 label: '江苏', 24 label: '江苏',
@@ -32,6 +32,35 @@ @@ -32,6 +32,35 @@
32 }] 32 }]
33 }] 33 }]
34 } 34 }
  35 + },
  36 + methods: {
  37 + handleLoad () {
  38 + this.data2[0].loading = !this.data2[0].loading;
  39 + },
  40 + loadData (item, cb) {
  41 + item.loading = true;
  42 + setTimeout(() => {
  43 + if (item.value === 'zhejiang') {
  44 + item.children = [
  45 + {
  46 + value: 'hangzhou',
  47 + label: '杭州',
  48 + loading: false,
  49 + children: []
  50 + }
  51 + ];
  52 + } else if (item.value === 'hangzhou') {
  53 + item.children = [
  54 + {
  55 + value: 'ali',
  56 + label: '阿里巴巴'
  57 + }
  58 + ];
  59 + }
  60 + item.loading = false;
  61 + cb();
  62 + }, 1000);
  63 + }
35 } 64 }
36 } 65 }
37 </script> 66 </script>
src/components/cascader/cascader.vue
@@ -88,6 +88,9 @@ @@ -88,6 +88,9 @@
88 default (label) { 88 default (label) {
89 return label.join(' / '); 89 return label.join(' / ');
90 } 90 }
  91 + },
  92 + loadData: {
  93 + type: Function
91 } 94 }
92 }, 95 },
93 data () { 96 data () {
@@ -224,8 +227,11 @@ @@ -224,8 +227,11 @@
224 } 227 }
225 this.updateSelected(true); 228 this.updateSelected(true);
226 }, 229 },
227 - data () {  
228 - this.$nextTick(() => this.updateSelected()); 230 + data: {
  231 + deep: true,
  232 + handler () {
  233 + this.$nextTick(() => this.updateSelected());
  234 + }
229 } 235 }
230 } 236 }
231 }; 237 };
src/components/cascader/casitem.vue
1 <template> 1 <template>
2 - <li :class="classes">{{ data.label }}<i v-if="data.children && data.children.length" class="ivu-icon ivu-icon-ios-arrow-right"></i></li> 2 + <li :class="classes">
  3 + {{ data.label }}
  4 + <i v-if="showArrow" class="ivu-icon ivu-icon-ios-arrow-right"></i>
  5 + <i v-if="showLoading" class="ivu-icon ivu-icon-load-c ivu-load-loop"></i>
  6 + </li>
3 </template> 7 </template>
4 <script> 8 <script>
5 export default { 9 export default {
@@ -18,6 +22,12 @@ @@ -18,6 +22,12 @@
18 [`${this.prefixCls}-menu-item-disabled`]: this.data.disabled 22 [`${this.prefixCls}-menu-item-disabled`]: this.data.disabled
19 } 23 }
20 ]; 24 ];
  25 + },
  26 + showArrow () {
  27 + return (this.data.children && this.data.children.length) || ('loading' in this.data && !this.data.loading);
  28 + },
  29 + showLoading () {
  30 + return 'loading' in this.data && this.data.loading;
21 } 31 }
22 } 32 }
23 }; 33 };
src/components/cascader/caspanel.vue
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 <script> 15 <script>
16 import Casitem from './casitem.vue'; 16 import Casitem from './casitem.vue';
17 import Emitter from '../../mixins/emitter'; 17 import Emitter from '../../mixins/emitter';
  18 + import { findComponentUpward } from '../../utils/assist';
18 19
19 export default { 20 export default {
20 name: 'Caspanel', 21 name: 'Caspanel',
@@ -56,6 +57,16 @@ @@ -56,6 +57,16 @@
56 handleTriggerItem (item, fromInit = false) { 57 handleTriggerItem (item, fromInit = false) {
57 if (item.disabled) return; 58 if (item.disabled) return;
58 59
  60 + if (item.loading !== undefined && !item.children.length) {
  61 + const cascader = findComponentUpward(this, 'Cascader');
  62 + if (cascader && cascader.loadData) {
  63 + cascader.loadData(item, () => {
  64 + this.handleTriggerItem(item);
  65 + });
  66 + return;
  67 + }
  68 + }
  69 +
59 // return value back recursion // 向上递归,设置临时选中值(并非真实选中) 70 // return value back recursion // 向上递归,设置临时选中值(并非真实选中)
60 const backItem = this.getBaseItem(item); 71 const backItem = this.getBaseItem(item);
61 this.tmpItem = backItem; 72 this.tmpItem = backItem;