ElementUI中关于计数器组件(InputNumber)在设置大小时具有一定局限性。因此利用两个button和一个input对上述计数器进行重构,并封装成组件,供今后使用。

先看效果(hover时):

在这里插入图片描述

上代码:

组件封装(Input_num.vue):

<!-- 自定义Input_num计数器组件 -->

<template>
    <div class="input_num">
        <button @click="minus">-</button>
        <input type="text" :value="counter_num" disabled />
        <button @click="add">+</button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            counter_num: this.value, // 计数
            min_num: this.min, // 最小值
            max_num: this.max // 最大值
        }
    },
    props: ['min', 'max', 'value'],
    methods: {
        minus() {
            if (this.counter_num <= this.min_num) {
                this.counter_num = this.min_num
            } else {
                this.counter_num--
            }
        },
        add() {
            if (this.counter_num >= this.max_num) {
                this.counter_num = this.max_num
            } else {
                this.counter_num++
            }
        }
    },
    watch: {
        counter_num(newVal) {
            // console.log(newVal)
            this.$emit('input', newVal)
        }
    }
}
</script>

<style scoped>
.input_num {
    /* width: 120px; counter组件的宽 */
    /* height: 24px; counter组件的高=上面的width*34行width对应的百分比 */
    position: absolute;
    border-radius: 2px;
}
.input_num:hover {
    box-shadow: 0 0 0 0.5px #409eff;
}
.input_num > button {
    width: 20%;
    height: 100%;
    float: left;
    box-sizing: border-box;
    border: 1px solid #dcdfe6;
    outline: none;
    cursor: pointer;
    background: #f5f7fa;
    border-radius: 2px;
}
.input_num > button:active {
    background: #ffffff;
}
.input_num > button:hover {
    color: #409eff;
}
.input_num > input {
    width: 60%;
    height: 100%;
    float: left;
    box-sizing: border-box;
    outline: none;
    border: 1px solid #dcdfe6;
    text-align: center;
    border-left: 0;
    border-right: 0;
    background: #fff;
}
</style>

组件使用:

<template>
    <div id="create6">
        <!-- 引入自定义计数器组件 -->
        <Input_num
            :min="min_val"
            :max="max_val"
            v-model="val"
        ></Input_num>
    </div>
</template>

<script>
import Input_num from '@/components/Input_num/Input_num'

export default {
    data() {
        return {
            min_val: 0, // 设定最小值
            max_val: Infinity, // 设定最大值,Infinity表示无穷大
            val: 0 // 计数器初始值
        }
    },
    components: {
        Input_num
    },
    methods: {
    	// 从子组件中接收input框中的数据,并更新父组件val值
        count_num(data) {
            this.val = data
        }
    }
}
</script>

<style scoped>
#create6 {
    width: 100%;
    height: 100%;
    background: #fff;
    padding: 100px; /*控制按钮的位置*/
}
</style>

使用时,min_val用于设定最小值、max_val用于设定最大值(Infinity表示无穷大)、val设定初始值。

注:给自定义组件添加v-model属性过程

在之前的博客中介绍过手动实现v-model的过程:

<template>
  <div class="hello">
  	<!-- <input type="text" v-model="aaa"> -->
    <input type="text" :value="aaa" @input="aaa=$event.target.value">
    {{ aaa }}
  </div>
</template>
<script>
export default {
  data() {
    return {
      aaa: ''
    }
  }
}
</script>

也就是说,任意元素包括组件,v-model就是:value@input的语法糖(标红的这两个是固定的,不能变),接着按照需求进行逐步完成组件引入v-mdel

  1. 在父元素中定义组件上绑定我们要传给子组件的值
<Input_num
    :value="val"
></Input_num>
const Input_num = () => import('@/components/Input_num/Input_num')

data() {
    return {
        val: 0 // 计数器初始值
    }
},
components: {
    Input_num
}
  1. 向子组件(Input_num.vue)传值
data() {
	return {
		counter_num: this.value // 计数
	}
},
props: ['value']

上述过程完成了父组件向子组件传值的过程

  1. 监听子组件中data属性值的变化,并向父组件发送input事件
watch: {
     counter_num(newVal) {
         // console.log(newVal)
         this.$emit('input', newVal)
     }
 }
  1. 父组件接收子组件input事件,并更新父组件val值
<Input_num
    :value="val"
    @input = "count_num"
></Input_num>
methods: {
    // 从子组件中接收input框中的数据,并更新父组件val值
    count_num(data) {
        this.val = data
    }
}
  1. 将上述子组件属性写成语法糖的形式
<Input_num1
    v-model="val"
></Input_num1>

完成!可以实现与data中val的双向绑定。

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐