草庐IT

微信小程序picker组件遇到的问题以及解决办法

Shansec~ 2023-04-17 原文

一、picker基本概念

先来看一下官方文档中picker的基本概念:
从底部弹起的滚动选择器,现支持三种选择器,通过mode来区分,分别是普通选择器,时间选择器,日期选择器,默认是普通选择器。

重要属性

  • range: 选取范围,数据类型为Array / Object Array,mode为 普通选择器 时,range 有效;
  • value: value 的值表示选择了 range 中的第几个(下标从 0 开始),数据类型肯定是Number;
  • bindchange: 绑定事件,value 改变时触发 change 事件,event.detail = {value: value}。
  • mode:选择器类型,可以是selector( 普通选择器)、multiSelector(多列选择器)、date(时间选择器)、time(日期选择器)、region(省市区选择器);

二、遇到的问题

问题说在前面,同一个页面使用多个普通选择器遇到了问题,选择一个选项,其他选项也跟随着改变了。
代码如下:

//picker.wxml:   
<view class="column_list" >
        <text class="font15">选项一</text>
        <picker class="inputText" bindchange="bindchange1" value="{{index}}" range="{{option1}}">
            <view class="select_picker">
                {{option1[index]}}
                <image  mode="aspectFit"  class="select_arrow" src="../../images/select_arrow.png"></image>
            </view>
        </picker>
    </view>
    <view class="column_list" >
        <text class="font15">选项二</text>
        <picker class="inputText" bindchange="bindchange1" value="{{index}}" range="{{option2}}">
            <view class="select_picker">
                {{option2[index]}}
                <image  mode="aspectFit"  class="select_arrow" src="../../images/select_arrow.png"></image>
            </view>
        </picker>
    </view>
    <view class="column_list" >
        <text class="font15">选项三</text>
        <picker class="inputText" bindchange="bindchange1" value="{{index}}" range="{{option3}}">
            <view class="select_picker">
                {{option3[index]}}
                <image  mode="aspectFit"  class="select_arrow" src="../../images/select_arrow.png"></image>
            </view>
        </picker>
    </view>
//picker.js
    Page({
    data: {
        index:0,//设置索引值默认为0
        option1: ['1', '2', '3','4','5'],
        option2: ['一', '二', '三','四','五'],
        option3: ['①', '②', '③','④','⑤'],
    },
    bindchange1:function (e) {
       // console.log('picker发送选择改变,携带值为', e.detail.value)
       // 设置这个携带值赋值给索引值index
       // 所以option1 ,option2 ,option3的索引值都是一样的
        this.setData({
            index: e.detail.value
        })
    }
})

因为默认索引值(也叫“下标”)都是index,绑定事件也只是改变了index。所以改变一个选项,其他选项都跟着改变了。

三、如何解决

首先想到的解决办法就是自定义不同的索引值index1、index2,、index3,分别绑定不同的时间bindchange1、bindchange2、bindchange3改变其对应的索引值。
代码如下:

//picker.wxml: 
 <view class="column_list" >
        <text class="font15">选项一</text>
        <picker class="inputText" bindchange="bindchange1" value="{{index1}}" range="{{option1}}">
            <view class="select_picker">
                {{option1[index1]}}
                <image  mode="aspectFit"  class="select_arrow" src="../../images/select_arrow.png"></image>
            </view>
        </picker>
    </view>
    <view class="column_list" >
        <text class="font15">选项二</text>
        <picker class="inputText" bindchange="bindchange2" value="{{index2}}" range="{{option2}}">
            <view class="select_picker">
                {{option2[index2]}}
                <image  mode="aspectFit"  class="select_arrow" src="../../images/select_arrow.png"></image>
            </view>
        </picker>
    </view>
    <view class="column_list" >
        <text class="font15">选项三</text>
        <picker class="inputText" bindchange="bindchange3" value="{{index3}}" range="{{option3}}">
            <view class="select_picker">
                {{option3[index3]}}
                <image  mode="aspectFit"  class="select_arrow" src="../../images/select_arrow.png"></image>
            </view>
        </picker>
    </view>
    // picker.js
    Page({
    data: {
        index1:0,
        index2:0,
        index3:0,
        option1: ['1', '2', '3','4','5'],
        option2: ['一', '二', '三','四','五'],
        option3: ['①', '②', '③','④','⑤'],
    },
    bindchange1:function (e) {
        this.setData({
            index1: e.detail.value
        })
    },
    bindchange2:function (e) {
        this.setData({
            index2: e.detail.value
        })
    },
    bindchange3:function (e) {
        this.setData({
            index3: e.detail.value
        })
    }
})

这样一个页面多个picker的问题就解决了,但是现在又发现了一个新的问题:
为什么多个picker会出现相互影响的问题?比如在第一个选择器选择了3,剩下的选择器点进去默认都是从第3个开始?” 小程序开发工具中的确存在,看了社区的帖子,才知道这个是官方的bug,目前还没有修复。

四、延伸

在这里使用了多个picker,可以想到使用wx:for循环,那么为了渲染方便,数据就要修改为对象的数组。

// picker.js
Page({
    data: {
    //每个对象就是一个选择器,有自己的索引值index,标题title,选项option(又是一个数组)
        objArray:[
            {
                index:0,
                title:'选项一',
                option: ['1', '2', '3','4','5'],
            },
            {
                index:0,
                title:'选项二',
                option: ['一', '二', '三','四','五'],
            },
            {
                index:0,
                title:'选项三',
                option: ['①', '②', '③','④','⑤']
            },
        ]
    },
    // 绑定事件,因为不能用this.setData直接设置每个对象的索引值index。
    // 所以用自定义属性current来标记每个数组对象的下标
    bindChange_select: function(ev) {
    // 定义一个变量curindex 储存触发事件的数组对象的下标
        const curindex = ev.target.dataset.current
    // 根据下标 改变该数组对象中的index值
        this.data.objArray[curindex].index = ev.detail.value
    // 把改变某个数组对象index值之后的全新objArray重新 赋值给objArray
        this.setData({
            objArray: this.data.objArray
        })
    }
})

wx:for绑定数组objArray,当前项的下标变量名默认为index,数组当前项的变量名默认为item,为了区分选项option中的下标
使用 wx:for-item 可以指定数组当前元素的变量名为itm,使用 wx:for-index 可以指定数组当前下标的变量名为idx。

关键点是:自定义一个属性对应当前下标 data-current=“{{idx}}”,绑定事件bindChange_select触发时判断出是哪个数组对象触发的,就改变该数组对象中的index值。

//picker.wxml:
 <view class="column_list mt_10" wx:for="{{objArray}}" wx:for-item="itm"  wx:for-index="idx" >
        <text class="font15">{{itm.title}} </text>
        <picker  class="inputText"  bindchange="bindChange_select" value="{{itm.index}}" data-current="{{idx}}" range="{{itm.option}}" >
            <view class="select_picker">
                 {{itm.option[itm.index]}}
                <image  mode="aspectFit"  class="select_arrow" src="../../images/select_arrow.png"></image>
            </view>
        </picker>
    </view>

五、效果图

有关微信小程序picker组件遇到的问题以及解决办法的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  5. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  6. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  9. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  10. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

随机推荐