基于uni-app开发刻度尺组件的实现示例

目录
  • 一、前言
  • 二、开发

一、前言

小编最近接到一个任务,就是在输入数值的时候不再使用传统的键盘了,而是用拖拉尺子的形式选择数值,大概长这样:

其实这需求不是第一次提出来了,在我们的应用第一版的时候产品就想这样做。
当然小编我当时刚接到这个任务的时候是拒绝的,你不能让我做,我就马上去做,第一我要调研一下,因为我不想花那么多时间成本开发出这个组件再加一些特技上去,

滑动超过边缘还能duang一下弹回来,但是其实用起来还没直接键盘输入数字来得方便,这样领导出来一定会骂我;后面经过一番调研和时间评估,最终选择了另一套方案:

自己写了一套数字键盘,比刻度尺简单很多,也不怎么耗性能,用起来还挺方便。

为什么不用系统自带键盘呢?这个不用说,大家都知道手机浏览器调用系统自带键盘有多恶心。
然而,该应用迎来了第二个版本,产品又把刻度尺拿了出来并扬言:“要砍需求先砍我!”。

不过确实,第二版有了更加复杂的场景,选择的数值需要限制范围,而且范围大小会随着一些条件不断变化,要想用户能直观并快速地输入正确的数值,只能是刻度尺了。

然后经过小编两分钟的深思熟虑,最终把任务接了下来。

二、开发

首先我们来看看刻度尺有哪些特点。

  • 可以滑动;
  • 根据滑动距离输出数值;
  • 滑过头了会自动回弹;

看起来,我们可以基于uni-app提供的scroll-view组件来开发,该组件有提供以下属性正好适合我们的刻度尺特性:

属性名 类型 默认值 说明
scroll-x Boolean false 允许横向滚动
scroll-left Number/String   设置横向滚动条位置
scroll-with-animation Boolean false 在设置滚动条位置时使用动画过渡
@scroll EventHandle   滚动时触发,event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}

然后第二步,需要计算刻度。
小编先设置好了默认每个刻度占10像素;

const GUTTER = 10;

然后就开始计算我们一共需要多少个刻度,其实很简单,就是你需要多少刻度,就传进来一个最大最小值,然后用最大值减去最小值,就是刻度的数量了;

这时候会出现一个交互问题,因为刻度尺的选择标是放在屏幕中间的,所以刻度尺的边界是需要显示多余的刻度用来充满屏幕,于是小编就决定生成相当于两倍于屏幕宽度的多余刻度;

// 多余的刻度数量
const extraGridCount = Math.ceil(window.innerWidth / GUTTER);
// 生成刻度数组
this.gridList = Array.from(Array(this.gridMax - this.gridMin + extraGridCount * 2)).map((_, i) => {
      const num = i + this.gridMin - extraGridCount;
      const displayNum = this.decimal === 1 ? num / 10 : num;
      return {
        num,
        displayNum,
        isLongGrid: num % GUTTER === 0,
        showText: num % GUTTER === 0 && num >= this.gridMin && num <= this.gridMax
      }
});

刻度数组内每个元素就是一个刻度对象,包含了以下属性:

  • 刻度数值
  • 刻度显示的数值(显示的数值可能会与实际数值不一致,是为了扩展小数用的)
  • 是否是长刻度(因为刻度尺每隔10个就会出现一条长刻度)
  • 是否显示刻度的数值(只有长刻度和有效刻度才会显示数值)

数组生成好,就可以根据数组来渲染整个刻度尺了;

 <u-row v-if="show" class="grid-wrapper" align="top">
    <view
        class="grid-item"
        :class="{'long': item.isLongGrid}"
        v-for="(item, i) in gridList"
        :key="i"
        :style="item.showText ? { ...gridItemStyle, height: '40px' } : gridItemStyle"
    >
      <text
          class="grid-num"
          v-if="item.showText"
      >{{item.displayNum}}</text>
    </view>
  </u-row>

渲染完毕之后,就可以通过一些算法计算刻度尺的初始位置了。然后通过scroll事件,在刻度尺滑动过程中计算数值;

scroll(e){
  const scrollLeft = e.detail.scrollLeft;
  let value = Math.floor((scrollLeft - this.offsetScroll + this.gridMin * GUTTER) / GUTTER);
  if(value < this.gridMin){
    value = this.gridMin;
  }else if(value > this.gridMax){
    value = this.gridMax;
  }}

其中offsetScroll 就是多余的那部分刻度,需要减掉的,还要判断一下是否小于最小值或者是否大于最大值; 接下来就是刻度尺的回弹了,当滑动超过最大值或最小值时,需要往回弹,在视觉上与计算好的数值保持一致; 其实也只是在滑动结束时算一下刻度尺是否应该回到边界就好了,动画上scroll-view已经帮我们解决好了;

adjustScrollPosition(){
    /** 滚动结束后调节滚动位置 */
    if(this.actualScrollLeft < this.offsetScroll){
        this.scrollLeft = this.offsetScroll + (Math.random() / 100);
    } else if(this.actualScrollLeft > (this.gridMax - this.gridMin) * GUTTER + this.offsetScroll){
        this.scrollLeft = (this.gridMax - this.gridMin) * GUTTER +
        this.offsetScroll + (Math.random() / 100);
    } else if(Math.floor(this.actualScrollLeft - this.offsetScroll) % GUTTER !== 0){
        const dryScrollLeft = this.actualScrollLeft - this.offsetScroll;
        this.scrollLeft = dryScrollLeft - dryScrollLeft % GUTTER + this.offsetScroll;
    }
}

至此,一个刻度尺组件就大致完成了。当然,还有很多细节问题没解决,比如:

  • 要是需要支持小数位怎么办呢;
  • 如果刻度过多是否有性能问题呢;
  • 等等...

这些问题就由大家思考完善一下吧

到此这篇关于基于uni-app开发刻度尺组件的实现示例的文章就介绍到这了,更多相关uni-app 刻度尺 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • uni-app实现点赞评论功能

    模拟朋友圈实时点赞及评论功能 点赞思路:点击的时候,使用push(点赞)以及slice(取消赞)方法处理数组,并且调用点赞接口 评论思路:点击的时候,写多一个评论列表,当点击发送的时候commentStatus=true,且索引等于点击的索引.同时调用获取评论列表的接口 html <view class="toolbar"> <view class="timestamp">{{item.timetype}}</view> <

  • uni-app 自定义底部导航栏的实现

    这是我目前发现较好的uni-app 自定义底部导航栏方法,其他方法的缺点主要是在切换时,要么会闪烁,要么会每点击一下,都会请求一次数据.如果有其他更好的方法,欢迎评论留言,最近才开始用uni-app写项目,之前只是看了下文档. 1. tabbar 组件 <template> <view class="tabbar-container"> <view :style="{ color: currentIndex == index ? '#007EFF

  • 微信小程序自定义tabBar在uni-app的适配详解

    引言:此方法可用作大部分微信小程序支持,但uni-app文档中却找不到相关说明的API 需求 需要在微信小程序中,实现一个中间图标突出显示的异形导航栏. 如下图 实现方法设计 要做这种异形的导航栏,用直接在配置文件里面写list的方法肯定做不到.那么,就有以下两种可替代方法. 在每一个页面都加载一个tabBar组件,与页面同时渲染. 设置自定义tabBar,修改tabBar的样式. 优缺点分析:方法1实现起来略为简单,但是会出现代码可重用率低,降低性能,已经界面跳动等问题.方法2则是微信官方提供

  • 详解vue或uni-app的跨域问题解决方案

    常见解决方案有两种 服务器端解决方案 服务器告诉浏览器:你允许我跨域 具体如何告诉浏览器,请看: // 告诉浏览器,只允许 http://bb.aaa.com:9000 这个源请求服务器 $response->header('Access-Control-Allow-Origin', 'http://bb.aaa.com:9000'); // 告诉浏览器,请求头里只允许有这些内容 $response->header('Access-Control-Allow-Headers', 'Author

  • 十步搞定uni-app使用字体图标的方法

    uni-app简介 uni-app是一个使用Vue.js开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS.Android.H5.小程序等多个平台.   uni-app框架由Dcloud即数字天堂(北京)网络技术有限公司推出,该公司主要产品有Web开发IDE Hbuiler.HbuilderX,前端框架mui.uni-app,增强版的手机浏览器引擎H5plus等. uni-app中使用字体图标图标的下载 首先去阿里图标库选择要用的图标,并且打包下载下来,步骤如下 1. 2. 3. 4.

  • uni-app之APP和小程序微信授权方法

    uni-app 介绍 uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架. 适用平台:Android.iOS.微信小程序.实现了一套代码,同时发布到Android.iOS.微信小程序. 参考官方:https://uniapp.dcloud.io/ APP微信授权 检测服务商 检测手机上是否安装微信.QQ.新浪微博等. uni.getProvider({ service: 'oauth', success: function (res) { console.log(res.prov

  • uni-app如何页面传参数的几种方法总结

    uni.$emit(eventName,OBJECT) 触发全局的自定事件.附加参数都会传给监听器回调. 其中eventName为事件名,OBJECT为触发事件附加参数 示例代码如下: uni.$emit('update',{msg:'页面更新'}) uni.$on(eventName,callback) 监听全局自定义事件,事件由uni.$emit()触发,回调函数会接收所有传入的数. eventName为事件名,callback为事件的回调函数. 示例代码如下: uni.$on('updat

  • uni-app自定义导航栏按钮|uniapp仿微信顶部导航条功能

    最近一直在学习uni-app开发,由于uniapp是基于vue.js技术开发的,只要你熟悉vue,基本上很快就能上手了. 在开发中发现uni-app原生导航栏也能实现一些顶部自定义按钮+搜索框,只需在page.json里面做一些配置即可.设置app-plus,配置编译到App平台的特定样式.dcloud平台对app-plus做了详细说明:app-plus配置,需注意 目前暂支持H5.App端,不支持小程序. 在page.json里配置app-plus即可 { "path": "

  • 基于uni-app开发刻度尺组件的实现示例

    目录 一.前言 二.开发 一.前言 小编最近接到一个任务,就是在输入数值的时候不再使用传统的键盘了,而是用拖拉尺子的形式选择数值,大概长这样: 其实这需求不是第一次提出来了,在我们的应用第一版的时候产品就想这样做.当然小编我当时刚接到这个任务的时候是拒绝的,你不能让我做,我就马上去做,第一我要调研一下,因为我不想花那么多时间成本开发出这个组件再加一些特技上去, 滑动超过边缘还能duang一下弹回来,但是其实用起来还没直接键盘输入数字来得方便,这样领导出来一定会骂我:后面经过一番调研和时间评估,最

  • Android APP开发KML轨迹导出教程示例

    目录 引言 写入kml gps点 奥森10km 轨迹图 引言 前两天在知乎上面找海外骑行.跑步软件Strava的时候,看到一个将运动轨迹从A App 导出,导入到B APP的工具 APP RunGap,恰巧之前给台湾.印度那边的测试同事处理他们的问题时,写过这样的一个工具,KML文件导出,然后在Mac下的 Google 地球上看轨迹是否偏差,是否存在坐标类型的转化错误等问题,能够比较快地定位问题. KML文件,读者有不知道的可以Google一下,它是一种专门存GPS 点数据的xml文件格式. 将

  • 基于Vue3.0开发轻量级手机端弹框组件V3Popup的场景分析

    之前有分享一个vue2.x移动端弹框组件,今天给大家带来的是Vue3实现自定义弹框组件. V3Popup 基于vue3.x实现的移动端弹出框组件,集合msg.alert.dialog.modal.actionSheet.toast等多种效果.支持20+种自定义参数配置,旨在通过极简的布局.精简的调用方式解决多样化的弹框场景. v3popup 在开发之初参考借鉴了Vant3.ElementPlus等组件化思想.并且功能效果和之前vue2.0保持一致. ◆ 快速引入 在main.js中全局引入v3p

  • 鸿蒙HarmonyOS App开发造轮子之自定义圆形图片组件的实例代码

    一.背景 在采用Java配合xml布局编写鸿蒙app页面的时候,发现sdk自带的Image组件并不能将图片设置成圆形,反复了翻阅了官方API手册(主要查阅了Compont和Image相关的API),起初发现了一个setCornerRadius方法,于是想着将图片宽度和高度设置为一样,然后调用该方法将radios设置为宽度或者高度的一半,以为可以实现圆形图片的效果,后来发现不行.于是乎想着能不能通过继承原有的Image自己来动手重新自定义一个支持圆形的图片组件. 二.思路: 1.对比之前自己在其他

  • 详解基于Vue cli开发修改外部组件Vant默认样式

    前言 在引入外部组件的时候,想要修改默认样式,可以通过class修改,但一般会有权重不够等各种原因,官网其实列出了一套主题定制的方案,通过覆盖配置文件来修改样式,官网地址:主题定制 提示:以下是本篇文章正文内容,下面案例可供参考 一.Less 因为Vant 使用了 Less 对样式进行预处理,并内置了一些样式变量,可以通过替换样式变量即可定制你自己需要的主题. 给你的项目配置less: npm install less --save-dev npm install less-loader --s

  • Mint UI 基于 Vue.js 移动端组件库

    官网地址 http://mint-ui.github.io/ Mint UI 包含丰富的 CSS 和 JS 组件,能够满足日常的移动端开发需要.通过它,可以快速构建出风格统一的页面,提升开发效率. 真正意义上的按需加载组件.可以只加载声明过的组件及其样式文件,无需再纠结文件体积过大. 考虑到移动端的性能门槛,Mint UI 采用 CSS3 处理各种动效,避免浏览器进行不必要的重绘和重排,从而使用户获得流畅顺滑的体验. 依托 Vue.js 高效的组件化方案,Mint UI 做到了轻量化.即使全部引

  • 详解Weex基于Vue2.0开发模板搭建

    前言 最近有一些人反馈说在面试过程中常常被问到weex相关的知识,也侧面反映的weex的发展还是很可观的,可是目前weex的开发者大多数是中小型公司或者个人,大公司屈指可数,揪其原因可能是基于weex的开发正确的姿势大家并没有找到,而且市面上的好多轮子还是.we后缀的,众所周知,weex和vue一直在努力的进行生态互通,而且weex实现web标准化是早晚的问题,今天和大家分享一下weex基于vue2.0的开发框架模板~ 工作原理 先简单熟悉一下weex的工作原理,这里引用一下weex官网上的一直

  • android使用webwiew载入页面使用示例(Hybrid App开发)

    Hybrid App 是混合模式应用的简称,兼具 Native App 和 Web App 两种模式应用的优势,开发成本低,拥有 Web 技术跨平台特性.目前大家所知道的基于中间件的移动开发框架都是采用的 Hybrid 开发模式,例如国外的 PhoneGap.Titanium.Sencha,还有国内的 AppCan.Rexsee 等等.Hybrid App 开发模式正在被越来越多的公司和开发者所认同,相信将来会成为主流的移动应用开发模式. Hybrid App 融合 Web App 的原理就是嵌

  • uni app仿微信顶部导航条功能

    最近一直在学习uni-app开发,由于uniapp是基于vue.js技术开发的,只要你熟悉vue,基本上很快就能上手了. 在开发中发现uni-app原生导航栏也能实现一些顶部自定义按钮+搜索框,只需在page.json里面做一些配置即可.设置app-plus,配置编译到App平台的特定样式.dcloud平台对app-plus做了详细说明:app-plus配置,需注意 目前暂支持H5.App端,不支持小程序. 在page.json里配置app-plus即可 { "path": "

  • 基于Vue2-Calendar改进的日历组件(含中文使用说明)

    一,前言 我是刚学Vue的菜鸟,在使用过程中需要用到日历控件,由于项目中原来是用jQuery写的,因此用了bootstarp的日历控件,但是配合Vue实在有点蛋疼,不够优雅-- 于是网上搜了好久找到了Vue2-Calendar,不用说,挺好用的,但是同时也发现这个组件有些问题,有些功能挺不符合我们的要求,于是着手改了一版 二,改进的功能 在Vue2-Calendar v2.2.4 版基础上作了优化. 1.改进原控件无法切换语言的BUG,支持 lang='zh-CN'和'en'. 2.日历面板增加

随机推荐