diff --git a/examples/routers/cascader.vue b/examples/routers/cascader.vue index 1a843a8..26da699 100644 --- a/examples/routers/cascader.vue +++ b/examples/routers/cascader.vue @@ -1,134 +1,193 @@ +<!--<template>--> + <!--<Row>--> + <!--<i-col span="4">--> + <!--<Button @click="handleLoad">load</Button>--> + <!--{{ v1 }}--> + <!--</i-col>--> + <!--<i-col span="4">--> + <!--<Cascader :data="data2" filterable v-model="v1" style="width: 200px;"></Cascader>--> + <!--<!–<Cascader :data="data2" filterable v-model="v1" :loadData="loadData"></Cascader>–>--> + <!--</i-col>--> + <!--</Row>--> +<!--</template>--> +<!--<script>--> + <!--export default {--> + <!--data () {--> + <!--return {--> + <!--v1: [],--> + <!--data2: [--> + <!--{--> + <!--value: 'zhejiang',--> + <!--label: '浙江',--> + <!--children: [],--> + <!--loading: false--> + <!--},--> + <!--{--> + <!--value: 'jiangsu',--> + <!--label: '江苏',--> + <!--children: [{--> + <!--value: 'nanjing',--> + <!--label: '南京',--> + <!--children: [--> + <!--{--> + <!--value: 'zhonghuamen',--> + <!--label: '中华门'--> + <!--},--> + <!--{--> + <!--value: 'v1',--> + <!--label: 'v111'--> + <!--},--> + <!--{--> + <!--value: 'v2',--> + <!--label: 'v2222'--> + <!--},--> + <!--{--> + <!--value: 'v3',--> + <!--label: 'v333'--> + <!--},--> + <!--{--> + <!--value: 'v4',--> + <!--label: 'v4444'--> + <!--},--> + <!--{--> + <!--value: 'v5',--> + <!--label: 'v555'--> + <!--},--> + <!--{--> + <!--value: 'v6',--> + <!--label: 'v666'--> + <!--},--> + <!--{--> + <!--value: 'v7',--> + <!--label: 'v777'--> + <!--}--> + <!--]--> + <!--}]--> + <!--}--> + <!--],--> + <!--data3: [{--> + <!--value: 'beijing',--> + <!--label: '北京',--> + <!--children: [--> + <!--{--> + <!--value: 'gugong',--> + <!--label: '故宫'--> + <!--},--> + <!--{--> + <!--value: 'tiantan',--> + <!--label: '天坛'--> + <!--},--> + <!--{--> + <!--value: 'wangfujing',--> + <!--label: '王府井'--> + <!--}--> + <!--]--> + <!--}, {--> + <!--value: 'jiangsu',--> + <!--label: '江苏',--> + <!--children: [--> + <!--{--> + <!--value: 'nanjing',--> + <!--label: '南京',--> + <!--children: [--> + <!--{--> + <!--value: 'fuzimiao',--> + <!--label: '夫子庙',--> + <!--}--> + <!--]--> + <!--},--> + <!--{--> + <!--value: 'suzhou',--> + <!--label: '苏州',--> + <!--children: [--> + <!--{--> + <!--disabled: true,--> + <!--value: 'zhuozhengyuan',--> + <!--label: '拙政园',--> + <!--},--> + <!--{--> + <!--value: 'shizilin',--> + <!--label: '狮子林',--> + <!--}--> + <!--]--> + <!--}--> + <!--],--> + <!--}]--> + <!--}--> + <!--},--> + <!--methods: {--> + <!--handleLoad () {--> + <!--this.data2[0].loading = !this.data2[0].loading;--> + <!--},--> + <!--loadData (item, cb) {--> + <!--item.loading = true;--> + <!--setTimeout(() => {--> + <!--if (item.value === 'zhejiang') {--> + <!--item.children = [--> + <!--{--> + <!--value: 'hangzhou',--> + <!--label: '杭州',--> + <!--loading: false,--> + <!--children: []--> + <!--}--> + <!--];--> + <!--} else if (item.value === 'hangzhou') {--> + <!--item.children = [--> + <!--{--> + <!--value: 'ali',--> + <!--label: '阿里巴巴'--> + <!--}--> + <!--];--> + <!--}--> + <!--item.loading = false;--> + <!--cb();--> + <!--}, 1000);--> + <!--}--> + <!--}--> + <!--}--> +<!--</script>--> + + <template> - <Row> - <i-col span="4"> - <Button @click="handleLoad">load</Button> - {{ v1 }} - </i-col> - <i-col span="4"> - <Cascader :data="data2" filterable v-model="v1" style="width: 200px;"></Cascader> - <!--<Cascader :data="data2" filterable v-model="v1" :loadData="loadData"></Cascader>--> - </i-col> - </Row> + <Cascader :data="data4" :load-data="loadData" style="width: 200px;"></Cascader> </template> <script> export default { data () { return { - v1: [], - data2: [ + data4: [ { - value: 'zhejiang', - label: '浙江', + value: 'beijing', + label: '北京', children: [], loading: false }, { - value: 'jiangsu', - label: '江苏', - children: [{ - value: 'nanjing', - label: '南京', - children: [ - { - value: 'zhonghuamen', - label: '中华门' - }, - { - value: 'v1', - label: 'v111' - }, - { - value: 'v2', - label: 'v2222' - }, - { - value: 'v3', - label: 'v333' - }, - { - value: 'v4', - label: 'v4444' - }, - { - value: 'v5', - label: 'v555' - }, - { - value: 'v6', - label: 'v666' - }, - { - value: 'v7', - label: 'v777' - } - ] - }] + value: 'hangzhou', + label: '杭州', + children: [], + loading:false } - ], - data3: [{ - value: 'beijing', - label: '北京', - children: [ - { - value: 'gugong', - label: '故宫' - }, - { - value: 'tiantan', - label: '天坛' - }, - { - value: 'wangfujing', - label: '王府井' - } - ] - }, { - value: 'jiangsu', - label: '江苏', - children: [ - { - value: 'nanjing', - label: '南京', - children: [ - { - value: 'fuzimiao', - label: '夫子庙', - } - ] - }, - { - value: 'suzhou', - label: '苏州', - children: [ - { - disabled: true, - value: 'zhuozhengyuan', - label: '拙政园', - }, - { - value: 'shizilin', - label: '狮子林', - } - ] - } - ], - }] + ] } }, methods: { - handleLoad () { - this.data2[0].loading = !this.data2[0].loading; - }, - loadData (item, cb) { + loadData (item, callback) { item.loading = true; setTimeout(() => { - if (item.value === 'zhejiang') { + if (item.value === 'beijing') { item.children = [ { - value: 'hangzhou', - label: '杭州', - loading: false, - children: [] + value: 'talkingdata', + label: 'TalkingData' + }, + { + value: 'baidu', + label: '百度' + }, + { + value: 'sina', + label: '新浪' } ]; } else if (item.value === 'hangzhou') { @@ -136,11 +195,15 @@ { value: 'ali', label: '阿里巴巴' + }, + { + value: '163', + label: '网易' } ]; } item.loading = false; - cb(); + callback(); }, 1000); } } diff --git a/src/components/cascader/cascader.vue b/src/components/cascader/cascader.vue index 9a4c0cc..926b4bf 100644 --- a/src/components/cascader/cascader.vue +++ b/src/components/cascader/cascader.vue @@ -128,7 +128,9 @@ tmpSelected: [], updatingValue: false, // to fix set value in changeOnSelect type currentValue: this.value, - query: '' + query: '', + validDataStr: '', + isLoadedChildren: false // #950 }; }, computed: { @@ -270,9 +272,31 @@ }, handleFocus () { this.$refs.input.focus(); + }, + // 排除 loading 后的 data,避免重复触发 updateSelect + getValidData (data) { + function deleteData (item) { + const new_item = Object.assign({}, item); + if ('loading' in new_item) { + delete new_item.loading; + } + if ('__value' in new_item) { + delete new_item.__value; + } + if ('__label' in new_item) { + delete new_item.__label; + } + if ('children' in new_item && new_item.children.length) { + new_item.children = new_item.children.map(i => deleteData(i)); + } + return new_item; + } + + return data.map(item => deleteData(item)); } }, created () { + this.validDataStr = JSON.stringify(this.getValidData(this.data)); this.$on('on-result-change', (params) => { // lastValue: is click the final val // fromInit: is this emit from update value @@ -332,7 +356,14 @@ data: { deep: true, handler () { - this.$nextTick(() => this.updateSelected()); + const validDataStr = JSON.stringify(this.getValidData(this.data)); + if (validDataStr !== this.validDataStr) { + this.validDataStr = validDataStr; + if (!this.isLoadedChildren) { + this.$nextTick(() => this.updateSelected()); + } + this.isLoadedChildren = false; + } } } } diff --git a/src/components/cascader/caspanel.vue b/src/components/cascader/caspanel.vue index 296c4d0..5c36499 100644 --- a/src/components/cascader/caspanel.vue +++ b/src/components/cascader/caspanel.vue @@ -61,6 +61,7 @@ const cascader = findComponentUpward(this, 'Cascader'); if (cascader && cascader.loadData) { cascader.loadData(item, () => { + cascader.isLoadedChildren = true; this.handleTriggerItem(item); }); return; -- libgit2 0.21.4