<template>
<van-field v-model="userInfo.nowAddress" placeholder="请输入现居住地址" label="现居住地址" input-align="right" @click="onClickCascader" />
<!--现居住地址 级联选择框 -->
<van-popup v-model:show="showCascader" round position="bottom">
<van-cascader v-model="cascaderAddress" title="请选择所在地区" :options="options" @close="showCascader = false"
@change="onChange" @finish="onFinish" />
</van-popup>
</template>
options: [{
text: '广东省',
value: '440000',
children: [],
}],
<script>
import { Cascader, Popup } from 'vant'
import { reactive, toRefs } from "vue"
import { getAllCity } from "@api/user"
export default {
name: 'userInfo',
components: {
[Cascader.name]: Cascader,
[Popup.name]: Popup,
},
setup() {
const state = reactive({
userInfo: {//用户个人信息,此处只放现居住地址nowAddress
nowAddress:'',
},
showCascader: false,//是否显示级联选择
cascaderAddress: '',//绑定的是当前选择的 value值(如:选择了广东省,当前值为440000)
options: [{
text: '广东省',
value: '440000',
children: [],
}],
});
const onClickCascader = () => {
state.showCascader = true;
};
//获取数据
const getAreas = async (value) => {
const { result } = await getAllCity(value);
return result;
};
const onChange = ({ value, tabIndex, selectedOptions }) => {
if (tabIndex === 0) {
getAreas(value).then((res) => {
if (res.length) {
addTree(selectedOptions, res, value);
}
});
}
};
const addTree = (selectedOptions, res, value) => {
selectedOptions.forEach(item => {
if (item.value === value) {
item.children = res;
}
})
};
const onFinish = ({ value, tabIndex, selectedOptions }) => {
console.log('onFinish', selectedOptions, state.finishIndex, tabIndex);
state.showCascader = false;
state.userInfo.nowAddress = selectedOptions.map((option) => option.text).join('');
};
return {
...toRefs(state),
onClickCascader,
onChange,
onFinish
}
}
}
</script>
此处需要着重说明的是,点击广东省的时候(tabIndex=0),触发的是onChange 事件,但是后续选择会触发onChange 事件和onFinish事件,本身我以为下图事件说明的意思是点击不同的省、市、区、街道…触发的是onChange 事件,直到选择完最后一层(该层没有了children属性)就表明全部选项选择完成,触发onFinished事件;
上述代码就是onChange 事件为每个层级获取children数数组,onFinish事件则关闭级联选择(state.showCascader = false;),并将选择的所有数据进行拼接获取nowAddress 的值(state.userInfo.nowAddress = selectedOptions.map((option) => option.text).join(‘’););
但是事实结果不是这样,除了第一层点击没有问题之外,点击第二层以及往后的每一层,级联选择器会关闭了,再次点击打开,数据还保存在上一次点击的状态,很明显,这触发了onFinish事件,关闭了级联选择器。
我尝试在onFinish事件中进行判断,记录当请求数据为空的时候,说明当前层级没有children,试了之后发现并不能控制onFinish事件的触发,该事件并不根据是说没有children属性就触发onFinish事件;
试了很多次,不知道是我理解问题还是我哪里出错了;
如图:
后续层级不再赘述
如果我的理解错了的话,根据上述得出结果:首次点击触发onChange ,后面触发onFinished,因此,为了控制
const onChange = ({ value, tabIndex, selectedOptions }) => {
console.log('onChange',value, tabIndex, selectedOptions[tabIndex].text);
if (tabIndex === 0) {
getAreas(value).then((res) => {
if (res.length) {
addTree(selectedOptions, res, value);
}
});
}
};
const onFinish = ({ value, tabIndex, selectedOptions }) => {
console.log('onFinish', value, tabIndex, selectedOptions[tabIndex].text);
getAreas(value).then((res) => {
if (res.length) {
addTree(selectedOptions, res, value);
} else {
state.showCascader = false;
state.userInfo.nowAddress = selectedOptions.map((option) => option.text).join('');
}
});
};