基于el-input的数字范围输入框

文章介绍了一个用于筛选的数字范围组件,该组件是对elementUI的扩展,用于处理价格、面积等筛选场景。组件实现了最小值和最大值的约束逻辑,当输入值违反约束时会自动调整。此外,它还支持el-input的属性绑定、精度设置和插槽功能。
摘要由CSDN通过智能技术生成

数字范围组件

在这里插入图片描述

在做筛选时可能会出现数字范围的筛选,例如:价格、面积,但是elementUI本身没有自带的数字范围组件,于是进行了简单的封装,不足可自行进行优化

满足功能:

  1. 最小值与最大值的相关约束,当最大值存在,最小值大于最大值且失焦,自动将最小值赋值为最大值,反之亦然。
  2. 拥有el-input组件本身的属性绑定以及方法
  3. 可设置精度,默认精度为0
  4. 可使用el-input插槽,但需要加前缀start-end-进行区分
<numberRange :startValue.sync="startValue" :endValue.sync="endValue" />

相关代码:

<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: "最大值",
    },
    // 精度参数
    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) {
      // 如果是非数字空返回null
      if (value == "" || isNaN(value)) {
        this.$emit("update:startValue", null);
        return;
      }
      // 初始化数字精度
      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) {
      // 如果是非数字空返回null
      if (value == "" || isNaN(value)) {
        this.$emit("update:endValue", null);
        return;
      }
      // 初始化数字精度
      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);
    },
    // 根据精度保留数字
    toPrecision(num, precision) {
      if (precision === undefined) precision = 0;
      return parseFloat(
        Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision)
      );
    },
    // 设置精度
    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>
根据引用,el-input-number有几个不同的版本和形式,包括UMD和ECMAScript Module。这些文件分别提供了不同的功能和压缩选项。 根据引用,el-input-number是一个基于Vue的输入框组件,可以使用v-model指令来进行双向数据绑定,并使用min和max属性限制输入的最小和最大值。在这个例子中,el-input-number被用于绑定customEdit.currEpisodeIndex,并通过:min和:max属性设置了最小值和最大值。 然而,根据引用,出现警告可能是因为数据类型不匹配。尽管你的类型是匹配的,但仍然有可能遇到其他类型问题。这可能导致输入框隐藏或产生其他问题。 综上所述,要隐藏el-input-number输入框,可以考虑以下几点: 1. 确保使用正确的el-input-number版本和形式,根据你的需求选择合适的文件。 2. 检查使用的v-model和属性是否正确绑定,并确保数据类型匹配。 3. 检查输入框是否被其他样式或组件覆盖。可以通过调整CSS样式或查看组件层次结构来解决。 请根据具体情况检查这些因素,并根据需要进行调整,以便隐藏el-input-number输入框。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vue-number-input:Vue.js数字输入组件](https://download.csdn.net/download/weixin_42138376/16605965)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [element-plus 使用 el-input-number 数字输入框 出现 Maximum recursive updates exceeded](https://blog.csdn.net/weixin_43873389/article/details/126227357)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凡小多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值