微信小程序 - 入門指引

 稍微整了整微信小程序,仍是有很多問題的,作個小總結吧php

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

 

1、微信公衆平臺 - 小程序後臺

1.申請小程序帳號

官網註冊前端

註冊時所用的郵箱有限制(未註冊過公衆平臺、開放平臺、企業號、未綁定我的號的郵箱)vue

選擇主體爲我的或企業,按照流程註冊webpack

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

登陸es6

 

2.設置

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

大部分操做都須要管理員掃碼驗證web

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

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

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

3.小程序社區

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

 

2、小程序開發者工具

使用文檔  工具下載

 

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 管理員選擇審覈經過的版本,發佈爲線上版本

 

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

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工做流的方案更爲合適

 

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

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);
    });
相關文章
相關標籤/搜索