微信小程序 - 入門指引


 稍微整了整微信小程序,還是有不少問題的,做個小總結吧

和以往一樣,本次項目也放到了 Github 中,歡迎圍觀 star ~

 

一、微信公眾平台 - 小程序后台

1.申請小程序賬號

官網注冊

注冊時所用的郵箱有限制(未注冊過公眾平台、開放平台、企業號、未綁定個人號的郵箱)

選擇主體為個人或企業,按照流程注冊

小程序的信息填寫有次數限制,需要注意不要亂填(服務類目,名稱,頭像,介紹 等)

登錄

 

2.設置

記住這兩項 AppID 和 AppSecret,在開發時需要用到

大部分操作都需要管理員掃碼驗證

配置好開發者,體驗用戶的相關權限

設置 -> 基本設置 中配置好 基礎庫最低版本的設置

設置 -> 開發者設置 -> 服務器域名中   配置好服務器域名,小程序才能正確地發起異步請求

3.小程序社區

常見的問題可以 在 小程序社區 及 小程序論壇 及 小程序文檔 查找答案 

 

二、小程序開發者工具

使用文檔  工具下載

 

1.安裝

注意,小程序開發者工具與公眾號開發者工具不能同時運行,不能安裝在同一個目錄中

為了能夠兼容兩者的使用,需要一些額外的操作

比如需要同時使用三個工具,先修改文件夾命名

 

內部的exe可執行程序修改成對應的名稱

在開始菜單中才能正確找到三個程序的快捷入口

 

一般來說,開發者工具僅作為編譯及調試使用,代碼編輯建議使用自己的編輯器或IDE

開發者工具bug多多,如果發現失效的奇怪的問題,請重啟開發者工具

常用快捷鍵:

Ctrl+B 編譯 

Ctrl+R 刷新 

Ctrl+Shift+P 遠程預覽(項目需要提供AppID) 

 

2.其他說明

2.1. 打開開發者工具,選擇項目文件夾,自動識別為已有項目還是新建的項目

填寫AppID 才能使用真機預覽

 

 

2.2. 小程序布局以iPhone6為基礎

所以在移動設備模擬中 選用 iPhone6作為基准,再兼容其他設備

設備模擬與真機預覽某些時候差異很大,別忘了在手機上調試

 

2.3 建議的設置項

默認開發者工具中發起的異步請求僅在開發者工具中看到,如需使用Fiddler進行調試,需要手動設置代理

 

2.4 項目配置

項目的設置,會自動同步到 project.config.json文件中

點開右側詳情,選中比較高的調試基礎庫版本

選用自帶的ES6轉ES5,代碼補全壓縮

開發時記得勾選不校驗域名(防止訪問失敗),上線階段記得取消勾選(校驗域名可更安全)

可點擊切換編輯器的顯示隱藏,快速調整右下開發者調試的窗口

 

2.5 代碼上傳

2.5.1 先進行編譯並遠程預覽

2.5.2 再進行上傳,管理員登錄微信公眾平台選擇啟用為體驗版本,相關人員進行體驗

2.5.3 管理員選用體驗版本上傳作為審核

不可隨意上傳審核,多次審核不通過有懲罰機制

2.5.4 管理員選擇審核通過的版本,發布為線上版本

 

三、小程序開發框架、代碼結構

1.基礎結構

文檔

文件的配置項

tabbar中的路徑以及頁面中的跳轉路徑,都必須在app.json的pages中配置好,其中分包的pages也要配置好

2.項目結構

小程序支持大部分ES6語法,但為了支持完整的ES6+語法,以及對原生的回調做優化,引入 wxPromise

基本支持小程序的所有API轉換成 then catch  finally 的便捷語法,加上 wx.pro.即可  如

// 演示 wxPromise 的能力
wx.request({
  url: 'test.php', //僅為示例,並非真實的接口地址
  data: {
     x: '' ,
     y: ''
  },
  header: {
    'content-type': 'application/json' // 默認值
  },
  success: function(res) {
    console.log(res.data)
  },
  fail: function(e) {
    console.log(e)
  },
  complete: function(e) {
    console.log(e)
  }
})
wx.pro.request({
  url: 'test.php',
  data: {},
  method: 'GET',
  header: {'content-type': 'application/json'}
}).then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
}).finally(() => {
  wx.hideLoading()
})

小程序不支持SCSS預編譯的CSS,為了支持SCSS,所有需要引入構建工具進行編譯

小程序自帶了代碼壓縮,不過基本上只是對JS做了壓縮,還需要壓縮其他資源文件(WXSS、WXML等)

引入Gulp構建工具

項目參考 此Demo

目錄結構

src目錄為源代碼,gulpfile為 Gulp的任務配置,經過處理猴,將生成dist目錄,在小程序開發者工具中打開此 dist目錄即可

在sign目錄下,執行 npm i 安裝依賴包,然后運行 npm start 即可執行並監聽,更新dist目錄的內容,然后在 開發者工具中重新編譯 Ctrl+B 即可看到效果(有時開發者工具出現奇怪問題的,就重啟工具)

src目錄中主要為項目根文件,pages頁面目錄,assets資源目錄

pages目錄中的 嵌入的subPages目錄用作分包目錄,頁面之外的其他資源文件或其他模塊在assets目錄中

app.json配置示例

{
    "pages": [
        "pages/index/index",
        "pages/user/user",
        "pages/wait/wait"
    ],
    "window": {
        "backgroundTextStyle": "light",
        "navigationBarBackgroundColor": "#1296db",
        "navigationBarTitleText": "我來也",
        "navigationBarTextStyle": "white"
    },
    "subPackages": [{
        "root": "pages/subPages",
        "pages": [
            "signed/signed"
        ]
    }],
    "tabBar": {
        "selectedColor": "#1296db",
        "borderStyle": "white",
        "list": [
            {
                "pagePath": "pages/index/index",
                "text": "我要簽到",
                "iconPath": "./assets/imgs/sign.png",
                "selectedIconPath": "./assets/imgs/sign_active.png"
            },
            {
                "pagePath": "pages/wait/wait",
                "text": "等候大廳",
                "iconPath": "./assets/imgs/wait.png",
                "selectedIconPath": "./assets/imgs/wait_active.png"
            },
            {
                "pagePath": "pages/user/user",
                "text": "個人中心",
                "iconPath": "./assets/imgs/user.png",
                "selectedIconPath": "./assets/imgs/user_active.png"
            }
        ]
    },
    "debug": true
}
View Code

頁面配置user.json配置示例

{
    "navigationBarTitleText": "個人中心"
}
View Code

Gulp編譯示例

運行示例

 

 

3. 項目框架

小程序開發,一般有三種方式

3.1 純原生開發

3.2 基本使用原生開發,並使用構建工具進行一些簡單構建

3.3 使用小程序開發框架

比較常用的框架為,wepy 和 mpvue

兩者都需要vue語法基礎,無vue基礎則有些障礙,相對來說 mpvue能更純粹地使用以往開發Web的經驗,wepy在小程序之上又有自己的一套規則

使用框架,並不是不再需要使用小程序原生的語法API

鑒於此,為了彌補原生不支持SCSS的不足,使用 3.2 做簡單構建方案

不采用webpack的原因是webpack基於JS模塊,通過配置入口模塊做依賴打包,在小程序項目中Gulp工作流的方案更為合適

 

四、小程序基礎語法、常見問題

1.基礎用法

小程序的學習主要分為 框架  組件 API 三個部分

框架為基礎的語法結構

組件類似web中的HTML標簽,web中的component 

API為小程序中的可用JS方法

部分組件與API有版本兼容問題,需要注意

 

2. 常見問題

2.1 input組件中上方的圖標按鈕在真機中點擊失效

input組件為原生組件,層級最高。focus 聚焦狀態下點擊上方的按鈕時,會先觸發失焦,再次點擊按鈕才生效

解決辦法,按鈕置於input后面,背景做一些處理,與input區域的背景協調一致

另外要注意,需要將按鈕可點區域擴大,可以獲得更好的使用體驗

 

2.2 image組件的大小適應問題

小程序中image默認為完全拉伸至填滿image容器的scaleToFill 屬性,有時會導致圖片扭曲變形

常用的 mode 模式為 widthFix 寬度不變,高度自動變化,保持原圖寬高比不變。需要先設置好寬度

另外,在引入小圖標時,也要注意小圖標受到image組件默認寬高320px*240px 的影響,會被拉伸。可手動設置寬高解決

 

2.3 部分小圖標可使用自帶的 icon組件

 

2.4 如需要提供可選擇可復制的文本 ,需使用 text組件 ,而不是 view 組件

 

2.5 Flex布局的使用

小程序中會大量使用到 Flex布局,要掌握好。優先使用此布局方案

 

2.6 rpx自適應單位的使用

小程序中引入了新的CSS單位 rpx(responsive pixel), 相對於px,它提供了自適應的能力,優先使用這個單位

 

 

規定了以iPhone6屏幕(375px*667px)為基准,其設備像素比DPR為2,所以定義其屏幕寬度為 375px * 2 = 750rpx,相當於 1px == 2rpx  、1rpx == 0.5px

在以往web開發中,我們需要根據不同機型的屏幕寬度與DPR,手動計算不同的rpx值

但在小程序中,我們只需要以iPhone6為基准開發即可(設計稿也需要設計成iPhone6的750px寬度),設置好750px下某個元素應該是多少rpx,其他的轉換工作無需考慮

 

2.7 文本垂直居中的處理

在小程序中文本和圖片之前的垂直居中可能需要特殊處理, 以往web頁面中可用 vertical-align: middle; 實現居中效果

但在小程序中的 image組件 和 text 組件的表現不太一樣,看着不居中

可以使用Flex布局居中的方式,父元素設置  display: flex;  align-items: center; 即可

 

2.8 底部 tabbar圖標與文本大小的自適應

小程序自帶的 底部tabbar可自定義的程度不是很高,不同機型下可能會出現圖標太大或文字太小的不同現象

解決方案:

使用自帶tabbar,圖標選用 81px * 81px ,注意圖標不要撐滿大小,需要留白,否則會偏大

自定義tabbar,需要模擬原生tabbar的一些跳轉時的固定效果,盡量保持和自定義的體驗一致

可參考 一些Demo

 

2.9  頁面跳轉使用絕對路徑,且需要在 pages 中配置好

如 跳轉到某個頁面

wx.navigateTo({
    url: '/pages/subPages/signed/signed'
});

 

2.10 tabbar中配置的頁面,需要使用 switchTab 才能跳轉

同樣的 switchTab 也只能跳轉到 tabbar設置的頁面

wx.switchTab({url:'/pages/user/user'});
 
<navigator class='goto-sign' open-type="switchTab" url='/pages/index/index'>
    <image src="../../assets/imgs/sign_active.png"  />
    <text>前往簽到</text>
</navigator>
 
wx.redirectTo({url:'/pages/subPages/signed/signed'});

 

2.11 在WXSS中的背景圖片不能設置為本地路徑

僅支持作為 base64引入圖片,或者使用網絡地址的圖片,或者使用 image組件引入圖片

 

2.12 請求時的url參數需要設置為帶 scheme(如 http)的絕對地址

且需要在微信工作平台設置好服務器域名

 

2.13 小程序的代碼包限制為 2M 

可使用分包策略,單個包限制為2M,所有包限制為8M

能使用網絡資源的就使用網絡資源(比如圖片、音頻等),能壓縮的就壓縮,精簡優化代碼

分包方法:

假設對不需要初次就加載的頁面 signed.wxml進行打包加載,對其進行分包

在 app.json中配置 subPackages

"subPackages": [{
    "root": "pages/subPages",
    "pages": [
        "signed/signed"
    ]
}],
"tabBar": {
    ...
}

將該頁面包放在 pages主頁面目錄下的 subPages 子頁面目錄即可

跳轉時記得把 這里的 subPages 路徑也加上  /pages/subPages/signed/signed

 

2.14 過多地進行 setData 操作可能會導致性能下降

 

2.15 登錄授權的兼容方案

以下僅涉及獲取用戶基本信息的部分,如要獲取openID 手機號等 還需要發起請求讓后端來解密處理 更多步驟

舊版本中一般直接使用JS進行調用

wx.getUserInfo({
    success: function(res) {
        console.log(res.userInfo)
    }
})

新版本中已逐漸不支持,直接調用會失效,應該改用 button組件引導用戶啟用授權

點擊按鈕后再獲取信息

 

 

<view class='user__info'>
    <button wx:if="{{!hasUserInfo}}" open-type='getUserInfo' bindgetuserinfo='getUserInfo'>
        <image class='user__wx' src="../../assets/imgs/wx.png" mode='widthFix' />
        <text>微信授權登錄</text>
    </button>
    <block wx:else>
        <image class="user__avatar" src="{{avatar}}"/>
        <view >{{nickName}}</view>
    </block>
</view>

有信息的就直接顯示信息,否則提示用戶點擊按鈕授權

點擊后將觸發 getUserInfo回調,e.detail中攜帶了 與 wx.getUserInfo 相同的返回信息

將用戶信息保存到本地緩存

 

data: {
    hasUserInfo: app.globalData.userInfo.hasUserInfo,
    avatar: app.globalData.userInfo.avatar,
    nickName: app.globalData.userInfo.nickName
},
...
getUserInfo(e) {
    if (!e.detail.userInfo) {
        return;
    }
    app.globalData.userInfo = {
        hasUserInfo: true,
        avatar: e.detail.userInfo.avatarUrl,
        nickName: e.detail.userInfo.nickName
    }
    wx.setStorage({
        key: 'userInfo',
        data: app.globalData.userInfo
    });
    this.setData({
        hasUserInfo: app.globalData.userInfo.hasUserInfo,
        avatar: app.globalData.userInfo.avatar,
        nickName: app.globalData.userInfo.nickName
    });
}

 

2.16 上傳文件

目前僅支持上傳圖片及小視頻

僅支持一次上傳一個文件,多個文件需循環上傳

需考慮全部上傳成功才繼續操作,可使用 promise.all 結合 await/async 異步處理

如 上傳圖片成功后才提交數據

async uploadFaces() {
     let p = [];
     (this.data.face || []).forEach(item => {
         p.push(new Promise((resolve, reject) => {
             wx.pro.uploadFile({
                 url: 'http://xxx',
                 filePath: item,
                 name: 'cover',
                 formData: {
                     _csrf: 'RktCQ3daWDJ3Sk1aSE9ucikRJRYcLhoFODo1Yx4AACgLBDsTBSwAYS59fGsxJ1offf'
                 },
                 header: {
                     'Cookie': 'PHPSESSID=95nno109b17gbfb852tpf4mke455',
                     'content-type': 'multipart/form-data'
                 }
             }).then(rs => {
                 let data = typeof rs.data === 'string' ? JSON.parse(rs.data) : rs.data;
                 if (!data.status) {
                     reject(rs);
                 } else {
                     resolve(rs);
                 }
                 console.log(rs);
             }).catch(e => {
                 reject(e);
                 console.log(e);
             });
         }));
     });
     await Promise.all(p);
 },
 submitData(data) {
     let that = this;
     console.log(data);
 ...
 }
 
 
 ...
  
 if (rs.confirm) {
    let uploadFaceloading = wx.showLoading({
       title: '上傳中'
    });
      
    // 先上傳圖片
    that.uploadFaces()
        .then((rs) => {
            console.log('uploadSuccess', rs);
              
             // 再提交數據
            that.submitData(e.detail.value);
       }).catch(e => {
           wx.showToast({
              title: '上傳失敗',
             icon: 'none'
           });
           console.log('uploadFail', e);
       }).finally(rs => {
           wx.hideLoading(uploadFaceloading);
       });
}

 

2.17  獲取本地圖片 wx.chooseImage 等相關的API,會觸發頁面的 onHide/onShow

開始選擇,直到選擇完畢,相關的觸發流程

所以在onShow或onHide中需要處理一些數據時,要關注這個問題

在app.globalData中設置一個標志位,由其他頁面跳轉進來onShow時獲取到正確的標志位(即其他頁面卸載/隱藏時 將該標志為置位),chooseImage 選擇后不置位

使用一些獲取頁面棧的API,來判斷當前頁面的信息(如 getCurrentPages() ,只是能夠判斷出來的幾率不是很大)

 

2.18 獲取用戶坐標位置

使用 wx.getLocation 能夠獲取用戶坐標的經緯度,我們還需要將其轉換為可識別的城市信息,需要使用第三方API(比如騰訊地圖,百度地圖等)來解析坐標

使用騰訊位置服務,先注冊登錄,生成屬於自己的 KEY值用於傳值,需要啟用 WebServiceAPI

查看相關文檔下載 JDK,然后引入

在獲取到經緯度之后,調用

// app.js
let QQMapWX = require('./assets/js/qqmap-wx-jssdk.min.js');
 
App({
    onLaunch: function() {
        let userInfo = wx.getStorageSync('userInfo');
        this.globalData.qqmapsdk = new QQMapWX({
            // 輸入對應的key
            key: '...'
        });
    },
 
    globalData: {
        qqmapsdk: null
    }
});
 
 
// index.js
let app = getApp();
 
Page({
    onReady() {
        wx.pro.getLocation({
            type: 'wgs84'
        }).then(res => {
            console.log(res);
            // 獲取當前位置
            app.globalData.qqmapsdk.reverseGeocoder({
                location: {
                    latitude: res.latitude,
                    longitude: res.longitude
                },
                success: (addressRes) => {
                    let city = addressRes.result.address_component.city;
                    console.log(addressRes.result.address_component, city);
                    // 匹配當前坐標,設置城市
                    if (city) {
                        let groupSelected = this.data.group.find(item => {
                            return city.includes(item);
                        });
                        groupSelected && this.setData({
                            groupSelected: groupSelected
                        });
                    }
                },
                fail: (e) => {
                    console.log(e);
                }
            });
        }).catch(e => {
            console.log(e);
        });
    }
 
})

也可以手動設置經緯度進行測試,在開發者工具中

 

可以使用百度地圖拾取坐標系統 查詢某地的坐標,用作測試

首次調用時會詢問用戶授權,如果用戶允許了,接下去就不再詢問。如果拒絕,則將一直拒絕。

大部分授權的詢問機制是差不多的。

 

2.19 關於授權

微信小程序涉及很多授權相關的東西,基礎的信息可以直接使用API獲取,敏感數據需要通過后端發起API來解析

在微信開發者工具中,可以在這里清除授權信息(遠程調試的手機上也會被清除),用以反復測試授權的情況

在手機上,可以點擊小程序右上角的.. ,查看關於小程序

 

 

 

 

即可在這個頁面的授權列表中開啟或關閉

如果用戶之前已經拒絕授權,調用相關API時將直接失敗,不會再彈出授權窗口

這時,可以考慮使用 wx.openSetting ,將會跳轉到這個授權列表頁,讓用戶先手動設置

// 打開授權設置窗口,進行手動授權
        wx.pro.openSetting({})
            .then(rs => {
                console.log(rs);
            }).catch(e => {
                console.log(e);
            });

也可以使用 wx.authorize 來指定哪種授權,不過如果之前用戶拒絕過,將在一段時間之內一直返回失敗的信息,所以還是很雞肋的..

// 獲取用戶的授權狀態列表
wx.pro.getSetting({})
    .then(rs => {
        console.log(rs);
        // 查詢位置信息是否已允許授權
        if (!rs.authSetting['scope.userLocation']) {
            // 請求授權獲取用戶位置
            wx.pro.authorize({
                scope: 'scope.userLocation'
            })
            .then(rs => {
                console.log(rs);
            }).catch(e => {
                console.log(e);
            });
        }
    }).catch(e => {
        console.log(e);
    });

其他相關的API

獲取用戶的登錄狀態,在調用某些API時,需要先調用此API,目前還不得而知

// 獲取用戶的登錄狀態
wx.pro.login({})
    .then(rs => {
        console.log(rs);
    }).catch(e => {
        console.log(e);
    });

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2024 CODEPRJ.COM