vue中,v-model与UI框架中的输入框组件的二次封装

一、介绍

在vue项目中,我们会用到很多类型的框架,例如:ElementUI等等。
此时如果我们要二次封装UI框架中的输入框组件时,你会想用v-model的方式进行绑定来实现。那么这篇博客可能能帮到你。

二、封装组件

numberInput.vue子组件文件:

<template>
  <div class="flex">
    <el-input class="input" :value="value" placeholder="填数字" @input="inputChange($event)"></el-input>
    <div class="btn-group input-border-color">
      <div class="btn" @click="onClickChangeBtn('add')">+</div>
      <div class="btn input-border-color" @click="onClickChangeBtn('sub')">-</div>
    </div>
  </div>
</template>

<script>
export default {
      
      
  name: "NumberInputComponent",
  props: {
      
      
    value: String | Number  // 这里接收父组件v-model绑定的变量
  },
  data() {
      
      
    return {
      
      }
  },
  methods: {
      
      
    inputChange(val) {
      
      
      if (["", undefined].includes(val)) {
      
       val = "" }
      // 在这里就修改了父组件中,用v-model绑定的变量的值。父组件的变量修改后,numberInput.vue中props中的value值就跟着改变了。
      this.$emit("input", val)
    },
    onClickChangeBtn(type) {
      
      
      var num = parseInt(this.value)
      if (isNaN(num)) {
      
       num = 0 }
      if (type === "add") {
      
      
        num++
      } else {
      
      
        num--
      }
      if (num < 0) {
      
       num = 0 }
      this.$emit("input", num)
    }
  }
}
</script>

<style lang="scss" scoped>
.input {
      
      
  width: 70px !important;
  & ::v-deep .el-input__inner {
      
      
    padding: 0 10px !important;
  }
}

.btn-group {
      
      
  display: flex;
  flex-direction: column;
  width: 30px;
  height: 40px;
  box-sizing: border-box;
  border-top: 1px solid;
  border-right: 1px solid;
  border-bottom: 1px solid;
  background-color: #fff;
  user-select:none;
  .btn {
      
      
    display: flex;
    justify-content: center;
    align-items: center;
    height: 50%;
    box-sizing: border-box;
  }
  .btn:active {
      
       opacity: .5; }
  .btn + .btn {
      
      
    border-top: 1px solid;
  }
}

.input-border-color {
      
      
  border-color: #dcdfe6 !important;
}
</style>

使用:

<p>被检精子数:<span class="reportSpanSort">{
   
   { obj.number }} 个</span></p>
<div>
  被检精子数:
  <div class="flex items-center">
    <NumberInput v-model="obj.number" /></div>
</div>

<script>
import NumberInput from "@/components/numberInput.vue"
export default {
      
      
	...
	components: {
      
       NumberInput },
}
</script>

三、分析

想要封装的input组件实现v-model的方式,来绑定属性,就要先了解v-model大概的原理。

<input v-model="obj.number">
相当于
<input v-bind:value="obj.number" v-on:input="obj.number= $event.target.value">

<NumberInput v-model="obj.number"></NumberInput>
相当于
<NumberInput v-bind:value="obj.number" v-on:input="obj.number= argument[0]"></NumberInput>
这个时候,obj.number接收的值就是input监听事件的回调函数的第一个参数,所以在自定义组件中,要实现数据绑定,还需要$emit去触发input的事件。
this.$emit('input', value)

四、效果图

在这里插入图片描述
可以看到,我们二次封装的输入框组件就已经生效了。

猜你喜欢

转载自blog.csdn.net/weixin_45689946/article/details/124428043