微信小程序vantw下components組件案例

前言

項(xiàng)目中有個(gè)業(yè)務(wù)場(chǎng)景,有些業(yè)務(wù)用戶想要參與必須要獲取用戶手機(jī)號(hào),所以很多頁(yè)面都寫了獲取手機(jī)號(hào)的判斷和相關(guān)引導(dǎo)邏輯?代碼和樣式重復(fù)了很多次,針對(duì)這種場(chǎng)景,我們可以把獲取用戶手機(jī)號(hào)的效果頁(yè)面做成組件,減少代碼和維護(hù)量。

準(zhǔn)備工作

分析抽離的頁(yè)面代碼和js代碼和樣式和第三方組件,思考我們要哪些變量是從主頁(yè)傳到組件的,組件要拋出什么自定義事件給主頁(yè)面接收。

場(chǎng)景分析

小程序UI框架使用的是vant-weapp框架,獲取手機(jī)號(hào)的效果是,點(diǎn)擊某些按鈕或者進(jìn)入頁(yè)面onLoad時(shí)判斷用戶緩存中是否存在用戶是否存在手機(jī)號(hào),沒(méi)有就彈出一個(gè)彈窗,彈窗內(nèi)容提示用戶為什么要獲取手機(jī)號(hào),有取消和確定按鈕,取消則關(guān)閉彈窗,確定則觸發(fā)微信獲取手機(jī)號(hào)的函數(shù)bindgetphonenumber,然后請(qǐng)求后端接口解密、更新用戶數(shù)據(jù),然后返回最新的用戶信息。

開始

項(xiàng)目根目錄下創(chuàng)建空文件夾components,這個(gè)目錄是專門放組件的,然后在這個(gè)文件夾下創(chuàng)建自定義組件文件夾,準(zhǔn)備放組件用到的js、json、wxml、wxss等文件,比如我在components創(chuàng)建空文件夾getPhone文件夾,然后選擇getPhone文件夾右鍵-新建component,名稱是getPhone,這樣開發(fā)工具就可以幫忙生成初始文件了

image.png

抽離代碼部分我就不解釋那么多,直接上最后效果,自定義組件相關(guān)的大家可以先去看看官方文檔,理解一些關(guān)鍵字

組件部分

getPhone.js
// components/getPhone.js
var http = require("../../utils/http.js");
/* 獲取手機(jī)號(hào)的彈窗頁(yè)面,引導(dǎo)用戶點(diǎn)擊按鈕
 ----------------------------------------------- */
Component({
  /**
   * 組件的屬性列表
   */
  properties: {
    // code,在父組件通過(guò)wx.login獲取,不在組件中寫,避免重復(fù)請(qǐng)求
    code: {
      type: String,
      value: ''
    },
    // 是否允許關(guān)閉彈窗,在有些頁(yè)面,是直接保持彈出手機(jī)號(hào)獲取框的,不允許用戶操作,強(qiáng)制獲取手機(jī)號(hào)
    isCloseEvent:{
      type: Boolean,
      value: true
    }
  },

  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {
    // 隱藏彈窗
    empower: false
  },

  /**
   * 組件的方法列表
   */
  methods: {
    // 組件初始化事件,比如父組件喚起子組件
    eventInit() {
      let that = this
      that.setData({
        empower: true
      })
      console.log(that.data)
    },
    //綁定手機(jī)號(hào)
    getPhoneNumber: function (e) {
      let that = this
      e.wx_phone_code = that.properties.code
      http.featPhone(e, function (userInfo) {
        that.setData({
          empower: false
        })
        // 成功則拋出自定義事件,參數(shù)是最新的用戶信息
        that.triggerEvent('success', userInfo);
      })
    },
    //拒絕綁定手機(jī)
    popBtnN: function (e) {
      // console.log(e)
      if(this.properties.isCloseEvent){
        this.setData({
          empower: false
        })
        // 關(guān)閉彈窗是否觸發(fā)事件
      }
    },
  }
})
getPhone.json
{
  "component": true,
  "usingComponents": {
    "van-popup": "@vant/weapp/popup/index"
  }
}
getPhone.wxml
<!--components/getPhone.wxml-->
<van-popup show="{{ empower }}" position="bottom" custom-class="bott_popup" bind:close="onClose">
  <view class="flex-column content-around h-fill p-3">
    <view class="flex-row align-center">
      <image class="popup_logo" src="../../lib/img/my.png"></image>
      <view class="font-medium ml-2">PayFun貝樂(lè)</view>
      <text class="ml-2">申請(qǐng)</text>
    </view>
    <view class="flex-column">
      <text class="font-medium">請(qǐng)求獲取手機(jī)號(hào)</text>
      <text class="font-extra-small mt-2">如拒絕,將會(huì)影響預(yù)訂和購(gòu)買套餐功能的使用</text>
    </view>
    <view class="flex-row content-around">
      <van-button type="default" custom-class="popup_btn1" bindtap="popBtnN">拒絕</van-button>
      <button open-type="getPhoneNumber" class="phone_btn van-button van-button--primary"
        bindgetphonenumber="getPhoneNumber">允許</button>
    </view>
  </view>
</van-popup>
getPhone.wxss
/* components/getPhone.wxss */
/* 手機(jī)窗 */
.bott_popup{
  height: 220px;
  background: #EDEDED;
}
.flex-column {
  display: flex;
  flex-direction: column;
}
.content-around {
  justify-content: space-around;
}
.h-fill {
  height: -webkit-fill-available;
}
.p-3 {
  padding: 30rpx;
}
.flex-row {
  display: flex;
  flex-direction: row;
}
.align-center {
  align-items: center;
}
.popup_logo {
  width: 60rpx;
  height: 60rpx;
  border-radius: 50%;
}
/*小標(biāo)題*/
.font-medium {
  font-size: 32rpx;
  font-weight: bold;
}
.ml-2 {
  margin-left: 20rpx;
}
/*輔助文字*/
.font-extra-small {
  font-size: 26rpx;
  color: #909399;
}
.mt-2 {
  margin-top: 20rpx;
}
.popup_btn1 {
  width: 250rpx;
}
.phone_btn {
  width: 250rpx;
  margin: 0;
  position: relative;
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 0;
  text-align: center;
  vertical-align: middle;
  -webkit-appearance: none;
  -webkit-text-size-adjust: 100%;
  height: 44px;
  height: var(--button-default-height,44px);
  line-height: 20px;
  line-height: var(--button-line-height,20px);
  font-size: 14px;
  font-size: var(--button-default-font-size,14px);
  transition: opacity .2s;
  transition: opacity var(--animation-duration-fast,.2s);
  border-radius: 2px;
  border-radius: var(--button-border-radius,2px);
  color: #fff;
  color: var(--button-primary-color,#fff);
  background: #07c160;
  background: var(--button-primary-background-color,#07c160);
}
index.js

主頁(yè)面代碼部分,樣式也剝離了,所以主頁(yè)面代碼就沒(méi)有組件的樣式代碼了。
這里說(shuō)明下,在去觸發(fā)按鈕bindgetphonenumber函數(shù)前,必須獲取最新的code,這個(gè)code要拿去后端解密用的,如果你先執(zhí)行了bindgetphonenumber函數(shù),在獲取code,會(huì)導(dǎo)致code不一樣,執(zhí)行bindgetphonenumber函數(shù)時(shí)加密的code和你后面拿的code明顯不一樣,這里順序要對(duì)

// 習(xí)慣給默認(rèn)值
data: {
// wx.login拿到的code
wx_phone_code: ''
}


      wx.login({
        success(res) {
          if (res.code) {
            let code = res.code;
            that.setData({
              wx_phone_code: code
            })
            // 初始化獲取手機(jī)號(hào)組件
            that.selectComponent('#componentsPhoneId').eventInit()
          } else {
            wx.showToast({
              title: '微信授權(quán)登錄失敗',
              icon: 'none',
              duration: 2000//持續(xù)的時(shí)間
            });
            return;
          }
        }
      }),
  // 獲取手機(jī)號(hào)成功后回調(diào)事件
  getPhoneSuccess:function(event){
    if(event){
      this.setData({
        userinfo:event.detail
      })
    }
  },
index.json
"usingComponents": {
    "getPhone": "/components/getPhone/getPhone"
  }
index.wxml
<!-- 獲取用戶手機(jī)號(hào)彈窗 -->
 <getPhone id="componentsPhoneId" code="{{wx_phone_code}}" bind:success="getPhoneSuccess"></getPhone>  

大概思路

拿到code后執(zhí)行that.selectComponent('#componentsPhoneId').eventInit(),就算執(zhí)行組件的eventInit方法,去顯示組件,組件拿到解密后的接口后拋出that.triggerEvent('success', userInfo);success事件名稱,userInfo參數(shù),然后主頁(yè)面bind:success="getPhoneSuccess" 監(jiān)聽事件success,并自定義事件getPhoneSuccess,userInfo的值是在event.detail里面,大家可以打斷點(diǎn)看看哈

最后效果,上圖

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容