小程序实现多列选择器


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 相关文章推荐
关于jQuery对象数据缓存Cache原理以及jQuery.data详解
Apr 07 Javascript
js 实现 input type=&quot;file&quot; 文件上传示例代码
Aug 07 Javascript
给before和after伪元素设置js效果的方法
Dec 04 Javascript
JavaScript添加随滚动条滚动窗体的方法
Feb 23 Javascript
D3.js实现饼状图的方法详解
Sep 21 Javascript
微信小程序 radio单选框组件详解及实例代码
Jan 10 Javascript
js实现3D图片环展示效果
Mar 09 Javascript
vue.js内部自定义指令与全局自定义指令的实现详解(利用directive)
Jul 11 Javascript
vue.js将时间戳转化为日期格式的实现代码
Jun 05 Javascript
图解javascript作用域链
May 27 Javascript
js数组相减简单示例【删除a数组所有与b数组相同元素】
Mar 04 Javascript
vue中三级导航的菜单权限控制
Mar 31 Vue.js
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
编写Smarty插件在模板中直接加载数据的详细介绍
2013/06/26 PHP
php calender(日历)二个版本代码示例(解决2038问题)
2013/12/24 PHP
PHP中鲜为人知的10个函数
2014/02/28 PHP
php操作MongoDB类实例
2015/06/17 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
再谈IE中Flash控件的自动激活 ObjectWrap
2007/03/09 Javascript
解决jQuery插件tipswindown与hintbox冲突
2010/11/05 Javascript
javascript 窗口加载蒙板 内嵌网页内容
2010/11/19 Javascript
JavaScript实现简单的tab选项卡切换
2016/01/05 Javascript
如何消除inline-block属性带来的标签间间隙
2016/03/31 Javascript
JavaScript实现打开链接页面的方式汇总
2016/06/02 Javascript
javascript数组去重常用方法实例分析
2017/04/11 Javascript
对象不支持indexOf属性或方法的解决方法(必看)
2017/05/28 Javascript
浅析webpack-bundle-analyzer在vue-cli3中的使用
2019/10/23 Javascript
vue下的@change事件的实现
2019/10/25 Javascript
[51:10]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python进阶教程之函数对象(函数也是对象)
2014/08/30 Python
Python实现检测服务器是否可以ping通的2种方法
2015/01/01 Python
Python中使用hashlib模块处理算法的教程
2015/04/28 Python
python实现下载指定网址所有图片的方法
2015/08/08 Python
PyQt5利用QPainter绘制各种图形的实例
2017/10/19 Python
python实现多线程网页下载器
2018/04/15 Python
解决python3运行selenium下HTMLTestRunner报错的问题
2018/12/27 Python
对django layer弹窗组件的使用详解
2019/08/31 Python
python函数装饰器之带参数的函数和带参数的装饰器用法示例
2019/11/06 Python
python 基于dlib库的人脸检测的实现
2019/11/08 Python
Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签
2019/12/04 Python
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
自我鉴定模板
2013/10/29 职场文书
学雷锋演讲稿
2014/03/04 职场文书
培训主管的职业生涯规划
2014/03/06 职场文书
竞选卫生委员演讲稿
2014/04/28 职场文书
项目建议书怎么写
2014/05/15 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
laravel ajax curd 搜索登录判断功能的实现
2021/04/17 PHP
mysql 8.0.24版本安装配置方法图文教程
2021/05/12 MySQL