vant的picker组件数据更新时视图却没有更新???

摘要:
1、背景最近项目有个需求,需要使用vant的picker选择器,并且搭配弹出层使用,并且picker的数据是异步获取的,但是在测试的过程中,数据已经正确获取到,页面也实现了响应式,但是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);
             })
          : '';
  • 加载数据的现象:

vant的picker组件数据更新时视图却没有更新???第1张

  • 加载数据成功后的现象:

vant的picker组件数据更新时视图却没有更新???第2张

2、分析

官网地址:https://vant-contrib.gitee.io/vant/v3/#/zh-CN/picker

刚开始的时候我认为是vue的响应式数据问题引起的,后来在popup中打印了数据源sourceData之后,发现页面的数据已经响应式更新了,但是picker中的下拉选项数据却并没有发生变化,所以接下来我查阅了一下vant-picker的官方文档,发现picker实例上有一个方法setColumnValues 可以设置对应列中所有的选项,所以我给picker设置了一个ref

  • html
    <van-picker
            default-index="0"ref="picker":loading="loading":columns="sourceData":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函数里面访问
lazy[ˈleɪzi]详细X
基本翻译
adj. 懒惰的;懒洋洋的;怠惰的;慢吞吞的
n. (Lazy)人名;(德)拉齐
网络释义
lazy: 懒惰的
Lazy Susan: 餐桌转盘
Lazy evaluation: 惰性求值

免责声明:文章转载自《vant的picker组件数据更新时视图却没有更新???》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇codeblocks---常用快捷键,折叠所有函数linux下crontab的使用方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

ps图层组快捷键 一次打开或关闭所有的顶级图层组

这些快捷键是:·按Ctrl键并单击顶层图层组的箭头,可同时打开/关闭所有顶层图层组。...

hiveserver2启动卡住问题解决方案

问题分析:hiveserver2可能是Hadoop集群进入安全模式,导致hiveserver2连接不上集群临时解决方案:离开安全模式即可#查看安全模式情况hdfsdfsadmin-safemodeget#离开安全模式hdfsdfsadmin-safemodeleave#进入安全模式hdfsdfsadmin-safemodeenter问题再分析:如何永久性的解...

关于WINFORM中输入法的设置

关于WINFORM(转移到)John Suna的专栏开发中输入方法的设置,它碰巧遇到了这种问题。网络真的很好:)这是文本集。感谢作者的辛勤工作给您带来的便利。在WINFORM中,我们经常遇到这样的问题:文本输入框中的输入法被禁用或总是更改为全宽输入法。查阅相关数据后,总结如下:(1)Control.ImeMode属性:获取或设置控件的输入方法编辑器模式。此模...

当微信小程序遇到AR(二)

当微信小程序遇到AR,会擦出怎么样的火花?期待与激动......通过该教程,可以从基础开始打造一个微信小程序的AR框架,所有代码开源,提供大家学习。注册地址=˃注册成功之后,需要下载微信小程序开发工具。下载地址=˃目前笔者的开发环境是:Windows10下载的微信小程序版本为:RCv1.0.2.1909111 打开,微信开发者工具之后,会看到如下的页面。...

5G中的频点计算及实例分析

相关图表:关于∏SSB的频域位置SSREF和GSCN之间的关系,请参见下表:注:SCSspacedchannelrasterisM=3的工作频带的默认值。同步网格是5G的第一个概念,旨在加快终端扫描SSB的频率位置。GSCN通常用于在SA联网模式下加速时频同步,以继续解释MIB和SIB1消息;对于NSA来说,这是不必要的。RRC重配置消息已经携带了NR的SS...

以『公众号』为例,手把手教你爬取PC端数据

“appmsgext_url=origin_url+”__biz={}&mid={}&sn={}&idx={}&appmsg_token={}&x5=1“.formatcontent=requests.post.json()打印打印可以看到帖子已成功发送,并提取相应的阅读号、点赞号和观看号。5。同一个公众号被扩展。如果...