目的:封装一个通用的数量选中组件。
大致功能分析:
- 默认值为1
- 可限制最大最小值
- 点击-就是减1 点击+就是加1
- 需要完成v-model得实现
- 存在无label情况
代码实现:
<template>
<div class="xtx-numbox">
<div class="label" v-if="label">{{ label }}</div>
<div class="numbox">
<a @click="changeNum(-1)" href="javascript:">-</a>
<input type="text" readonly :value="modelValue">
<a @click="changeNum(1)" href="javascript:">+</a>
</div>
</div>
</template>
<script setup>
import { useVModel } from '@vueuse/core'
const props = defineProps({
label: {
type: String,
default: ''
},
modelValue: {
type: Number,
default: 1
},
// 最小值最大值
min: {
type: Number,
default: 1
},
max: {
type: Number,
default: 10
}
})
const emit = defineEmits(['update:modelValue', 'change'])
// 1.绑定按钮点击事件 -按钮 +按钮 触发同一个事件 同一个函数
// 2.使用vueuse的useVModel做数据绑定 修改count 通知父组件更新
const count = useVModel(props, 'modelValue', emit)
const changeNum = (step) => {
const newValue = count.value + step
// 3.得到将要改变的值 如果值不合法终止程序
if (newValue < props.min || newValue > props.max) return
// 4.修改正常值
count.value = newValue
// 5.提供change事件
emit('change', newValue)
}
</script>
<style scoped lang="less">
.xtx-numbox {
display: flex;
align-items: center;
.label {
width: 60px;
color: #999;
padding-left: 10px;
}
.numbox {
width: 120px;
height: 30px;
border: 1px solid #e4e4e4;
display: flex;
> a {
width: 29px;
line-height: 28px;
text-align: center;
background: #f8f8f8;
font-size: 16px;
color: #666;
&:first-of-type {
border-right: 1px solid #e4e4e4;
}
&:last-of-type {
border-left: 1px solid #e4e4e4;
}
}
> input {
width: 60px;
padding: 0 5px;
text-align: center;
color: #666;
}
}
}
</style>
使用:
<xtx-numbox label="数量" v-model="num" :max="goods.inventory"/>