InputNumer 组件的难点在于:基于 Input 组件进行二次拓展的 InputNumber 组件html
代码git
<!-- 基础用法 -->
<fat-radio-group v-model="value">
<fat-radio :value="1">备选项</fat-radio>
<fat-radio :value="2">备选项</fat-radio>
</fat-radio-group>
<!-- 禁用状态 -->
<fat-radio-group v-model="anotherValue">
<fat-radio :value="1">备选项</fat-radio>
<fat-radio :value="2" disabled>备选项</fat-radio>
</fat-radio-group>
<!-- 步数 -->
<fat-input-number :step="5" v-model="stepValue" />
<!-- 最大,最小值限制 -->
<fat-input-number :max="20" :min="0" :step="5" v-model="value" />
复制代码
实例地址:InputNumber 实例github
代码地址:Github UI-Librarybash
首先利用 Input 组件,在其 slot prepend
和 slot append
两个插槽内,插入相应的加、减按钮,具体以下。app
<fat-input
class="input-number-inner"
type="text"
:disabled="disabled"
v-model="inputValue"
v-bind="$attrs"
>
<template slot="prepend">
<div
:class="['prepend-part', { 'is-disabled': addDisabled }]"
@mousedown.stop="!addDisabled && handleClick('add')"
>
<fat-icon name="add" size="16"/>
</div>
</template>
<template slot="append">
<div
:class="['append-part', { 'is-disabled': decDisabled }]"
@mousedown.stop="!decDisabled && handleClick('dec')"
>
<fat-icon name="remove" size="16"/>
</div>
</template>
</fat-input>
复制代码
接下來实现加、减按钮的长按功能,其本质就是将 click
事件分为了,mousedown
以及 mouseup
两个事件来处理,具体体如今 handleClick
函数。函数
handleClick(type) {
const { step } = this;
const period = 100;
const timerHandler = () => {
const { addDisabled, decDisabled } = this;
if (!addDisabled && type === "add") this.inputNumberValue += step;
if (!decDisabled && type === "dec") this.inputNumberValue -= step;
};
const timer = setInterval(timerHandler, period);
const startTime = new Date();
const handler = () => {
const endTime = new Date();
if (endTime - startTime < period) timerHandler();
clearInterval(timer);
document.removeEventListener("mouseup", handler, false);
};
document.addEventListener("mouseup", handler, false);
}
复制代码
首先,监听按钮的 mousedown
,当它触发时完成如下操做:ui
startTime
;setInterval
,每隔一个 period
就调用相应的 timerHandler
函数,来模拟长按操做;document
上监听 mouseup
事件,当鼠标还原时触发。而后,当鼠标还原时,就会触发 document
的 mouseup
事件,此时相应的处理为:this
endTime
,若是知足 endTime - startTime < period
条件,则执行一次 timerHandler
;clearInterval
中止 setInterval
,以后移除对 mouseup
的监听。因为每次修改 InputNumber 组件的值时,都需判断是否超出最大、最小值、或是输入的值是否为数字等规则,即便将这些规则抽象为一个函数,也会显得代码有些臃肿,因此选用 computed
属性对 inputValue
状态进行一层代理,具体以下spa
computed: {
inputNumberValue: {
get() {
return this.inputValue;
},
set(value) {
const { min, max, inputValue } = this;
const limits = [{
need: value => !isNum(value),
value: inputValue
}, {
need: value => value >= max,
value: max
}, {
need: value => value <= min,
value: min
}, {
need: () => true,
value: value
}];
this.inputValue = limits.find(limit => limit.need(value)).value;
}
}
}
复制代码
将对 inputValue
的修改,转变为对 inputNumberValue
的修改,同时劫持 get
,set
函数,在 set
中,定义规则。设计
实现了基础的InputNumber,后续能够在自行在样式上进行扩展。
<!-- 基础用法 -->
<fat-input-number v-model="value" />
<!-- 禁用状态 -->
<fat-input-number disabled />
<!-- 步数 -->
<fat-input-number :step="5" v-model="stepValue" />
<!-- 最大,最小值限制 -->
<fat-input-number :max="20" :min="0" :step="5" v-model="value" />
复制代码
原创声明: 该文章为原创文章,转载请注明出处。