水平较低,主要是给自己看的。如果要用vue transition,必须每次弹出都初始化better-scroll实例。

<!--
li下必须加子元素包裹,否则选中样式会有延迟。
目前是在任何一列在滚动中都会禁用取消和确认,实际上可以使用stop()方法,不过需要下次弹出前想办法初始化
$data.show控制弹出和收起
$props.type: 场景类型1.YMD——年月日,默认initYMD是当前年月日,否则传入new Date(yyyy,mm,dd),注意mm为0-112.SHX——省市区、三级联动,目前没做初始位置逻辑。由于地区名字可能会很长,由filter做了一些不恰当处理
-->
<template><div class="selector"><div v-show="show" class="shade"></div><div class="box" :class="{'up':show,'down':!show}"><div class="title"><button type="button" @click="cancel" :disabled="disableBtn">{{lb}}</button><div>{{title}}</div><button type="button" @click="deal" :disabled="disableBtn">{{rb}}</button></div><div class="section"><div class="line"></div><div class="line"></div><!--数据没有关联性的年月日--><div class="lists three" v-if="type==='YMD'"><div class="wrapper" ref="first"><ul ref="firstUl"><li v-for="(v,i) in firstList" :key="i"><p :class="getClass(firstIndex, i)">{{v}}</p></li></ul></div><div class="wrapper" ref="second"><ul ref="secondUl"><li v-for="(v,i) in secondList" :key="i" :ref="i===0?'cell':null"><p :class="getClass(secondIndex, i)">{{v}}</p></li></ul></div><div class="wrapper" ref="third"><ul ref="thirdUl" class="wheel-scroll"><li v-for="(v,i) in thirdList" :key="i" class="wheel-item"><p :class="getClass(thirdIndex, i)">{{v}}</p></li></ul></div></div><!--省市县三级联动--><div class="lists threeLink" v-if="type==='SHX'"><div class="wrapper" ref="first"><ul ref="firstUl" class="wheel-scroll"><li v-for="(v,i) in firstList" :key="i" class="wheel-item"><p :class="getClass(firstIndex, i)">{{v.name | reduceLetter}}</p></li></ul></div><div class="wrapper" ref="second"><ul ref="secondUl"><li v-for="(v,i) in secondList" :key="i" :ref="i===0?'cell':null"><p :class="getClass(secondIndex, i)">{{v.name | reduceLetter}}</p></li></ul></div><div class="wrapper" ref="third"><ul ref="thirdUl"><li v-for="(v,i) in thirdList" :key="i"><p :class="getClass(thirdIndex, i)">{{v.name | reduceLetter}}</p></li></ul></div></div></div></div></div>
</template><script>
import BScroll from 'better-scroll';
import SHX from 'ass/js/ChinaAreaList';export default {name: 'Selector',data() {return {show: false,firstScroll: Function, // 第一列better-scroll对象secondScroll: Function,thirdScroll: Function,firstIndex: 0, // 第一列选中索引secondIndex: 0,thirdIndex: 0,firstList: null, // 第一列数据secondList: null,thirdList: null,lastDate: Date,ymdList: Array,firstScrolling: false,secondScrolling: false,thirdScrolling: false}},props: {type: {type: String,default: 'YMD'},config: {type: Object},lb: {type: String,default: '取消'},rb: {type: String,default: '确认'},title: {type: String,default: '日期选择'},initYMD: { // 初始时间年月日type: Date,default() {return new Date();}},initSHX: {type: Array,default() {return ['110000', '110000'];}},output: null // 输出对象},computed: {disableBtn() {if (!this.thirdScrolling && !this.secondScrolling && !this.firstScrolling) {return false;} else {return true;}}},filters: {reduceLetter(v) {const reg = /(省|市|县|自治区|特别行政区|壮族|回族|藏族|土族|维吾尔|自治县|自治州|蒙古族|自治)/g;return v.replace(reg, '');}},methods: {getYears(len, init) {return Array.from({length: len}).map((v, i) => i + init);},getMonth() {return Array.from({length: 12}).map((v, i) => i + 1);},createYMD(start, lang) { // start开始年份,lang展示const d31 = /^(0|2|4|6|7|9|11)$/;const d30 = /^(3|5|8|10)$/;return Array.from({length: lang}).map((yv, yi) => {yv = {};yv['year'] = yi + start;yv['first'] = Array.from({length: 12}).map((mv, mi) => {let len;mv = {};if (yv.year % 4 === 0 && mi === 1) {len = 29;} else if (yv.year % 4 !== 0 && mi === 1) {len = 28;} else if (d30.test(mi)) {len = 30;} else if (d31.test(mi)) {len = 31;}mv['month'] = mi + 1;mv['second'] = Array.from({length: len}).map((dv, di) => {dv = di + 1;return dv;});return mv;});return yv;});},getDate(y, m) {let len = 28;const d31 = /^(0|2|4|6|7|9|11)$/;const d30 = /^(3|5|8|10)$/;let year = y || this.initYMD.getFullYear();let mon = m || this.initYMD.getMonth();if (d31.test(mon)) {len = 31;} else if (d30.test(mon)) {len = 30;} else if (mon === 1 && year % 4 === 0) {len = 29;}return Array.from({length: len}).map((v, i) => i + 1);},getClass(index, key) {if ((key === index - 1) || (key === index + 1)) {return 'second';} else if (key !== index) {return 'third';}},initListYMD() {let time;switch (this.type) {case 'MD':time = this.initYMD;break;default:time = this.initYMD;this.firstList = this.getYears(300, 1900);this.secondList = this.getMonth();this.thirdList = this.getDate();this.firstIndex = time.getFullYear() - 1900;this.secondIndex = time.getMonth();this.thirdIndex = time.getDate() -1;break;}},initScroll(scroll) {this.$nextTick(() => {if (!this.$refs[scroll]) return;this[scroll + 'Scroll'] = new BScroll(this.$refs[scroll], {probeType: 3,wheel: {selectedIndex: this[scroll + 'Index']||0,wheelWrapperClass: 'wheel-scroll',wheelItemClass: 'wheel-item',rotate: 0,adjustTime: 0}});const ch = this.$refs.cell[0].clientHeight;this[scroll + 'Scroll'].on('scroll', ({y}) => {this[scroll + 'Index'] = Math.round(Math.abs(y) / ch);this[scroll + 'Scrolling'] = true;});this[scroll + 'Scroll'].on('scrollEnd', () => {this[scroll + 'Scrolling'] = false;this[scroll + 'Index'] = this[scroll + 'Scroll'].getSelectedIndex();if (this.type === 'YMD' && (scroll === 'first' || scroll === 'second')) {let len1 = this.thirdList.length;this.thirdList = this.getDate(this.firstIndex + 1900, this.secondIndex);let len2 = this.thirdList.length;if (len1 === len2) return;this.thirdScroll.refresh();this.thirdIndex = 0;this.thirdScroll.scrollTo(0, 0, 300); // 注意:最顶端是0,往下的坐标是负的,时间单位ms}if (this.type === 'SHX') {if (scroll === 'first') {this.secondIndex = 0;this.secondList = this.firstList[this.firstIndex].cityList;this.secondScroll.scrollTo(0, 0, 300);this.thirdIndex = 0;this.thirdList = this.secondList[this.secondIndex].areaList;this.thirdScroll.scrollTo(0, 0, 300);}if (scroll === 'second') {this.thirdIndex = 0;this.thirdList = this.secondList[this.secondIndex].areaList;this.thirdScroll.scrollTo(0, 0, 300);}}});});},cancel() {this.show = false;this.$emit('cancel',this.lastDate);},deal() {this.show = false;if (this.type === 'YMD') {let date = `${this.firstList[this.firstIndex]}-${this.secondList[this.secondIndex]}-${this.thirdList[this.thirdIndex]}`;this.$emit('update:output',date);} else if (this.type === 'SHX') {let arr = [{code: this.firstList[this.firstIndex].code,name: this.firstList[this.firstIndex].name},{code: this.secondList[this.secondIndex].code,name: this.secondList[this.secondIndex].name},this.thirdList[this.thirdIndex]];this.$emit('update:output',arr);}}},created() {console.error('', this);switch (this.type) {case 'SHX':this.firstList = SHX;this.secondList = this.firstList[0].cityList;this.thirdList = this.secondList[0].areaList;break;default:this.initListYMD();this.lastDate = this.initYMD;}this.initScroll('first');this.initScroll('second');this.initScroll('third');this.ymdList = this.createYMD(1900, 300);}
}
</script><style scoped lang="less">@import "~ass/style/base.less";.selector{.shade {height: 100%;width: 100%;background: #333;opacity: 0.5;position: fixed;top: 0;left: 0;z-index:9;}.box{height: 491*@rpx;width: 750*@rpx;position: absolute;bottom: -500*@rpx;z-index: 10;font-size: 32*@rpx;background: @cff;display: flex;flex-direction: column;.title{height: 88*@rpx;width: 100%;display: flex;justify-content: space-between;border-bottom: 1px solid @ce5;div{line-height: 88*@rpx;}button{padding: 0 42*@rpx;color:@c80;}button:last-of-type{color:@c10;}}.section{width: 100%;flex:1;padding: 0 40*@rpx;position: relative;.wrapper{padding: 160*@rpx 0;height: 402*@rpx;overflow: hidden;ul{li{p{height: 100%;width: 100%;line-height: 80*@rpx;text-align: center;font-size: 40*@rpx;white-space:nowrap;overflow: hidden;pointer-events: none;}.second{color: @c99;font-size: 36*@rpx;}.third{color: @ccc;font-size: 32*@rpx;}}}}.lists{width: 100%;display: flex;justify-content: space-between;}.three{padding: 0 40*@rpx 0 80*@rpx;li{width: 126*@rpx;}}.threeLink{li{width: 220*@rpx;overflow: hidden;}}.line{width: 670*@rpx;height: 0;border-bottom: 1px solid @ccc;position: absolute;top: 160*@rpx;}.line:nth-of-type(2){top: 240*@rpx;}}}.up{transform: translateY(-500*@rpx);transition: transform .3s ease-in-out;}.down{transform: translateY(500*@rpx);transition: transform .3s ease-in-out;}}
</style>复制代码
<!--HTML font-size,rem-->var htmlFontSize = document.documentElement.clientWidth / 375 * 100 + 'px';var bodyFontSize = '16px';var styleDom = document.createElement('style');styleDom.innerHTML = 'html{font-size:' + htmlFontSize + '!important;}body{font-size:' + bodyFontSize + '!important;}';document.getElementsByTagName('head')[0].appendChild(styleDom)
复制代码
<!--SHX格式-->
[{"code": "820000","name": "澳门特别行政区","cityList": [{"code": "820000","name": "澳门特别行政区","areaList": [{"code": "820000","name": "澳门特别行政区"}]}]}]
复制代码

转载于:https://juejin.im/post/5cda16b3f265da03ae74e3bc

基于better-scroll实现的类似ios选择器相关推荐

  1. 创建一个delete触发器_基于 Django 信号机制实现类似触发器的效果

    我们都知道,在关系数据库中,为了保证数据完整性,我们都会使用一个叫做触发器的玩意.今天我就基于Django信号机制实现类似触发器的效果,在此之前我先简单介绍一下触发器. 触发器 触发器(trigger ...

  2. Android类似IOS的果冻效果

    转载:https://github.com/HomHomLin/SlidingLayout SlidingLayout是一种Android平台的View控件,可以帮助你实现类似微信网页浏览的下拉功能, ...

  3. mo-quarter-picker:基于 Vue2 和 ElementUI 的季度范围选择器

    mo-quarter-picker 一个基于 Vue2 和 ElementUI 的季度范围选择器 注意: 此文档是1.0版本的 2.0版本的文件请至github查看,有更新 Home: https:/ ...

  4. 基于uniapp开发DiscuzQ社区的ios和安卓、小程序H5

    Discuz!Q生成多端小程序和APP. 基于DiscuzQ!3.0版本API,使用UNIAPP框架重构,暂时没有做登录互动和支付相关功能. 基于uniapp开发DiscuzQ社区的ios和安卓.小程 ...

  5. html页面滑动不流畅,解决页面使用overflow:scroll在移动端iOS系统上滑动出现卡顿的问题...

    对某个div或模块使用了overflow: scroll属性,在iOS系统的手机上浏览时,则会出现明显的卡顿现象.但是在android系统的手机上则不会出现该问题. 通过一个早上的爬虫搜索和与前端开发 ...

  6. 安卓Android 7.1.1 shortcut实现桌面图标快捷方式跳转,类似IOS 3d touch

    一.背景介绍: 3D Touch是一种立体触控技术,被苹果称为新一代多点触控技术,是在Apple Watch上采用的Force Touch,屏幕可感应不同的感压力度触控.3D Touch,苹果iPho ...

  7. flutter 类似日期选择器控件_一切皆组件的Flutter,安能辨我是雄雌

    从一开始接触Flutter,相信读者都会铭记一句话,那就是--一切皆组件.今天我们就来体会一下这句话的神奇魔力,我们先从实际的产品需求说起. 我们先来看一个简化的运行图: 我们要实现如上图所示的日期选 ...

  8. 基于clang插件的一种iOS包大小瘦身方案

    引子 \ 包瘦身,包瘦身,包瘦身,重要的事情说三遍. \ 最近公司一款iOS APP(本文只讨论使用Objective C开发的iOS安装包)一直在瘦身,我们团队的APP也愈发庞大了.而要解决这个问题 ...

  9. 基于opencv做一个HSV的颜色选择器

    From sztu 自动化专业的小菜鸡. 本篇将介绍计算机视觉的HSV颜色选择器,基于python的opencv. 众所周知,每个物体的HSV值都是不同的,并且每个色系所在的HSV的颜色范围也都不同, ...

最新文章

  1. ActiveMQ的多节点集群
  2. mysql统计今日首充用户_电商用户行为MySQL分析
  3. 看似简单但容易忽视的编程常识
  4. 变分贝叶斯深度学习综述
  5. 天天写业务代码,如何成为技术大牛
  6. JS中的基本数据类型与引用数据类型
  7. 【算法】【JAVA】冒泡排序
  8. idea中tomcat服务器的配置
  9. 多功能计算机如何关闭,多功能的计算机显示终端
  10. android特殊用法(转)
  11. C#反射获取 所有字段 及 私有字段
  12. 使用ServiceMonitor管理配置监控
  13. 使用fastlane match自动化管理证书和描述文件
  14. caffe源码学习:softmaxWithLoss前向计算
  15. 洛谷 P1238 走迷宫【搜索】【DFS】
  16. 付费代理IP——Redis数据库的使用01
  17. [Oracle]-[OCP]-申请纸质版OCP证书
  18. 使用U8G2在oled屏幕上显示胡桃摇动画
  19. uniapp h5 发行
  20. java定义float a = 1和float a = 1f什么区别?

热门文章

  1. JavaScript全局变量和局部变量
  2. JAMA:Java矩阵包
  3. xv6 - simple modern os for education purpose.
  4. Nginx+Tomcat负载均衡群集
  5. Tomcat5.5链接Oracle、DB2、MySQL数据源实现JSP下拉框的填充
  6. slf4j+log4j在Java中实现日志记录
  7. webpack基础教程:(二)
  8. Redis 3.2.x版本 redis.conf 的配置文件参数详解
  9. 判断用户是否开启定位功能 / 判断用户是否为应用程序开启定位功能
  10. GUI Design Studio设计实例(附视频) :快速入门