Element基于el-input數(shù)字范圍輸入框的實現(xiàn)
數(shù)字范圍組件

在做篩選時可能會出現(xiàn)數(shù)字范圍的篩選,例如:價格、面積,但是elementUI本身沒有自帶的數(shù)字范圍組件,于是進行了簡單的封裝,不足可自行進行優(yōu)化
滿足功能:
- 最小值與最大值的相關(guān)約束,當(dāng)最大值存在,最小值大于最大值且失焦,自動將最小值賦值為最大值,反之亦然。
- 擁有el-input組件本身的屬性綁定以及方法
- 可設(shè)置精度,默認精度為0
- 可使用
el-input插槽,但需要加前綴start-,end-進行區(qū)分
<numberRange :startValue.sync="startValue" :endValue.sync="endValue" />
相關(guān)代碼:
<template>
<div class="input-number-range" :class="{ 'is-disabled': disabled }">
<div class="flex">
<el-input
ref="inputFromRef"
clearable
v-model="startValue"
:disabled="disabled"
:placeholder="startPlaceholder"
@blur="handleBlurFrom"
@focus="handleFocusFrom"
@input="handleInputFrom"
@change="handleInputChangeFrom"
v-bind="$attrs"
v-on="$listeners"
>
<template v-for="(value, name) in startSlots" #[name]="slotData">
<slot :name="name" v-bind="slotData || {}"></slot>
</template>
</el-input>
<div class="center">
<span>至</span>
</div>
<el-input
ref="inputToRef"
clearable
v-model="endValue"
:disabled="disabled"
:placeholder="endPlaceholder"
@blur="handleBlurTo"
@focus="handleFocusTo"
@input="handleInputTo"
@change="handleInputChangeTo"
v-bind="$attrs"
v-on="$listeners"
>
<template v-for="(value, name) in endSlots" #[name]="slotData">
<slot :name="name" v-bind="slotData || {}"></slot>
</template>
</el-input>
</div>
</div>
</template>
<script>
export default {
name: "InputNumberRange",
props: {
// inputs: {
// type: Array,
// required: true,
// default: () => [null, null],
// },
startValue: {
type: Number || String,
default: null,
},
endValue: {
typeof: Number || String,
default: null,
},
// 是否禁用
disabled: {
type: Boolean,
default: false,
},
startPlaceholder: {
type: String,
default: "最小值",
},
endPlaceholder: {
type: String,
default: "最大值",
},
// 精度參數(shù)
precision: {
type: Number,
default: 0,
validator(val) {
return val >= 0 && val === parseInt(val, 10);
},
},
},
data() {
return {};
},
computed: {
startSlots() {
const slots = {};
Object.keys(this.$slots).forEach((name) => {
if (name.startsWith("start-")) {
const newKey = name.replace(/^start-/, "");
slots[newKey] = this.$slots[name];
}
});
return slots;
},
endSlots() {
const slots = {};
Object.keys(this.$slots).forEach((name) => {
if (name.startsWith("end-")) {
const newKey = name.replace(/^end-/, "");
slots[newKey] = this.$slots[name];
}
});
return slots;
},
},
watch: {},
methods: {
handleInputFrom(value) {
this.$emit("update:startValue", value);
},
handleInputTo(value) {
this.$emit("update:endValue", value);
},
// from輸入框change事件
handleInputChangeFrom(value) {
// 如果是非數(shù)字空返回null
if (value == "" || isNaN(value)) {
this.$emit("update:startValue", null);
return;
}
// 初始化數(shù)字精度
const newStartValue = this.setPrecisionValue(value);
// 如果from > to 將from值替換成to
if (
typeof newStartValue === "number" &&
parseFloat(newStartValue) > parseFloat(this.endValue)
) {
this.startValue = this.endValue;
} else {
this.startValue = newStartValue;
}
if (this.startValue !== value) {
this.$emit("update:startValue", this.startValue);
}
},
// to輸入框change事件
handleInputChangeTo(value) {
// 如果是非數(shù)字空返回null
if (value == "" || isNaN(value)) {
this.$emit("update:endValue", null);
return;
}
// 初始化數(shù)字精度
const newEndValue = this.setPrecisionValue(value);
// 如果from > to 將from值替換成to
if (
typeof newEndValue === "number" &&
parseFloat(newEndValue) < parseFloat(this.startValue)
) {
this.endValue = this.startValue;
} else {
this.endValue = newEndValue;
}
if (this.endValue !== value) {
this.$emit("update:endValue", this.endValue);
}
},
handleBlurFrom(event) {
this.$emit("blur-from", event);
},
handleFocusFrom(event) {
this.$emit("focus-from", event);
},
handleBlurTo(event) {
this.$emit("blur-to", event);
},
handleFocusTo(event) {
this.$emit("focus-to", event);
},
// 根據(jù)精度保留數(shù)字
toPrecision(num, precision) {
if (precision === undefined) precision = 0;
return parseFloat(
Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision)
);
},
// 設(shè)置精度
setPrecisionValue(value) {
if (this.precision === undefined) return value;
return this.toPrecision(parseFloat(value), this.precision);
},
},
};
</script>
<style lang="scss" scoped>
// 取消element原有的input框樣式
::v-deep .el-input__inner {
border: 0px;
margin: 0;
padding: 0 15px;
background-color: transparent;
}
.input-number-range {
background-color: #fff;
border: 1px solid #dcdfe6;
border-radius: 4px;
}
.flex {
display: flex;
flex-direction: row;
width: 100%;
height: auto;
justify-content: center;
align-items: center;
.center {
margin-top: 1px;
}
}
.is-disabled {
background-color: #f5f7fa;
border-color: #e4e7ed;
color: #c0c4cc;
cursor: not-allowed;
}
</style>到此這篇關(guān)于 Element基于el-input數(shù)字范圍輸入框的實現(xiàn)的文章就介紹到這了,更多相關(guān) Element el-input輸入框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue 父子組件實現(xiàn)數(shù)據(jù)雙向綁定效果的兩種方式(案例代碼)
本文給大家分享Vue 父子組件實現(xiàn)數(shù)據(jù)雙向綁定效果的兩種方式,方式一是通過監(jiān)聽事件實現(xiàn)方式二是通過 v-model 實現(xiàn),每種方式結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2022-11-11
Vue3中的ref為何要用.value進行值的調(diào)用呢
這篇文章主要介紹了Vue3中的ref為何要用.value進行值的調(diào)用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
Vue使用pinia管理數(shù)據(jù)pinia持久化存儲問題
這篇文章主要介紹了Vue使用pinia管理數(shù)據(jù)pinia持久化存儲問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
使用vuex解決刷新頁面state數(shù)據(jù)消失的問題記錄
這篇文章主要介紹了使用vuex解決刷新頁面state數(shù)據(jù)消失的問題記錄,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
vue2.0和mintui-infiniteScroll結(jié)合如何實現(xiàn)無線滾動加載
這篇文章主要介紹了vue2.0和mintui-infiniteScroll結(jié)合如何實現(xiàn)無線滾動加載,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10

