Vue3 — Encapsulates the counter component itself

background

When you open the product details in some shopping mall web pages, there will be a counter to select the purchase quantity. Such a timer will not only be displayed on the product details page, but also be found in the shopping cart. Then you can package the timer into components for better use and later maintenance

Be born code

<template>
  <div class="xtx-numbox">
    <div class="label"><slot /></div>
    <div class="numbox">
      <a href="javascript:;" @click="handleSub(-1)">-</a>
      <input type="text" readonly :value="num" />
      <a href="javascript:;" @click="handleSub(1)">+</a>
    </div>
  </div>
</template>
<script>
// The third-party method useVModel is used to implement bidirectional binding
import { useVModel } from '@vueuse/core'
export default {
  name: 'XtxNumbox'.props: {
    modelValue: {
      type: Number.default: 1}},setup(props, { emit }) {
    // The useVModel method takes three arguments,
    // Parameter 1: The custom property props receives the data passed by the parent component via the V-Model bidirectional binding
    // Parameter 2: props To pass data
    // Parameter 3: Emit bound data needs to be notified to the parent component via emit events
    const num = useVModel(props, 'modelValue', emit)
    const handleSub = n= > {
      if (n < 0) {
        num.value -= 1
        if (props.modelValue === 1) {
          num.value = 1}}else {
        num.value += 1}}return { handleSub, num }
  }
}
</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>
Copy the code

use

<XtxNumbox v-model="num">The number of</XtxNumbox>
Copy the code

The effect