vant的picker组件数据更新时视图却没有更新
1、背景
最近项⽬有个需求,需要使⽤vant的picker选择器,并且搭配弹出层使⽤,并且picker的数据是异步获取的,但是在测试的过程中,数据已经正确获取到,页⾯也实现了响应式,但是picker选择器的数据却没有更新,这是为什么呢
代码:
html
<van-popup position="bottom" v-model:show="showPicker">
<!--
loading:是否显⽰加载状态,默认为false
columns:对象数组,配置每⼀列显⽰的数据
value-key已经弃⽤,所以需要columns-field-names⾃定义 Columns 的结构
show-toolbar:是否显⽰顶部栏,默认为true
confirm:点击完成按钮时触发
cancel:点击取消按钮时触发
-->
{{ sourceData }}
<van-picker
default-index="0"
:loading="loading"
:columns="sourceData"
:columns-field-names="customFieldName"
show-toolbar
@confirm="onConfirm"
@cancel="onCancel"
/>
</van-popup>
js:
let res = await initSelectData({
data: {},
method: 'GET',
url: codeId
});
// sourceData = res.data; //直接赋值丢失了响应性
res.data
res.data.forEach(el => {
sourceData.push(el);
})
: '';
加载数据的现象:
加载数据成功后的现象:
2、分析
官⽹地址:
刚开始的时候我认为是vue的响应式数据问题引起的,后来在popup中打印了数据源sourceData之后,发现页⾯的数据已经响应
式更新了,但是picker中的下拉选项数据却并没有发⽣变化,所以接下来我查阅了⼀下vant-picker的官⽅⽂档,发现picker实例上
有⼀个⽅法 setColumnValues 可以设置对应列中所有的选项,所以我给picker设置了⼀个ref
html
<van-picker
default-index="0"
ref="picker"
:loading="loading"
:columns="sourceData"
null官方更新地址:columns-field-names="customFieldName"
show-toolbar
@confirm="onConfirm"
@cancel="onCancel"
/>
js
/**
* @description: onMounted 可以⽤来加载页⾯的初始化数据
* @author: wangxinghua1
*/
onMounted(async () => {
console.log(picker.value, '.....');
});
问题:在onMounted中的结果为:null '.....'。这就导致页⾯加载选择器数据的时候,没有办法获取到实例,⽽导致调
⽤ setColumnValues 报错,这是因为popup弹层在打开前并没有提前渲染到页⾯上(dom加载时并没加载popup),所以导致ref获取不到它⾥⾯的picker选择器,解决⽅法:
<van-popup
:lazy-render="false"
/>
最终结果是
html
<!--
lazy-render:是否在显⽰弹层时才渲染节点,默认为true,防⽌popup弹出层
在打开前并没有提前渲染到页⾯上(dom加载时并没加载popup),
所以导致ref获取不到它⾥⾯的picker选择器(picker.value),
从⽽使得picker.value.setColumnValues报错
-->
<van-popup :lazy-render="false" position="bottom" v-model:show="showPicker">
<!--
loading:是否显⽰加载状态,默认为false
columns:对象数组,配置每⼀列显⽰的数据
value-key已经弃⽤,所以需要columns-field-names⾃定义 Columns 的结构
show-toolbar:是否显⽰顶部栏,默认为true
confirm:点击完成按钮时触发
cancel:点击取消按钮时触发
-->
{{ sourceData }}
<van-picker
default-index="0"
ref="picker"
:loading="loading"
:columns="sourceData"
:columns-field-names="customFieldName"
show-toolbar
@confirm="onConfirm"
@cancel="onCancel"
/>
</van-popup>
js
// 定义是否显⽰弹出层
let showPicker = ref(false);
// 定义选择器的数据
let sourceData = reactive([]);
// 选择器数据是异步获取的,可以通过 loading 属性显⽰加载提⽰
let loading = ref(false);
// 获取picher的dom节点,即picker的实例
let picker = ref(null);
/**
* @description: onMounted 可以⽤来加载页⾯的初始化数据
* @author: wangxinghua1
*/
onMounted(async () => {
// 当选择器的数据来源于后端时,判断是否有请求地址,进⾏初始化数据
if (codeId) {
loading.value = true;
await loadData();
}
});
/**
* @description: loadData 获取select的数据
* @author: wangxinghua1
*/
const loadData = async () => {
try {
let res = await initSelectData({
data: {},
method: 'GET',
url: codeId
});
// sourceData = res.data; //直接赋值丢失了响应性
res.data
res.data.forEach(el => {
sourceData.push(el);
})
: '';
res.data ? (loading.value = false) : (loading.value = false);
console.log('9999999', picker.value);
picker.value.setColumnValues(0, sourceData);
console.log('initSelectData', res, sourceData);
} catch (e) {
console.log('select-loaddata', e.errmsg);
}
};
3、vue3使⽤ref的步骤
1. 给元素添加ref属性<div ref="box"></div>
2. 在setup函数中,可以使⽤ref函数,⽤于创建⼀个响应式数据const box = ref(null)
3. 在setup函数中,使⽤return返回box数据
4. 在onMounted函数⾥⾯访问
[ˈleɪzi] X
基本翻译
adj. 懒惰的;懒洋洋的;怠惰的;慢吞吞的
n. (Lazy)⼈名;(德)拉齐
⽹络释义
懒惰的
餐桌转盘
惰性求值
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论