您好,登錄后才能下訂單哦!
今天小編給大家分享一下基于element UI input組件自行封裝數(shù)字區(qū)間輸入框組件的問題怎么解決的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
在開發(fā)時遇到一個數(shù)字區(qū)間輸入框的需求,如下圖:
項目使用的是vue,組件庫用的是element UI,但是element UI并沒有提供數(shù)字區(qū)間組件,只提供了InputNumber 計數(shù)器輸入框,如果用兩個計數(shù)器輸入框進行拼接也能滿足需求,但是樣式調(diào)試起來太過于復(fù)雜且不夠靈活,不能令人滿意,并且該數(shù)字區(qū)間輸入框在其它界面也有這種需求,于是就在element input輸入框的基礎(chǔ)上自行封裝了一個數(shù)字區(qū)間組件使用。
實現(xiàn)效果如下:
使用方式如下:
<input-number-range :disabled="isDisabled" :precision="num" v-model="value"></input-number-range>
其中disabled屬性控制是否禁用,precision屬性控制精度默認為0即只能輸入整數(shù),v-model雙向綁定要傳遞的值,該值是一個數(shù)組類型 [最小值,最大值]
另外該組件只能輸入數(shù)字,輸入其他非數(shù)字,或錯誤數(shù)字(多個小數(shù))都會默認為空;在先輸入最小值時,如果后輸入的最大值小于最小值,則最大值默認為最小值,同理先輸入最大值時,如果后輸入的最小值大于最大值,則最小值默認為最大值
實現(xiàn)代碼可以分為兩塊一塊為組件的封裝代碼,一塊為上述實現(xiàn)效果的演示代碼
數(shù)字區(qū)間組件代碼
<template> <div> <div class="input-number-range" :class="{ 'is-disabled': disabled }"> <div class="flex"> <div class="from"> <!-- blur:最小值失焦事件 focus:最小值聚焦事件 input:最小值輸入事件 change:最小值change事件 --> <el-input ref="input_from" v-model="userInputForm" :disabled="disabled" placeholder="最小值" @blur="handleBlurFrom" @focus="handleFocusFrom" @input="handleInputFrom" @change="handleInputChangeFrom" ></el-input> </div> <div class="center"> <span>至</span> </div> <div class="to"> <!-- blur:最大值失焦事件 focus:最大值聚焦事件 input:最大值輸入事件 change:最大值change事件 --> <el-input ref="input_to" v-model="userInputTo" :disabled="disabled" placeholder="最大值" @blur="handleBlurTo" @focus="handleFocusTo" @input="handleInputTo" @change="handleInputChangeTo" ></el-input> </div> </div> </div> </div> </template> <script> export default { name: "InputNumberRange", /** 組件接收參數(shù) */ props: { value: { required: true }, // 是否禁用 disabled: { type: Boolean, default: false, }, // 精度參數(shù) precision: { type: Number, default: 0, validator(val) { return val >= 0 && val === parseInt(val, 10); }, }, }, data() { return { userInputForm: null, // 最小值 userInputTo: null, // 最大值 }; }, watch: { /** 監(jiān)聽value實現(xiàn)雙向綁定 */ value: { immediate: true, handler(value) { // 判斷是否為數(shù)字number類型 if (value instanceof Array && this.precision !== undefined) { let fromVal = value[0] && typeof value[0] === "number" ? value[0] : null; let toVal = value[1] && typeof value[1] === "number" ? value[1] : null; this.userInputForm = fromVal ? fromVal : null; this.userInputTo = toVal ? toVal : null; } }, }, }, methods: { // 根據(jù)精度保留數(shù)字 toPrecision(num, precision) { if (precision === undefined) precision = 0; return parseFloat( Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision) ); }, /** 觸發(fā)以下事件時自動向上冒泡執(zhí)行(通過emit將事件拋給element input組件) */ handleBlurFrom(event) { this.$emit("blurfrom", event); }, handleFocusFrom(event) { this.$emit("focusfrom", event); }, handleBlurTo(event) { this.$emit("blurto", event); }, handleFocusTo(event) { this.$emit("focusto", event); }, handleInputFrom(value) { this.$emit("inputfrom", value); this.userInputFrom = value; }, handleInputTo(value) { this.$emit("inputto", value); this.userInputTo = value; }, // from輸入框change事件 handleInputChangeFrom(value) { const newVal = this.setPrecisionValue(value); this.userInputForm = newVal; // 如果初始化數(shù)字的精度不符合代碼設(shè)置時重置數(shù)字 this.userInputTo = this.setPrecisionValue(this.userInputTo); if (!this.userInputForm && !this.userInputTo) { this.$emit("input", []); this.$emit("changefrom", newVal); return; } if (!this.userInputTo) { this.userInputForm = newVal; } else { // 最小值大于最大值時邏輯判斷 this.userInputForm = !newVal || parseFloat(newVal) <= parseFloat(this.userInputTo) ? newVal : this.userInputTo; } this.$emit("input", [this.userInputForm, this.userInputTo]); this.$emit("changefrom", newVal); }, // to輸入框change事件 handleInputChangeTo(value) { const newVal = this.setPrecisionValue(value); this.userInputTo = newVal; this.userInputForm = this.setPrecisionValue(this.userInputForm); if (!this.userInputTo && !this.userInputForm) { this.$emit("input", []); this.$emit("changefrom", newVal); return; } if (!this.userInputForm) { this.userInputTo = newVal; } else { // 最大值小于最小值時邏輯判斷 this.userInputTo = !newVal || parseFloat(newVal) >= parseFloat(this.userInputForm) ? newVal : this.userInputForm; } this.$emit("input", [this.userInputForm, this.userInputTo]); this.$emit("changeto", newVal); }, // 設(shè)置成精度數(shù)字 setPrecisionValue(value) { if (!value) return null; const newVal = Number(value); // 如果是非數(shù)字空返回null if (isNaN(value)) return null; if (typeof newVal === "number" && this.precision !== undefined) { const val = this.toPrecision(value, this.precision); return val; } return null; }, }, }; </script> <style lang="scss" scoped> // 取消element原有的input框樣式 ::v-deep .el-input .el-input__inner { border: 0px; margin: 0; padding: 0 15px; background-color: transparent; text-align: center; } .input-number-range { background-color: #fff; border: 1px solid #dcdfe6; border-radius: 4px; } .flex { display: flex; flex-direction: row; width: 100%; justify-content: center; align-items: center; .center { margin-top: 1px; } } .is-disabled { background-color: #f5f7fa; border-color: #e4e7ed; color: #c0c4cc; cursor: not-allowed; } </style>
上述就是完整的組件代碼,寫好組件代碼后,就是在項目中使用,有兩種方式,一種是使用時在通過引用進行使用如下:
<template> <div> <InputNumberRange></InputNumberRange> </div> </template> <script> import InputNumberRange from './components/inputNumberRange.vue' export default { name: "XXXX" components: { InputNumberRange, }, data() {} } </script>
另一種方式是在main.js中進行全局組測,這樣就可以自由使用<input-number-range>標(biāo)簽,如下:
import InputNumberRange from './components/inputNumberRange.vue' Vue.component(InputNumberRange.name, InputNumberRange)
示例演示代碼
<template> <div class="main"> <!-- 演示操作按鈕模塊 --> <div class="caseHeader"> <div> <el-switch v-model="isDisabled" size="small" active-text="禁用" @change="switchChange" > </el-switch> </div> <div > <span>精度:</span> <el-input-number size="small" v-model="num" @change="precisionChange" :min="0" :max="10" label="描述文字" ></el-input-number> </div> <div> <el-button type="link" size="small" @click="reset">重置</el-button> </div> </div> <!-- 數(shù)字區(qū)間使用模塊 --> <div class="numberRange"> <el-form ref="form" :model="formData" label-width="80px"> <el-form-item label="數(shù)字區(qū)間"> <input-number-range :disabled="isDisabled" :precision="num" v-model="formData.numberRange" ></input-number-range> </el-form-item> </el-form> </div> </div> </template> <script> export default { name: "TestCase", data() { return { isDisabled: false, // 是否禁用 num: 0, // 精度 formData: { numberRange: [], }, }; }, methods: { /** 重置方法 */ reset() { this.formData.numberRange = []; } }, }; </script> <style lang="scss" scoped> .main { width: 100%; margin: 16px; position: relative; } .numberRange { width: 400px; } .caseHeader { width: 400px; display: flex; justify-content: space-between; margin: 24px; } </style>
以上就是“基于element UI input組件自行封裝數(shù)字區(qū)間輸入框組件的問題怎么解決”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。