Vue自定义InputNumber 计数器组件
ElementUI中关于计数器组件(InputNumber)在设置大小时具有一定局限性。因此利用两个button和一个input对上述计数器进行重构,并封装成组件,供今后使用。先看效果(hover时):上代码:组件封装(Input_num.vue):<!-- 自定义Input_num计数器组件 --><template><div class="input_num"&g
·
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
- 在父元素中定义组件上绑定我们要传给子组件的值
<Input_num
:value="val"
></Input_num>
const Input_num = () => import('@/components/Input_num/Input_num')
data() {
return {
val: 0 // 计数器初始值
}
},
components: {
Input_num
}
- 向子组件(Input_num.vue)传值
data() {
return {
counter_num: this.value // 计数
}
},
props: ['value']
上述过程完成了父组件向子组件传值的过程
- 监听子组件中data属性值的变化,并向父组件发送input事件
watch: {
counter_num(newVal) {
// console.log(newVal)
this.$emit('input', newVal)
}
}
- 父组件接收子组件input事件,并更新父组件val值
<Input_num
:value="val"
@input = "count_num"
></Input_num>
methods: {
// 从子组件中接收input框中的数据,并更新父组件val值
count_num(data) {
this.val = data
}
}
- 将上述子组件属性写成语法糖的形式
<Input_num1
v-model="val"
></Input_num1>
完成!可以实现与data中val的双向绑定。
更多推荐
已为社区贡献9条内容
所有评论(0)