記錄使用微信小程序的開發過程當中遇到的各類難點及教程(不定時更新)

本文爲整理記錄本人使用微信小程序開發產品的過程當中,針對項目中業務需求所遇到的各類難點、API問題、BUG、及教程整理😁

一、wxml頁面的 Mustache 語法(雙大括號)數據綁定是不能使用全局js方法的,例如utils.js裏面定義的時間日期格式化,價錢格式化等等公共函數方法。
只能用.wxs文件,這是文檔:https://developers.weixin.qq....,而且.wxs文件只能使用es4語法,不支持es6語法,以及一些符號,好比我在vue項目裏經常使用的這個郵箱正則
const emailReg = /[\w!#$%&'*+/=?^_{|}~-]+(?:.[w!#$%&'*+/=?^_{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/; ,就會報錯。
因此想要在.wxml頁面使用全局方法的話,就先定義好.wxs文件的全局方法,而後以下引入就可使用util.wxs裏面的全局方法了,
<wxs src="../../utils/util.wxs" module="util" />
可是用.wxs來作全局方法的話有侷限性,例如moment.js和accounting.js,這種使用率比較大的第三方插件,.wxs文件是不能引用js文件的,只能引用.wxs文件。html

因此這點很操蛋,只能繼續使用 utils.js 在裏面定義好全局方法,而後在app.js入口引入,vue

/**
 * 全局公共方法
 * @type {function}
 */
const utils = require('./utils/utils.js');

App({
    // 全局公共方法
    utils: utils,
})

接着,假如在test頁面裏,須要使用全局方法來處理數據的美圓、RMB價錢以及平方英尺、平方米換算。使用方法很簡單:在test.js裏,在data裏聲明好變量,而後就能夠在下面使用全局方法來處理數據了。
例子:git

/* test.js */

// 獲取全局應用程序實例對象
const app = getApp();

Page({
    /**
     * 頁面的初始數據
     */
    data: {
        price: null,
    },
    
    /**
     * 生命週期函數--監聽頁面加載
     */
    onLoad: function (options) {
        //js裏只能這樣使用util全局方法,結合data聲明的變量處理數據
        
        //此處是判斷服務器接口返回的數據字段是否爲null,如res.data.price = 123
        this.setData({ price: app.utils.isNull0(res.data.price) });
    },
})

/* test.wxml */

<view>{{ price }}</view>
//最終頁面呈現爲<view>123</view>,若是服務端接口返回的price字段是null的話,那麼通過全局方法判斷後,頁面這裏應該顯示-

以上這些就是小程序page子路由頁面如何使用utils全局方法的所有內容了,這一點算是我入手小程序這幾天以來遇到的比較噁心🤢的了,相比用vue開發webapp項目,小程序這一點真的是反人類,很不方便😱。es6

二、UI庫的使用,我用了有讚的vant-weapp和iView-weapp。
使用方法:
vant-weapp:https://github.com/youzan/van...
iView-weapp:https://github.com/TalkingDat...
把代碼包下載到本地後,把裏面的dist目錄放到小程序的components目錄下,最終結構爲
圖片描述github

而後在app.json裏面定義好usingComponents字段,用到哪一個組件,按照其官方文檔的使用指南,把組件引入到usingComponents裏面就好了,注意相對路徑要設置好,否則會報錯。
例如我目前開發的小程序項目暫時用到了這幾個組件,以後開發完之後,dist目錄裏沒有用到的組件能夠刪掉。web

"usingComponents": {
    "van-row": "../components/vant-weapp/dist/row/index",
    "van-col": "../components/vant-weapp/dist/col/index",
    "van-toast": "../components/vant-weapp/dist/toast/index",
    "van-notify": "../components/vant-weapp/dist/notify/index",
    "van-tab": "../components/vant-weapp/dist/tab/index",
    "van-tabs": "../components/vant-weapp/dist/tabs/index",
    "van-search": "../components/vant-weapp/dist/search/index",

    "i-spin": "../components/iView-weapp/dist/spin/index",
    "i-button": "../components/iView-weapp/dist/button/index",
    "i-drawer": "../components/iView-weapp/dist/drawer/index"
}

三、小程序的頁面間跳轉有些規則的,vue開發wabapp項目,跳轉路由通常使用編程式導航的話是這樣的:vue-cli

this.$router.push({path: "/houseDetails", query: {id: id}});
//傳參在query裏定義。

而小程序的跳轉有4種:
(1)、wx.navigateTo(Object object);//保留當前頁面,跳轉到應用內的某個頁面。可是不能跳到 tabbar 頁面。使用 wx.navigateBack 能夠返回到原頁面。
(2)、wx.redirectTo(Object object);//關閉當前頁面,跳轉到應用內的某個頁面。可是不容許跳轉到 tabbar 頁面。
(3)、wx.reLaunch(Object object);//關閉全部頁面,打開到應用內的某個頁面
(4)、wx.switchTab(Object object);//跳轉到 tabBar 頁面,並關閉其餘全部非 tabBar 頁面npm

剛開始開發首頁的時候,用bindtap點擊事件綁定一個方法,在裏面用 navigateTo 怎麼點都不跳轉,沒反應,次日仔細看文檔才發現,要跳轉的頁面是 tabBar 頁面,因此向 tabBar 頁面跳轉的時候,不能使用navigateTo,要用 switchTab 方法來跳轉😳。編程

四、安裝npm第三方插件,參考此文檔,https://developers.weixin.qq....
具體步驟:
(1)、先在本項目裏打開命令行,而後npm install --production
(2)、跑完之後,好比要安裝moment.js 則 npm install moment --save
(3)、安裝完後 去微信開發者工具裏找到菜單欄 -> 工具 -> 構建npm 點擊執行,等待完成。
(4)、構建完後,項目根目錄裏會多出一個miniprogram_npm目錄,裏面就是安裝好的moment.js插件。
而後在utils.js引用:json

// moment時間格式化
import moment from 'moment';
// moment.locale('zh-cn');//加載中文包

而後就能夠在下面的全局方法 momentFormat(函數名本身取的) 裏利用moment.js的 API 正常處理數據了。

五、js裏的方法不能用es6的箭頭函數,只能用function(),不然會報錯this指向,查看報錯信息裏,this是undefined,暫不知是什麼緣由。
例如:

keywordChange: app.utils.debounce((e) => {
    this.setData({ searchKeyword: e.detail });//此時的this是undefined  因此這行會報錯
    if (app.utils.getByteLen(e.detail) > 3) {
        this.setData({ searchLoaderShow: true });
    }
}, 500)

keywordChange: app.utils.debounce(function(e) {
    this.setData({ searchKeyword: e.detail });//不用es6的箭頭函數就沒問題
    if (app.utils.getByteLen(e.detail) > 3) {
        this.setData({ searchLoaderShow: true });
    }
}, 500)

六、bindtap點擊事件的方法傳參要這麼寫才行:

<view bindtap="gotoDetails" data-searchType="{{ item.id }}"></view>

//方法裏這樣獲取點擊事件要用的key-value
gotoDetails(e){
    let url = '/pages/details/details?id='+ e.currentTarget.dataset.searchtype;
    //這裏有個坑,綁定事件的設置參數,若是參數名有大寫字母的話,下面獲取的時候要用小寫的,否則會報錯undefined。例如:data-searchType -> e.currentTarget.dataset.searchtype
    wx.navigateTo({
        url: url
    })
}

//不能像vue項目那樣,直接在括號裏跟參數,會報錯,哎,小程序有些地方真的反人類😝
<view bindtap="gotoDetails(id)"></view>

七、報錯:wx.switchTab: url 不支持 queryString
意思是tabBar頁面不支持url傳參,只能利用app.js定義好globalData裏的query參數,在要跳轉的頁面裏賦值,就能夠了。

八、吐槽下微信開發者工具的版本管理,真TMD難用,還不如直接用命令行操做git來的方便,跟intellij IDEA 內置的Git管理工具差遠了。
附個微信開發者工具的版本管理的設置教程:https://static.oschina.net/ne...

九、微信小程序設爲體驗版後,不能加載數據,進去首頁後會彈個Toast 輕提示 報錯:Object Object
通過百度搜索,多是這些緣由:域名已經備案、https已經配置、ssl證書在1.2以上版本、小程序後臺已經配置服務器域名

十、小程序遍歷對象要用wx:for-index屬性

<view wx:for="{{ obj }}" wx:for-item="item"  wx:for-index="key">
    <view class='aside'>{{ key }}</view>
</view>

十一、小程序的自定義組件有些像vue的組件化,好比詳情頁類型的內容結構複雜的頁面或者是有2處及以上有複用需求的,能夠用自定義組件來實現,具體教程可參考:
https://developers.weixin.qq....
https://blog.csdn.net/qq_4181...
注意:自定義組件不能用wxs。

十二、若是小程序頁面要作echarts圖表可視化功能,可是echarts圖表有不少,須要進行封裝,這種狀況最好仍是採用小程序的webview API來實現,
具體教程可參考:
https://developers.weixin.qq....
https://www.jianshu.com/p/292...

已經有作好的webAPP項目,可是要同步開發小程序,詳情頁有不少echarts圖表,這種狀況就很適合用webview,我剛開始的時候不知道webview,在研究自定義組件,在構思怎麼封裝全局可以使用的line、bar、pie、面積圖這四種公共組件,當時沒想好怎麼作,很麻煩。後來CTO告訴我用webview來實現。

好比已經作好了一個vue框架的webapp項目,而後只須要vue-cli再起一個vue項目,而後把之前作好的詳情頁圖表相關的代碼結構照搬過來就好了,無非就是改一點兒東西。

好比個人web端項目的詳情頁加起來有9個模塊,近百個echarts圖表,若是用戶初次進入頁面就加載所有的接口,那麼瀏覽器內存會很高,用戶會卡死幾秒的時間,體驗不好,因此用戶初次進入頁面是默認不加載圖表相關接口的。我採用了每一個模塊作成摺疊面板的方案,點擊展開時展現該模塊下的全部圖表,收起時銷燬圖表實例釋放內存,而且只在第一次展開時加載接口,後面收起再展開時就不須要重複請求接口了。

而小程序webview所需的vue項目,好比詳情頁9個模塊,能夠在小程序裏定義爲9個page頁面,而後點擊每一個模塊時跳轉到這個模塊對應的page頁面,而且把這個模塊下全部圖表所需的參數(好比商品id),經過url傳過去。而後這個page的wxml裏放webview組件,動態設置src。js裏獲取從詳情頁點擊模塊跳轉過來時所攜帶的query參數,拼接好之後,setData設置webviewURL。大概是這樣:

<!--商品詳情頁——圖表模塊標題-->
點擊圖表模塊時跳轉到這個模塊對應的page頁面,而且攜程必備query參數過去,好比我是這樣寫的:

<van-cell-group>
    <van-cell icon="location-o" title="查看圖表詳情" url="/pages/Details_RegionSituation/Details_RegionSituation?id={{id}}&zip={{zip}}" is-link />
</van-cell-group>

圖片描述

而後這個圖表模塊的page頁面獲取上面穿過來的query參數,並進行拼接處理,處理好後setData設置webview的src,我是這樣寫的:

<!--圖表模塊的採用webview組件的page頁面——wxml-->
<view class="page-body">
    <view class="page-section page-section-gap">
        <web-view src="{{ webviewURL }}"></web-view>
    </view>
</view>

<!--圖表模塊的採用webview組件的page頁面——js-->
data: {
    id: null, //商品id
    zip: null,
},
onLoad: function (options) {
        // console.log(options)
        //獲取url參數
        this.setData({
            id: options.id || null,
            zip: options.zip || null
        });

        let url = `https://-----此處爲你配置的業務域名-------/situation?id=${this.data.id}&zip=${this.data.zip}`;
        
        // situation爲模塊頁面名稱,隨便你怎麼定義。後面就是query參數

        this.setData({
            webviewURL: url
        });
},

【之因此項目詳情頁裏有9個圖表模塊,小程序就要新建9個page頁面,是由於一個page頁面只能放一個webview組件,而且會覆蓋掉其餘組件。】

而後在vue項目裏獲取到小程序webview src跳轉的時候攜帶的query參數,而後進行接口請求數據,配置圖表,就完事兒了。
記得退出頁面時也要銷燬圖表實例,vue項目的生命週期是這樣的:

beforeDestroy () {
    if(this.myEcharts){
        this.myEcharts.dispose();
    }
},

具體流程就是以上這些了,並不複雜。

這樣下來節省了大量的工做,詳情頁9個圖表模塊,加起來近百個echarts圖表,用webview從無到有隻用了三四天時間,我就不用頭疼麻煩的用小程序的自定義組建來實現需求了。

1三、image組件默認圖片的寬度300px、高度225px,有點二噁心,要實現實現寬度100%,高度自適應效果,要使用mode="widthFix"參數,參考API文檔:https://developers.weixin.qq....

1四、實現 Anchor 錨點定位,相似樓層導航的功能,主要使用scroll-view組件的scroll-into-view屬性,參考教程:https://developers.weixin.qq....
https://blog.csdn.net/weixin_...

1五、使用txv-video標籤,實現騰訊視頻播放功能。

【txv-video標籤的方案】
1️⃣:登陸上微信公衆平臺,而後第三方設置裏,添加騰訊視頻插件。
圖片描述

2️⃣:在app.json裏添加以下代碼

"plugins": {
    "tencentVideo": {
        "version": "1.3.0",
        "provider": "wxa75efa648b60994b"
    }
}

//version是騰訊視頻插件的版本號,我今天安裝完,查看最新更新的版本是1.3.0。
//provider是小程序的AppID,填對應本身開發的小程序AppID便可

3️⃣:在要用txv-video標籤的頁面的json文件裏添加以下代碼

"usingComponents": {
    "txv-video": "plugin://tencentVideo/video"
}

4️⃣:取出接口返回的src中的vid,(我使用的是web端的接口,video字段返回的是embed標籤,v-html直接渲染出來,然鵝,小程序不能用rich-text渲染embed標籤。。而後取出vid的邏輯看本身怎麼實現吧,個人代碼放上來僅供參考,可能有點兒傻😝)

//取出video中src
let videoSrc;
if (res.data.video.includes("src=")) {
    videoSrc = res.data.video.split('src=')[1].split('allowFullScreen')[0]; 
}
console.log(videoSrc)
//取出videoSrc中vid的值
let vid;
if (videoSrc.includes("vid=")) {
    vid = videoSrc.split('vid=')[1].split('&auto')[0];
}
this.setData({
    vid: vid
});
console.log(vid)
console.log(this.data.vid)

5️⃣:而後在wxml裏使用txv-video標籤,就完事兒了,蛋疼的是有廣告😒

//playerid名字隨便取,相似於id,是惟一的
<txv-video vid="{{ vid }}" playerid="txvVideo1"></txv-video>

到此就算完事兒了,播放騰訊視頻的功能已經完成,至於產品需求有多個視頻/有視頻列表,要作動態切換的話,就本身慢慢摸索吧,應該沒什麼難度。小程序目前看來最方便的就是用txv-video標籤,而後傳過去vid值,就能夠實現播放騰訊視頻的功能了,比下面的video組件的方案好,video組件的方案太麻煩,並且已通過去很長時間了,屬於取巧的一種方法吧。

【video組件實現播放騰訊視頻的方案】
具體流程參考這篇教程:https://blog.csdn.net/qq_4162...,前面取vid值的邏輯是同樣的,只不事後面要發接口vv.video.qq.com,再根據返回的字段,切割拼接出完整的video url,就是這麼個邏輯。

注:我沒順利完成,由於卡在了配置服務器域名這一步,https://tcb-api.tencentclouda...、https://vv.video.qq.com這兩個域名我都添加配置好了,可是請求接口時會報錯:https://vv.video.qq.com 不在如下 request 合法域名列表中,請參考文檔:https://developers.weixin.qq....
剛開始我覺得是配置服務器域名,小程序有緩存,要等10分鐘,後來仍是不行,果斷放棄該方案了。

1六、點擊圖片預覽大圖,通常詳情頁的輪播圖使用。
參考文檔:https://developers.weixin.qq....

//wxml
<swiper indicator-dots  circular indicator-active-color="#fff" current wx-if="{{ !housePhotoNoDataShow }}">
    <block wx:for="{{ housePhotoItem }}" wx:for-item="item" wx:key="index">
        <swiper-item>
            <image src='{{ item }}' lazy-load mode="aspectFill" data-index='{{index}}' bindtap='previewImg'></image>
        </swiper-item>
    </block>
</swiper>

//js
previewImg(e) {
    var currentImgIndex = e.currentTarget.dataset.index;
    var imgArr = this.data.housePhotoItem;
    // console.log(currentImgIndex, imgArr);
    wx.previewImage({
        current: imgArr[currentImgIndex],     //當前圖片地址
        urls: imgArr,               //全部要預覽的圖片的地址集合-數組形式
        success: function (res) {
            console.log(res)
        },
        fail: function (res) {
            console.log(res)
        },
        complete: function (res) {
            console.log(res)
        },
    })
},

1七、app.js新增更新線上版本的用戶友好提示(用於熱啓動時及時提示用戶有新版本更新,冷啓動時會自動下載更新),參考官方文檔:https://developers.weixin.qq....

App({
    onLaunch: function (options) {
        // 獲取小程序更新機制兼容
        if (wx.canIUse('getUpdateManager')) {
            const updateManager = wx.getUpdateManager();

            //監聽向微信後臺請求檢查更新結果事件。微信在小程序冷啓動時自動檢查更新,不需由開發者主動觸發。
            updateManager.onCheckForUpdate(function (res) {
                // 請求完新版本信息的回調
                console.log(res.hasUpdate)
            });

            //監聽小程序有版本更新事件。客戶端主動觸發下載(無需開發者觸發),下載成功後回調
            updateManager.onUpdateReady(function () {
                wx.showModal({
                    title: '新版本更新提示~',
                    content: '本小程序新版本已經準備好,是否重啓應用?',
                    success: function (res) {
                        if (res.confirm) {
                            // 新版本已經下載好,調用 applyUpdate 應用新版本並重啓
                            updateManager.applyUpdate()
                        }
                    }
                });
            });

            //監聽小程序更新失敗事件。小程序有新版本,客戶端主動觸發下載(無需開發者觸發),下載失敗(多是網絡緣由等)後回調
            updateManager.onUpdateFailed(function () {
                // 新版本下載失敗
                wx.showModal({
                    title: '已經有新版本了喲~',
                    content: '本小程序最新版本已經上線啦~,請您在小程序列表刪除當前小程序,從新搜索關鍵詞打開本小程序便可體驗最新版本喲~',
                })
            });
        } else {
            // 提示用戶在最新版本的客戶端上體驗您的小程序
            wx.showModal({
                title: '華美優勝提示您:',
                content: '當前微信版本太低,沒法正常使用小程序,請升級到最新微信版本後重試。'
            })
        }
    },
})
相關文章
相關標籤/搜索