html
<template>
<div class="mall-input-number">
<span class="reduce" @click="() => handleChange(null,-1)">-</span>
<input
type="text"
class="text"
:value="value"
min="1"
@input="(e) => handleChange(e.target, 0)"
/>
<span class="increase" @click="() => handleChange(null, 1)">+</span>
</div>
</template>
js
<script lang="ts">
import {
defineComponent } from 'vue';
export default defineComponent({
name: 'MallInputNumber',
props: {
value: {
type: Number,
required: true,
},
},
setup(props, ctx) {
// 更改购物车商品数量
const handleChange = (e: HTMLInputElement | null, value: number) => {
let newValue = props.value;
if (e !== null) {
if (/^(?:[1-9][0-9]*)$/.test(e.value)) {
newValue = +e.value;
} else {
e.value = `${
newValue}`;
}
} else {
newValue += value;
if (newValue < 1) {
return; }
}
ctx.emit('update:value', newValue);
ctx.emit('change', newValue);
};
return {
handleChange,
};
},
});
</script>
css
<style lang="scss">
.mall-input-number {
display: flex;
span {
cursor: pointer;
}
.reduce,
.increase {
display: block;
width: 29px;
height: 29px;
text-align: center;
line-height: 29px;
user-select: none;
}
.reduce {
background: hsla(0, 0%, 96%, 1);
color: hsla(0, 0%, 33%, 1);
}
.text {
width: 37px;
border: 1px solid #f5f5f5;
font-size: 14px;
font-weight: 500;
color: #545454;
text-align: center;
line-height: 17px;
}
.increase {
background: hsla(349, 100%, 45%, 1);
color: hsla(0, 0%, 100%, 1);
}
}
</style>
在外面调用 MallInputNumber
<MallInputNumber
v-model:checked="isLoading"
v-model:value="item.quantity"
@change="(newValue) => quantityOnChange(item, newValue)"
/>