uni-app/vue封装车牌选择器

先看下效果如下:
在这里插入图片描述
代码如下:
父组件:

<car-license carvalue="" @input="(e) => {platNo = e}"></car-license>

子组件:(代码较长,css部分没有提供)

<template>
  <view class="license-input">
    <view class="t">请填写车牌号码 <text class="fr" @click="clearCode">清空</text></view>
    <view class="text-enter" style="position: relative">
      <view class="input-code code0" :class="setClass(0)" @click.stop="chooseFn(0)">
        {{ carvaluelist[0] }}
        <text class="colgpla" v-if="!carvaluelist[0]"></text>
      </view>
      <view class="input-code code1" :class="setClass(1)" @click.stop="chooseFn(1)">{{ carvaluelist[1] }}</view>
      <span class="dian"></span>
      <view class="input-code code2" :class="setClass(2)" @click.stop="chooseFn(2)">{{ carvaluelist[2] }}</view>
      <view class="input-code code3" :class="setClass(3)" @click.stop="chooseFn(3)">{{ carvaluelist[3] }}</view>
      <view class="input-code code4" :class="setClass(4)" @click.stop="chooseFn(4)">{{ carvaluelist[4] }}</view>
      <view class="input-code code5" :class="setClass(5)" @click.stop="chooseFn(5)">{{ carvaluelist[5] }}</view>
      <view class="input-code code6" :class="setClass(6)" @click.stop="chooseFn(6)">{{ carvaluelist[6] }}</view>
      <view class="input-code code7" :class="setClass(7)" @click.stop="chooseFn(7)">
        {{ carvaluelist[7] }}
        <view class="code7-pla" v-if="carvaluelist[7]===''"><text class="plus">+</text><text class="plus-txt">新能源</text></view>
      </view>
    </view>
    <view class="pai">
      <view class="lan" :class="carvaluelist[7]==='' ? 'active' : ''">
        <image src="@/static/images/etc/Union.png"></image>
        蓝牌
        <fan-icon class="check" name="CircleCheckFilled" color="#FC6C2D" size="28rpx" />
      </view>
      <view class="lv" :class="carvaluelist[7]!=='' ? 'active' : ''">
        <image src="@/static/images/etc/Union.png"></image>
        绿牌
        <fan-icon class="check" name="CircleCheckFilled" color="#FC6C2D" size="28rpx" />
      </view>
    </view>

    <!-- 选择省 -->
    <u-popup v-model="show" mode="bottom" close-icon-pos="top-right" :border-radius="20" :mask="false" :mask-close-able="false" class="prov-popup">
      <template v-if="popShow[chooseIndex]">
        <!-- <view class="prov-title">请选择省份</view> -->
        <view class="prov-pview">
          <view class="enter-tit">
            <view
              class="enter-btn"
              @click="
                show = false;
                chooseIndex = -1;
              "
              >完成</view
            >
          </view>
          <template v-if="chooseIndex == 0">
            <view class="prov-item" :class="carvaluelist[chooseIndex] == f ? 'active' : ''" v-for="(f, fi) of strList[0]" :key="fi" @click="chooseCode(f)">
              {{ f }}
            </view>
          </template>
          <template v-else>
            <view :class="chooseIndex == 1 ? 'disabled' : ''" style="text-align: center">
              <view
                class="prov-item s1"
                :class="carvaluelist[chooseIndex] == f ? 'active' : ''"
                v-for="(f, fi) of 10"
                :key="fi"
                @click="
                  () => {
                    if (chooseIndex > 1) {
                      chooseCode(fi);
                    }
                  }
                "
              >
                {{ fi }}
              </view>
            </view>
            <view style="padding: 0 30rpx">
              <view class="prov-item s2" :class="carvaluelist[chooseIndex] == f ? 'active' : ''" v-for="(f, fi) of strList[1]" :key="fi" @click="chooseCode(f)">
                {{ f }}
              </view>
            </view>
          </template>
          <view class="del-btn" @click="delCode">删除</view>
        </view>
      </template>
    </u-popup>
  </view>
</template>

<script>
/**
 *  车牌照输入
 *
 * ===== 使用场景 ======
 * 下单页面ETC
 *
 */
import { scrollToDistance } from "@/utils/utils";
export default {
  name: "license-input",
  props: {
    carvalue: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      show: false,
      popShow: {
        "-1": false,
        0: false,
        1: false,
        2: false,
        3: false,
        4: false,
        5: false,
        6: false,
        7: false,
        8: false,
      },
      chooseIndex: -1,
      carvaluelist: this.carvalue && this.carvalue.length > 6 ? this.carvalue.split("") : ["", "", "", "", "", "", "", ""],
      strList: [
        ["京", "津", "渝", "沪", "冀", "晋", "辽", "吉", "黑", "苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "琼", "川", "贵", "云", "陕", "甘", "青", "蒙", "桂", "宁", "新", "藏"],
        ["Q", "W", "E", "R", "T", "Y", "U", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X", "C", "V", "B", "N", "M"],
      ],
    };
  },
  mounted() {
    this.$nextTick(() => {
      document.querySelector("body").removeEventListener("click", this.addEvent);
      document.querySelector("body").addEventListener("click", this.addEvent);

      document.querySelectorAll("input").forEach((el) => {
        el.removeEventListener("focus", this.addEvent);
        el.addEventListener("focus", this.addEvent);
      });
      document.querySelectorAll("textarea").forEach((el) => {
        el.removeEventListener("focus", this.addEvent);
        el.addEventListener("focus", this.addEvent);
      });
      this.setClass(-1);
    });
  },
  methods: {
    addEvent() {
      this.show = false;
      this.chooseIndex = -1;
    },
    setClass(num) {
      return `${this.chooseIndex == num ? "focus" : ""} ${this.carvaluelist.join("").length == 8 ? "fill-lv" : this.carvaluelist[num] !== "" ? "fill" : ""}`;
      // return this.chooseIndex == num && this.carvaluelist[num] ? "focus fill" : this.chooseIndex == num ? "focus" : this.carvaluelist[num] ? "fill" : "";
    },
    chooseCode(item) {
      this.$set(this.carvaluelist, this.chooseIndex, item);
      this.$set(this.popShow, this.chooseIndex, false);
      this.chooseIndex = this.chooseIndex + 1;
      if (this.chooseIndex >= this.carvaluelist.length - 1) {
        this.chooseIndex = this.carvaluelist.length - 1;
      }
      this.$set(this.popShow, this.chooseIndex, true);
      console.log(this.carvaluelist.join(""));
      this.$emit("input", this.carvaluelist.join(""));
    },
    delCode() {
      this.$set(this.carvaluelist, this.chooseIndex, "");
      this.$set(this.popShow, this.chooseIndex, false);
      this.chooseIndex = this.chooseIndex - 1;
      if (this.chooseIndex <= 0) {
        this.chooseIndex = 0;
      }
      this.$set(this.popShow, this.chooseIndex, true);
    },
    chooseFn(num) {
      this.show = true;
      this.chooseIndex = num;
      for (let key in this.popShow) {
        this.$set(this.popShow, key, false);
      }
      this.$set(this.popShow, this.chooseIndex, true);
      // 将选择车牌模块滚动到顶部,防止被键盘遮住
      const c = document.querySelector(`.license-input`).offsetTop - 50;
      scrollToDistance(0, c);
    },
    clearCode() {
      this.carvaluelist = ["", "", "", "", "", "", "", ""];
      this.$emit("input", this.carvaluelist.join(""));
    },
  },
};
</script>

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值