小程序实现多列选择器


Posted in Javascript onFebruary 15, 2019

本文实例为大家分享了小程序实现多列选择器的具体代码,供大家参考,具体内容如下

代码分两部分,先上wxml

<view class="container">
 <form catchsubmit="formSubmit">
  <view class="form-card">
   <view class="weui-cell weui-cell_input">
    <view class="weui-cell__hd">
     <view class="weui-label">物种<span>*</span></view>
    </view>
    <view class="weui-cell__bd">
     <picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">
      <view class="weui-input">{{multiArray[0][multiIndex[0]]}}{{multiArray[1][multiIndex[1]]}}{{multiArray[2][multiIndex[2]]}}</view>
     </picker>
    </view>
   </view>
  </view>
 </form>  
</view>

其次是js

Page({
 
 /**
  * 页面的初始数据
  */
 data: {
  objectMultiShow: [],
  objectMultiArray: [],
  multiArray: [],
  multiIndex: [],
  checkeIndex: []
 },
 
 /**
  * 生命周期函数--监听页面加载
  * objectMultiShow--匹配多列选择器渲染数据所对应的json数据(包含id,parentId,name)
  * multiArray--多列选择器渲染数据
  */
 onLoad: function (options) {
  // 初始化
  let data = {
   objectMultiShow: this.data.objectMultiShow,
   objectMultiArray: this.data.objectMultiArray,
   multiArray: this.data.multiArray,
   multiIndex: this.data.multiIndex,
   checkeIndex: this.data.checkeIndex
  }
  data.objectMultiArray = [
   [{ id: 0, name: '无脊柱动物' }, { id: 1, name: '脊柱动物' }],
   [
    { id: 0, name: '扁性动物', parentId: 0 }, { id: 1, name: '线形动物', parentId: 0 }, { id: 2, name: '环节动物', parentId: 0 }, { id: 3, name: '软体动物', parentId: 0 }, { id: 4, name: '节肢动物', parentId: 0 },
    { id: 5, name: '鱼', parentId: 1 }, { id: 6, name: '两栖动物', parentId: 1 }, { id: 7, name: '爬行动物', parentId: 1 }
   ],
   [
    { id: 0, name: '猪肉绦虫', parentId: 0 }, { id: 1, name: '吸血虫', parentId: 0 },
    { id: 2, name: '蛔虫', parentId: 1 },
    { id: 3, name: '蚂蚁', parentId: 2 }, { id: 4, name: '蚂蟥', parentId: 2 },
    { id: 5, name: '河蚌', parentId: 3 }, { id: 6, name: '蜗牛', parentId: 3 }, { id: 7, name: '蛞蝓', parentId: 3 },
    { id: 8, name: '昆虫', parentId: 4 }, { id: 9, name: '甲壳动物', parentId: 4 }, { id: 10, name: '蛛形动物', parentId: 4 }, { id: 11, name: '多足动物', parentId: 4 },
    { id: 3, name: '鲫鱼', parentId: 5 }, { id: 4, name: '带鱼', parentId: 5 },
    { id: 3, name: '青蛙', parentId: 6 }, { id: 4, name: '娃娃鱼', parentId: 6 },
    { id: 3, name: '蜥蜴', parentId: 7 }, { id: 4, name: '龟', parentId: 7 }, { id: 4, name: '壁虎', parentId: 7 },
   ]
  ]
  data.objectMultiShow = data.objectMultiArray.map((item, index) => {
   if (index > 0) {
    item = item.filter(i => i.parentId === data.objectMultiArray[index - 1][0].id)
   }
   return item
  })
  data.multiArray = data.objectMultiShow.map(item => {
   item = item.map(i => i.name)
   return item
  })
  console.log(data.multiIndex)
  // 数据更新
  this.setData(data)
 },
 
 bindMultiPickerChange: function (e) {
  console.log('picker发送选择改变,携带值为', e.detail.value)
  this.setData({
   multiIndex: e.detail.value
  })
 },
 bindMultiPickerColumnChange: function (e) {
  console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
  // 初始化数据
  var data = {
   objectMultiShow: this.data.objectMultiShow,
   multiArray: this.data.multiArray,
   multiIndex: this.data.multiIndex
  };
 
  // 改变第i列数据之后,后几列选择第0个选项(重置)
  data.multiIndex[e.detail.column] = e.detail.value;
  for (let i = e.detail.column; i < data.multiIndex.length - 1; i++) {
   data.multiIndex[i + 1] = 0
  }
 
  /**
   * 改变第i列数据之后,后几列数据更新
   * 两种写法:for 和 switch,switch为三列选择器写法,for由switch精简拓展过来,可用于多列选择器
   * swich写法:如果更改的是第一列数据,第二列数据通过filter筛选(parentId = 第一列选中项id),同时更新第三列数据
   *      如果更改的是第二列数据,更新第三列数据 通过filter筛选(parentId = 第二列选中项id)
   */
  let arry = this.data.objectMultiArray
  for (let i = e.detail.column; i < data.multiIndex.length - 1; i++) {
   data.objectMultiShow[i + 1] = arry[i + 1].filter(item => item.parentId === data.objectMultiShow[i][data.multiIndex[i]].id)
   data.multiArray[i + 1] = data.objectMultiShow[i + 1].map(item => item.name)
  }
  /*switch (e.detail.column) {
   case 0:
    data.objectMultiShow[1] = arry[1].filter(item => item.parentId === data.objectMultiShow[0][data.multiIndex[0]].id)
    data.multiArray[1] = data.objectMultiShow[1].map(item => item.name)
    data.objectMultiShow[2] = arry[2].filter(item => item.parentId === data.objectMultiShow[1][data.multiIndex[1]].id)
    data.multiArray[2] = data.objectMultiShow[2].map(item => item.name)
    break;
   case 1:
    data.objectMultiShow[2] = arry[2].filter(item => item.parentId === data.objectMultiShow[1][data.multiIndex[1]].id)
    data.multiArray[2] = data.objectMultiShow[2].map(item => item.name)
  }*/
  // 数据更新
  this.setData(data);
 }
})

wxml部分选用的官方组件--picker,根据官方文档mode=multiSelector,表示使用多列选择器。

其他参数容我吐槽下:首先是range--绑定的二维数据,只能是字符串组成的二维数组,比如[["a","b"], ["c","d"]],这样的话多列选择器就是第一列a,b选项,第二列c,d选项。感觉很美。然而事实上这能干啥捏?我们做的多列选择器并不是只是页面展示,要跟后台对接数据的,就这样传字符串合适否?我需要的是带id之类的对象,而wxml页面又不支持双括号绑定数据里写map之类的函数方法。所以,我们后台传过来的数据要改造一下,提取其中的name为绑定数据。

第二个就是value,本来以为这个是对应项中的第几个是这样的:a如果对应c,b如果对应d。选择bd应该就是[1, 1],而事实上是[1, 0]。也就是对应页面上展示的第几个对应(bd,页面上第一列有ab两个选项,第二列有且只有一个d)

其他关于bindchange绑定的方法是点击确认按钮触发,bindcolumnchange绑定的方法是滑动多列选择器时候触发,至于bindcancel绑定感觉就是笑话,数据实时改变,取消需要再绑定一个中间值才能达到该有的效果,这里暂时没有做。

js部分我使用了五个数据

  • objectMultiShow: []   选中带id的Object对象数组
  • objectMultiArray: []    后台带id,parentId对象数组
  • multiArray: []    微信小程序组件需求的字符串二维数组
  • multiIndex: []    微信小程序组件需求的选中对象数组
  • checkeIndex: []    基于bindcancel的中间值(暂时未做)

为了达到我想到的真正的多列效果,我不惜出卖肉体,跟后台大哥达成的各种屈辱协议,获得了想要的数据格式第一列数组不带parentId,因为没有parent。第二列parentId对应第一列id,第三列parentId对应第二列id,如果还有多,可以依次类推。然后根据需求,依次从中获取所需的其他数据,完成数据初始化。

然后在滑动多列选择器的时候,动态更新后一列的数据,我这里做的处理是更新后一列数据,并默认选择第一个选项。

详细注释写完,发现更多的是配置代码,具体的功能代码反而很少。

个人感觉,小程序不是写代码,而是在配置选项搭建出来的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Prototype使用指南之selector.js
Jan 10 Javascript
jquery.jstree 增加节点的双击事件代码
Jul 27 Javascript
jquery中通过过滤器获取表单元素的实现代码
Jul 05 Javascript
jQueryMobile之Helloworld与页面切换的方法
Feb 04 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
Mar 23 Javascript
JavaScript获取function所有参数名的方法
Oct 30 Javascript
JS原型、原型链深入理解
Feb 27 Javascript
ES6中非常实用的新特性介绍
Mar 10 Javascript
ionic js 复选框 与普通的 HTML 复选框到底有没区别
Jun 06 Javascript
JS中用EL表达式获取上下文参数值的方法
Mar 28 Javascript
用原生JS实现爱奇艺首页导航栏代码实例
Sep 19 Javascript
JavaScript中关于预编译、作用域链和闭包的理解
Mar 31 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
Feb 15 #jQuery
微信实现自动跳转到用其他浏览器打开指定APP下载
Feb 15 #Javascript
微信小程序实现联动选择器
Feb 15 #Javascript
推荐一个基于Node.js的表单验证库
Feb 15 #Javascript
微信小程序实现左右列表联动
May 19 #Javascript
webpack-url-loader 解决项目中图片打包路径问题
Feb 15 #Javascript
微信小程序实现单选选项卡切换效果
Jun 19 #Javascript
You might like
解析使用substr截取UTF-8中文字符串出现乱码的问题
2013/06/20 PHP
PHP根据传入参数合并多个JS和CSS文件的简单实现
2014/06/13 PHP
PHP生成RSS文件类实例
2014/12/05 PHP
从数据结构分析看:用for each...in 比 for...in 要快些
2013/04/17 Javascript
不到30行JS代码实现Excel表格的方法
2014/11/15 Javascript
Vue方法与事件处理器详解
2016/12/01 Javascript
实例分析vue循环列表动态数据的处理方法
2018/09/28 Javascript
vue 移动端注入骨架屏的配置方法
2019/06/25 Javascript
将RGB值转换为灰度值的简单算法
2019/10/09 Javascript
JavaScript实现多文件下载方法解析
2020/08/07 Javascript
Angular进行简单单元测试的实现方法实例
2020/08/16 Javascript
jQuery实现简单弹幕制作
2020/12/10 jQuery
[11:57]《一刀刀一天》第十七期:TI中国军团加油!
2014/05/26 DOTA
python正常时间和unix时间戳相互转换的方法
2015/04/23 Python
python实现八大排序算法(1)
2017/09/14 Python
Python实现简易Web爬虫详解
2018/01/03 Python
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
Django 内置权限扩展案例详解
2019/03/04 Python
用vue.js组件模拟v-model指令实例方法
2019/07/05 Python
python爬取百度贴吧前1000页内容(requests库面向对象思想实现)
2019/08/10 Python
PyCharm 2019.3发布增加了新功能一览
2019/12/08 Python
Python实现删除某列中含有空值的行的示例代码
2020/07/20 Python
HTML5实现的震撼3D焦点图动画的示例代码
2019/09/26 HTML / CSS
美国南加州的原创极限运动潮牌:Vans(范斯)
2016/08/05 全球购物
巴黎卡诗加拿大官网:Kérastase加拿大
2018/11/12 全球购物
波兰汽车配件网上商店:iParts.pl
2020/09/08 全球购物
医学专业五年以上个人求职信
2013/12/03 职场文书
事业单位请假制度
2014/01/13 职场文书
会计电算化毕业生自荐信
2014/03/03 职场文书
月度优秀员工获奖感言
2014/08/16 职场文书
学习礼仪心得体会
2014/09/01 职场文书
2014领导班子四风问题查摆思想汇报
2014/09/13 职场文书
2014离婚协议书范文两篇
2014/09/15 职场文书
2014副镇长民主生活会个人对照检查材料思想汇报
2014/09/30 职场文书
护士年终工作总结不会写?各科护士模板总结
2020/01/02 职场文书
深入理解margin塌陷和margin合并的解决方案
2021/06/26 HTML / CSS