前言
这篇我们继续研究InputNumber。
基本实现
基本的准备工作过后,开始基本实现。
上测试代码:
<el-input-number v-model="num" @change="handleChange" :min="1" :max="10" label="描述文字"> </el-input-number>
上组件代码:
<template> <div :class="[ 'el-input-number', ]" > <span class="el-input-number__decrease" role="button" :class="{'is-disabled': minDisabled}" @click="decrease" > <i class="el-icon-minus"></i> </span> <span class="el-input-number__increase" role="button" :class="{'is-disabled': maxDisabled}" @click="increase" > <i class="el-icon-plus"></i> </span> <el-input ref="input" :value="value" @input="value => $emit('input', value)" > </el-input> </div> </template> <script> import ElInput from '../Input/index' export default { name: 'ElInputNumber', props: { value: {}, max: { type: Number, default: Infinity }, min: { type: Number, default: -Infinity }, }, computed: { minDisabled() { return this.value - 1 < this.min; }, maxDisabled() { return this.value + 1 > this.max; }, }, methods: { decrease() { if(this.minDisabled) return this.$emit('input', this.value - 1) }, increase() { if(this.maxDisabled) return this.$emit('input', this.value + 1) } }, components: { ElInput } } </script>
上效果:
这次可以复用Input组件,两边加新增/减少两个按钮,实现加减逻辑。再控制最大值最小值的时候,禁用按钮,基本实现完成。
点击按钮持续增加/减少
现在添加:点击加减按钮的时候,不抬起鼠标,值就会持续增加/减少的特性。
要实现此功能,源码中用到了directive自定义指令,靠节流mousedown事件来实现持续点击效果。
写自定义命令:
import { once, on } from '../utils/dom'; export default { bind(el, binding, vnode) { let interval = null; let startTime; // binding.expression 就是decrease/increase 事件名称 // handler就是对应的相应函数 const handler = () => vnode.context[binding.expression].apply(); const clear = () => { if (Date.now() - startTime < 100) { handler(); } clearInterval(interval); interval = null; }; on(el, 'mousedown', (e) => { if (e.button !== 0) return; startTime = Date.now(); once(document, 'mouseup', clear); clearInterval(interval); // 实现节流 interval = setInterval(handler, 100); }); } };
在组件中使用自定义命令:
import RepeatClick from '../../directives/repeat-click'; directives: { repeatClick: RepeatClick }, <span class="el-input-number__decrease" role="button" :class="{'is-disabled': minDisabled}" v-repeat-click="decrease" > <i class="el-icon-minus"></i> </span> <span class="el-input-number__increase" role="button" :class="{'is-disabled': maxDisabled}" v-repeat-click="increase" > <i class="el-icon-plus"></i> </span>
禁用状态
- 添加 { 'is-disabled': disabled } 到根节点样式上。
- 添加:disabled="disabled"到el-input节点上。
- 添加if(this.disabled) return 到decrease/increase方法上。
完成效果:
步数
上测试代码:
<el-input-number v-model="num" :step="2"></el-input-number>
给组件添加step属性。在组件中把+/-1这样到代码替换为+/- this.step。
严格步数
step-strictly属性接受一个Boolean。如果这个属性被设置为true,则只能输入步数的倍数。
上测试代码:
<el-input-number v-model="num" :step="2" step-strictly></el-input-number>
要想实现严格步数,我们直接输入的值,会检查是不是step的倍数,如果不是,则换成step的倍数。这就不能直接把InputNumber的value直接绑定在内部的el-input上了。先在el-input的input事件记录输入的值。再在change事件中将值赋予给value,最后在watch.value上校验输入的值,并转换成step的倍数。
data() { return { currentValue: 0, // 缓存上次输入的值 userInput: null, // 缓存当前输入的值 }; }, <el-input ref="input" :disabled="disabled" :value="currentValue" // 变为绑定currentValue @input="handleInput" @change="handleInputChange" > </el-input> // 先在el-input的input事件记录输入的值 handleInput(value) { this.userInput = value; }, // 在change事件中将值赋予给value handleInputChange(value) { let newVal = value === '' "color: #ff0000">精度上测试代码:
<el-input-number v-model="numPrecision" :precision="2" :step="0.1" :max="10"></el-input-number>这里step变成小数了,那在累加得过程中,就会有0.1+0.2这样得精度问题出现了。element的解决思路是将值扩大精度倍进行计算,得到结果后再除以精度倍数。
increase() { if(this.maxDisabled || this.disabled) return const value = this.value || 0; const newVal = this._increase(value, this.step); this.setCurrentValue(newVal); }, _increase(val, step) { if (typeof val !== 'number' && val !== undefined) return this.currentValue; // step是0.1,precisionFactor是10。 const precisionFactor = Math.pow(10, this.numPrecision); return this.toPrecision((precisionFactor * val + precisionFactor * step) / precisionFactor); }, // 确保计算得结果0.10000000001这种误差情况会被消除 toPrecision(num, precision) { if (precision === undefined) precision = this.numPrecision; return parseFloat(Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision)); },在展示的时候,利用toFixed函数展示精度即可。
效果如下:
尺寸
添加size属性,在根元素得样式添加size "text-align: center">
按钮位置
设置 controls-position 属性可以控制按钮位置。
上测试代码:
<el-input-number v-model="num" controls-position="right" @change="handleChange" :min="1" :max="10"> </el-input-number>通过controls-position='right',在组件内控制样式即可。
效果如下:
总结
严格步数和精度这两个特性得逻辑稍有些复杂,需要多研究一会。
源码在码云: https://gitee.com/DaBuChen/my-element-ui/tree/input-number
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】