微信小程序组件

2021/12/6 1:17:33

本文主要是介绍微信小程序组件,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

车牌号输入组件

密码支付键盘


车牌号输入组件

如图

基于微信小程序组件封装,输出值为当前选择车牌号,可回显车牌号。

支持7位8位车牌号,因为我的项目没有此需求,所以没有测试,具体功能待验证。

话不多说,上代码。

json文件

{
  "component": true,
  "usingComponents": {
    "van-overlay": "@vant/weapp/overlay/index",
    "van-divider": "@vant/weapp/divider/index"
  }
}

wxs文件

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 组件显示
    keyboardShow: {
      type: Boolean,
      value: false
    },
    // 初始传入车牌号
    vehicleNo: {
      type: String,
      value: ''
    },
    // 车牌号位数
    plateLimit: {
      type: Number,
      value: 7
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    keyboardShow: false, // 整体键盘显示
    numberIsDis: 1, // 输入键盘不可点击 2可点击
    fieldBoardShow: true, // 省键盘
    provincesKeyList: '京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新',
    numberKeyList: '0123456789',
    englishKeyOneList: 'ABCDEFGHJKLMNPQRSTUV',
    englishKeyTwoList: 'WXYZ',
    currentFocus: 0,
    currIndex: 0,
    codeList: [],
    codeReset: []
  },

  /**
   * 组件的生命周期
   * ready方法要正确执行需要在父页面中写入当前组件时,wx:if 绑定组件显示属性
   * 组件隐藏之后要注销,否则ready方法只执行一次
   */
  ready: function() {
    let temp = []
    let reset = []
    let carLen = this.properties.vehicleNo ? this.properties.vehicleNo.length + 1 : 0
    if (carLen) {
      let arr = this.properties.vehicleNo.split('')
      arr.forEach(item => {
        temp.push({ value: item })
        reset.push({ value: '' })
      })
      // 解决车牌号异常数据导致的样式问题(车牌号位数不够)
      if (carLen < this.data.plateLimit) {
        let num = this.data.plateLimit - carLen
        for (let index = 0; index <= num; index++) {
          temp.push({ value: '' })
          reset.push({ value: '' })
        }
      }
    } else {
      // 初始化设置数据
      for (let index = 0; index < this.data.plateLimit; index++) {
        temp.push({ value: '' })
        reset.push({ value: '' })
      }
    }
    this.setData({
      codeList: temp,
      codeReset: reset,
      numberIsDis: carLen ? 2 : 1,
      fieldBoardShow: carLen ? false : true,
      currentFocus: carLen,
      currIndex: this.properties.vehicleNo ? this.properties.vehicleNo.length : 0
    })
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 省份键盘
    provinceKeyClick(e) {
      const { val } = e.currentTarget.dataset
      const { currentFocus, codeList } = this.data
      let temp = codeList
      temp[0].value = val
      this.setData({
        codeList: temp,
        fieldBoardShow: false,
        currIndex: 1,
        numberIsDis: 1,
        currentFocus: currentFocus + 1
      })
    },

    //数字键盘不可点击事件
    numberKeyDisabled(e) {
      // 获取组件
      // this.keyboard = this.selectComponent("#keyboard");
      return
    },

    // 数字键盘可点击
    numberKeyEnabled(e) {
      const { currIndex, codeList } = this.data
      if (currIndex > codeList.length - 1) return
      const { val } = e.currentTarget.dataset
      let temp = this.data.codeList
      temp[currIndex].value = val
      this.setData({
        codeList: temp,
        currIndex: currIndex + 1,
        currentFocus: currIndex + 1
      })
    },

    // 字母键盘点击
    englishKeyClick(e) {
      const { currIndex, codeList } = this.data
      if (currIndex > codeList.length - 1) return
      const { val } = e.currentTarget.dataset
      let temp = this.data.codeList
      temp[currIndex].value = val
      this.setData({
        codeList: temp,
        currentFocus: currIndex + 1,
        currIndex: currIndex + 1,
        numberIsDis: 2
      })
    },

    // 退格
    backspace: function(e) {
      const { currIndex } = this.data
      let temp = this.data.codeList
      if (!currIndex) return
      temp[currIndex - 1].value = ''
      this.setData({
        codeList: temp,
        currentFocus: currIndex - 1,
        currIndex: currIndex - 1,
        fieldBoardShow: currIndex === 1,
        numberIsDis: currIndex === 2 ? 1 : 2
      })
    },

    // 关闭
    closeKeyBoard: function(e) {
      const { codeReset } = this.data
      this.setData({
        keyboardShow: false,
        codeList: codeReset,
        currentFocus: 0,
        currIndex: 0,
        fieldBoardShow: true,
        numberIsDis: 1
      })
      this.triggerEvent('closeKeyBoard')
    },

    // 确定
    confirmKeyBoard: function(e) {
      const { currIndex, codeList } = this.data
      if (currIndex < codeList.length) return
      let plate = ''
      codeList.map(item => (plate += item.value))
      this.triggerEvent('keyboardConfirm', plate)
      this.closeKeyBoard()
    }
  }
})

wxml文件

<!--车牌号输入组件-->
<van-overlay show="{{ keyboardShow }}" z-index="9990">
  <view class="keyBoard_content">
    <!-- header -->
    <view class="top-part flex">
      <view class="font-30 close" bindtap="closeKeyBoard">x</view>
      <view class="message color-333">输入车牌号</view>
      <view class="font-30 confirm {{currIndex === codeList.length ? 'confirm-active' : ''}}" bindtap="confirmKeyBoard">确定</view>
    </view>

    <!-- input -->
    <view class="license flex">
      <view wx:for="{{codeList}}" wx:key="index" class="edit-text {{currentFocus === index ? 'border-active' : ''}} {{index === 2 ? 'space-left' : ''}}">
        <view>{{item.value}}</view>
      </view>
    </view>
    
    <!-- 键盘 -->
    <view class="keyboard">
      <!-- 省份键盘 -->
      <block wx:if="{{fieldBoardShow}}">
        <view class="province-keyboard flex">
          <view
            class="td td-nor color-333"
            wx:for="{{provincesKeyList}}"
            wx:key="index"
            wx:for-index="idx"
            wx:for-item="itemName"
            catch:tap="provinceKeyClick"
            data-index="{{idx}}"
            data-val="{{itemName}}"
            hover-class="board-active"
            hover-start-time="0"
            hover-stay-time="80"
          >
            {{itemName}}
          </view>
        </view>
      </block>
      <!--数字键盘-->
      <block wx:if="{{!fieldBoardShow}}">
        <view class="number-keyboard flex between">
          <!-- 不可点击 -->
          <block wx:if="{{numberIsDis === 1}}">
            <view
              class="td td-num color-333 board-active"
              wx:for="{{numberKeyList}}"
              wx:key="idx"
              wx:for-index="idx"
              wx:for-item="itemName"
              catch:tap="numberKeyDisabled"
              data-val="{{itemName}}"
            >
              {{itemName}}
            </view>
          </block>
          <!-- 可点击 -->
          <block wx:if="{{numberIsDis === 2}}">
            <view
              class="td td-num color-333"
              wx:for="{{numberKeyList}}"
              wx:key="idx"
              wx:for-index="idx"
              wx:for-item="itemName"
              catch:tap="numberKeyEnabled"
              data-index="{{idx}}"
              data-val="{{itemName}}"
              hover-class="board-active"
              hover-start-time="0"
              hover-stay-time="80"
            >
              {{itemName}}
            </view>
          </block>
        </view>
      </block>
      <!--字母键盘-->
      <block wx:if="{{!fieldBoardShow}}">
        <view class="english-keyboard flex between">
          <view
            class="td td-num color-333"
            wx:for="{{englishKeyOneList}}"
            wx:key="idx"
            wx:for-index="idx"
            wx:for-item="itemName"
            data-index="{{idx}}"
            data-val="{{itemName}}"
            hover-class="board-active"
            hover-start-time="0"
            hover-stay-time="80"
            catch:tap="englishKeyClick"
          >
            {{itemName}}
          </view>
        </view>
        <view class="english-keyboard flex englishtTwo">
          <view
            class="td td-num color-333"
            wx:for="{{englishKeyTwoList}}"
            wx:key="idx"
            wx:for-index="idx"
            wx:for-item="itemName"
            data-index="{{idx}}"
            data-val="{{itemName}}"
            hover-class="board-active"
            hover-start-time="0"
            hover-stay-time="80"
            catch:tap="englishKeyClick"
          >
            {{itemName}}
          </view>
        </view>
      </block>
      <!--清除按钮-->
      <view
        catch:tap="backspace"
        class="delete flex"
        hover-class="board-active"
        hover-start-time="0"
        hover-stay-time="80"
      >
        <image class="deleteImg" src="/images/clear.png" />
      </view>
    </view>

  </view>
</van-overlay>


wxss文件

@import "../../styles/style.wxss";

.keyBoard_content {
  z-index: 9999;
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: auto;
  background: #fff;
}

.top-part {
  width: 100%;
  padding: 25rpx 40rpx;
  height: 92rpx;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
  border-bottom: 1rpx solid #EAEAEA;
  margin-bottom: 15rpx;
  text-align: center;
}

.close {
  width: 10%;
  font-size: 47rpx;
  color: #A0A0A0;
}

.message {
  width: 80%;
  text-align: center;
  font-weight: Semibold;
}

.confirm {
  width: 10%;
  color: #A0A0A0;
  font-weight: Regular;
}

.confirm-active {
  color: #27B57D;
}

.license {
  box-sizing: border-box;
  justify-content: space-around;
  margin: 60rpx 90rpx 50rpx;
}

.edit-text {
  height: 80rpx;
  line-height: 80rpx;
  width: 60rpx;
  border: 1rpx solid #A0A0A0;
  border-radius: 8rpx;
  text-align: center;
  font-size: 36rpx;
}

.space-left {
  margin-left: 30rpx;
}

.border-active {
  border: 1rpx solid #5BCA92;
}

.keyboard {
  width: 100%;
  height: 450rpx;
  box-sizing: border-box;
  position: relative;
}

.province-keyboard {
  margin: 0 50rpx;
  flex-wrap: wrap;
}

.number-keyboard {
  margin: 0 5rpx;
}

.english-keyboard {
  margin: 0 5rpx;
  flex-wrap: wrap;
}

.englishtTwo {
  margin-left: 10%;
}

.td {
  font-family: "PingFangSC";
  font-size: 36rpx;
  font-weight: Medium;
  margin: 12rpx 4rpx;
  border: 1rpx solid #E0E0E0;
  border-radius: 8rpx;
  height: 84rpx;
  line-height: 84rpx;
  text-align: center;
}

.td-nor {
  flex: 0 1 9%;
}

.td-num {
  flex: 0 1 8%;
}

.board-active {
  box-shadow: 0 0 0 #e5e5e5;
  background: #e5e5e5;
}

.delete {
  width: 140rpx;
  height: 84rpx;
  text-align: center;
  background-color: #D8D8D8;
  border-radius: 8rpx;
  position: absolute;
  right: 80rpx;
  bottom: 30rpx;
  justify-content: center;
  align-items: center;
}

.deleteImg {
  width: 44rpx;
  height: 30rpx;
}

style.wxss 文件

.van-dialog__header {
  padding-bottom: 20rpx;
}

.flex {
  display: flex;
}

.between {
  justify-content: space-between;
}

.font-30 {
  font-size: 30rpx;
}

.color-333 {
  color: #333333;
}

密码支付键盘

交互样式如上图

上代码:

json文件

{
  "component": true,
  "usingComponents": {
    "van-popup": "@vant/weapp/popup/index",
    "van-tab": "/miniprogram_npm/@vant/weapp/tab/index"
  }
}

 wxs文件

import { throttle } from '../../utils/throttle'
const passwordInputData = ['', '', '', '', '', '']
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 显示隐藏弹窗
    passWordShow: {
      type: Boolean,
      observer(value) {
        if (!value) {
          this.setData({
            passwordInput: JSON.parse(JSON.stringify(passwordInputData)),
            passwordIndex: -1
          })
        }
      }
    },
    // 支付金额
    payAmount: {
      type: Number
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    passwordInput: JSON.parse(JSON.stringify(passwordInputData)),
    passwordIndex: -1,
    keyboardNumber: '123456789*0*',
    password: ''
  },
  /**
   * 启用插槽
   */
  options: {},
  lifetimes: {
    attached: function() {}
  },
  externalClasses: ['custom-class'],

  /**
   * 组件的方法列表
   */
  methods: {
    // 忘记密码
    forgetPassWord() {
      this.onClose()
      wx.navigateTo({
        url: `/pages/manage-password/refund-password/index?source=Back`
      })
    },

    //tab切换
    onTabChange(e) {
      this.triggerEvent('onTabChange', {
        currStatus: e.currentTarget.dataset.value
      })
    },

    onClose() {
      this.setData({
        passwordInput: JSON.parse(JSON.stringify(passwordInputData)),
        passWordShow: false
      })
      this.triggerEvent('closeFun')
    },

    // throttle防抖
    tapKeyboard: throttle(function(e) {
      const { val } = e.currentTarget.dataset
      const passwordIndex = this.data.passwordIndex + 1
      if (passwordIndex > 5) {
        return
      }
      this.data.passwordInput[passwordIndex] = val
      this.setData({
        passwordIndex,
        passwordInput: this.data.passwordInput
      })
      if (passwordIndex === 5) {
        const password = this.data.passwordInput.join('')
        this.triggerEvent('submitFun', {
          password: password
        })
        this.onClose()
      }
    }),

    tapKeyboardDelete() {
      const passwordIndex = this.data.passwordIndex - 1
      if (passwordIndex < -1) {
        return
      }
      this.data.passwordInput[this.data.passwordIndex] = ''
      this.setData({
        passwordIndex,
        passwordInput: this.data.passwordInput
      })
    }
  }
})
// throttle
export function throttle(fn, delay) {
  let timer = null
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(() => fn.apply(this, [...args]), delay)
  }
}

wxml文件

<van-popup
  show="{{ passWordShow }}"
  closeable
  close-icon-position="top-left"
  position="bottom"
  close-icon="cross"
  custom-style="height: 20%"
  bind:close="onClose"
  z-index="99"
  custom-style="height: 914rpx"
>
  <view class="content">
    <view class="title color-333">请输入退款密码</view>

    <view class="password-box">
      <view class="password-main">
        <view
          class="password-item"
          wx:for="{{passwordInput}}"
          wx:for-index="boxIndex"
          wx:key='boxIndex'
        >
          <view class="star">{{item ? "*" : ''}}</view>
        </view>
      </view>
      <view class="forget" catch:tap="forgetPassWord">忘记密码</view>
    </view>

    <view class="keyboard flex between">
      <!-- 数字键盘可点击 -->
      <view
        class="td flex color-333"
        wx:for="{{keyboardNumber}}"
        wx:key="index"
        wx:for-index="idx"
        wx:for-item="itemName"
        data-index="{{idx}}"
        data-val="{{itemName}}"
        hover-class="board_bg"
        hover-start-time="0"
        hover-stay-time="80"
      >
        <view
          class="del_icon flex"
          wx:if="{{idx === 11}}"
          catch:tap="tapKeyboardDelete"
          data-index="{{idx}}"
          data-val="{{itemName}}"
        >
          <image class="deleteImg" src="/images/clear.png" />
        </view>
        <view
          class="keyboard-num flex"
          wx:if="{{idx !== 9 && idx !== 11}}"
          catch:tap="tapKeyboard"
          data-index="{{idx}}"
          data-val="{{itemName}}"
        >
          {{itemName}}
        </view>
      </view>
    </view>

  </view>
</van-popup>

wxss文件

style.wxss文件上面有

@import "../../styles/style.wxss";

.title{
  font-size: 34rpx;
  font-family: PingFangSC, PingFangSC-Medium;
  font-weight: Medium;
  text-align: center;
  min-height: 136rpx;
  line-height: 136rpx;
  border-bottom: 1px solid #eaeaea;
}

.van-popup__close-icon--top-left {
  top: 50rpx!important;
}
.password-box{
  padding-top: 40rpx;
}
.forget{
  font-size: 28rpx;
  text-align: right;
  color: #0091ff;
  padding: 12rpx 28rpx 20rpx;
}
.password-main{
  width: 684rpx;
  height: 104rpx;
  border: 1px solid #a1a1a1;
  border-radius: 3px;
  display: flex;
  margin: 0 auto;
}
.password-item{
  width: 114rpx;
  border-right: 1px solid #a1a1a1;
  display: flex;
  justify-content: center;
  align-items: center;
}
.password-item:last-child{
  border: none;
}
.star{
  font-size: 60rpx;
  line-height: 108rpx;
  padding-top: 20rpx;
}


.keyboard{
  width: 100%;
  height: 490rpx;
  padding: 40rpx 16rpx 0;
  box-sizing: border-box;
  background: #EEEEEE;
  flex-wrap: wrap;
}

.td {
  flex: 0 1 32%;
  border-radius: 8rpx;
  background-color: #fff;
  font-size: 50rpx;
  font-weight: Regular;
  align-items: center;
  justify-content: center;
  margin-bottom: 16rpx;
  height: 96rpx;
}

.board_bg {
  box-shadow: 0 0 0 #e5e5e5;
  background: #e5e5e5;
}

.del_icon {
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
}

.del_icon .deleteImg {
  width: 54rpx;
  height: 34rpx;
}

.keyboard-num {
  width: 100%;
  height: 100%;
  justify-content: center;
  align-items: center;
}


这篇关于微信小程序组件的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程