Commit f7ffdac56931b17211074c0ac0c41b5a25c946b1

Authored by 梁灏
1 parent 13a940ee

Cascader support loadData async

examples/routers/cascader.vue
1 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 11 </template>
6 12 <script>
7 13 export default {
8 14 data () {
9 15 return {
10   - v1: ['zhejiang'],
  16 + v1: [],
11 17 data2: [{
12 18 value: 'zhejiang',
13 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 23 value: 'jiangsu',
24 24 label: '江苏',
... ... @@ -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 66 </script>
... ...
src/components/cascader/cascader.vue
... ... @@ -88,6 +88,9 @@
88 88 default (label) {
89 89 return label.join(' / ');
90 90 }
  91 + },
  92 + loadData: {
  93 + type: Function
91 94 }
92 95 },
93 96 data () {
... ... @@ -224,8 +227,11 @@
224 227 }
225 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 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 7 </template>
4 8 <script>
5 9 export default {
... ... @@ -18,6 +22,12 @@
18 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 15 <script>
16 16 import Casitem from './casitem.vue';
17 17 import Emitter from '../../mixins/emitter';
  18 + import { findComponentUpward } from '../../utils/assist';
18 19  
19 20 export default {
20 21 name: 'Caspanel',
... ... @@ -56,6 +57,16 @@
56 57 handleTriggerItem (item, fromInit = false) {
57 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 70 // return value back recursion // 向上递归,设置临时选中值(并非真实选中)
60 71 const backItem = this.getBaseItem(item);
61 72 this.tmpItem = backItem;
... ...