mpvue開發小程序總結

前言

前段時間公司要開發個小程序的項目,因而開始了本身的小程序之旅,一切從頭看文檔開始,邊看邊作,遇到了很多坑,由於筆者一直習慣使用vue,因而就使用了mpvue框架開發;我會從構建項目開始以及開發中遇到的問題所有講述一遍,但願可以對你有幫助,或許你以爲簡單,但再簡單也是要從零走過來;在開發中有好幾個問題要注意的:html

  1. 小程序主包不能超過2M問題;
  2. 單位使用問題;
  3. 頁面緩存問題;
  4. 圖片路徑問題;
  5. 有兩個網站會你會常常用到:
    開發平臺:mp.weixin.qq.com/
    開發文檔:developers.weixin.qq.com/miniprogram…
    小問題就更多了,接下來會一一羅列,雖然有點囉嗦,但只要看下去,基本能夠解決遇到的坑;

一、開發前準備

  1. 首先要到微信開發平臺註冊帳號,這步很簡單,網址:mp.weixin.qq.com/ 登陸進去後能夠處處逛逛,而後開發時基本要用到的是appid,在左邊的開發中點進去,在開發設置中能夠取到appid;具體其它的就要本身看看其它配置了;
  2. 下載微信小程序開發者工具,這個要到小程序開發文檔官網上能夠下載;
    網址:developers.weixin.qq.com/miniprogram…
  3. 開發者工具就像谷歌瀏覽器同樣,模擬手機,還有能夠方便咱們的調試等等 ;

二、構建項目

  1. 構建項目具體根據mpvue的官網來就能夠了,網址:mpvue.com/mpvue/#_1
  2. 裏面人家寫得清清楚楚,這裏就很少講了,以下:
# 全局安裝 vue-cli
$ npm install --global vue-cli

# 建立一個基於 mpvue-quickstart 模板的新項目
$ vue init mpvue/mpvue-quickstart my-project

# 安裝依賴
$ cd my-project
$ npm install
# 啓動構建
$ npm run dev
複製代碼
  1. 在npm install 及 npm start 後,會啓動一個項目出來,而後能夠在項目的文件夾中看到有個dist文件,那個就是webpack打包出來的小程序文件,開發工具只要引入它就能夠打開項目了:

三、分包策略

  1. 先解釋一下什麼叫分包? 一開始我也感受到很陌生,後來查了好多資料,資料上說小程序爲了保證它的流暢性,就把主包的大小控制在2M,超過了2M就發佈不上去,連預覽都不能夠;
    主包包括 :
    1. 在pages裏面的頁面
      這三個就是主包中的頁面,subPackages是分包,分包接下來會講;爲何要將這三個頁面放到主包中呢?由於我用了小程序默認的底部tabbar,小程序要求tabbar上的頁面必需要在主包中,因此我也沒辦法;固然tabbar是能夠本身寫一個的,我沒有自定義,就用它的能夠了;
      2. static裏面的全部靜態資源,因此最好不要將圖片跟體積大的插件放進來,否則後面難於開發;
  2. 知道了主包,這下就能夠理解分包了,咱們會有不少頁面要開發,不可能不超過2M的,因此咱們能夠將其它頁面寫在分包中,分包能夠有很是多個,一個分包的大小也是不能夠超過2M的:
  3. 分包的建立:mpvue建立分包是很是簡單的,步驟以下:
    1. 在pages文件夾下建立一個文件夾,名字叫subPackages(文件名能夠隨意配); 2. 而後將頁面寫在裏面就能夠了:
    3. 在app.json中寫上剛纔添加的方件路徑就能夠了:

四、tabbar的配置

小程序底部的tabbar仍是很好用的,方法很簡單,在app.json中,以下:前端

  1. 將頁面放在主包中(最少要有兩個頁面)
  2. 將頁面路徑配在pages 中;
  3. 將頁面配置在tabbar裏的list中
  4. 具體細節看文: developers.weixin.qq.com/miniprogram…

五、配置less

小程序建立出來的裸版是不帶less、sass的,須要本身去配置:vue

  1. 先安裝:npm install less less-loader --save-dev
  2. 配置 : 在webpack.base.conf.js中配置

六、頁面的跳轉及參數的獲取

  1. 小程序的頁面跳轉開發文檔上已經說的很詳細了,網址:
    developers.weixin.qq.com/miniprogram…node

  2. 在此,有幾個要注意的:
    (1). 若是是小程序自帶的tabbar上的頁面,在任何其它頁面跳轉到tabbar 的其中一個頁面時,要使用webpack

    wx.switchTab({url : '/pages/xxx/main'})  
    複製代碼

    (2). 關閉其它曾經打開的頁面,打開新的頁面,也就是沒有返回按鈕的,使用git

    wx.reLaunch({url : '/pages/subPackages/xxx/main'}) 
    複製代碼

    (3).普通頁面的跳轉,可使用 wx.navigateTo({url: ' '})github

  3. 頁面參數的傳遞以及獲取
    (1). 頁面參數的傳遞,咱們能夠經過地址欄帶過去,很簡單:web

    wx.switchTab({url : '/pages/xxx/main?id=123&key=456'})
     wx.switchTab({url : `/pages/xxx/main?id=${this.id}&key=${this.key}`})
    複製代碼

    (2). 頁面參數的獲取:
    mpvue的文檔有也有說,網址:mpvue.com/mpvue/#_3算法

    能夠在onLoad鉤子之後的其它鉤子中獲取,參數就在options裏,若是沒有參數,取不到時爲undefined:vue-cli

    wx.onLoad(options){ console.log( options )}
     wx.onShow(options){ console.log( options )}
    複製代碼

    若是要在其它方法中獲取,也可使用方法:

    this.$root.$mp.query
    複製代碼

七、單位rpx

在小程序中,咱們能夠直接使用rpx做爲單位,建議設計稿也是按照iphone6的尺寸來設計,由於rpx是按照 750px iphone6上的像素來設計的,文檔上也有說明,網址:
developers.weixin.qq.com/miniprogram…

八、單位PX自適應換算

  1. 有時咱們會使用到第三方的庫,可能它的大小不能使用rpx,這時可能就要咱們本身去換算 px 自適應了,好比echarts,它就是要你傳入單位爲px的,我就遇到了這個問題;

  2. 換算公式:
    自適應尺寸 / 設備屏幕寬度 = 設計稿上元素寬度 / 設計稿寬度
    也就是: 自適應尺寸 = 設計稿上元素寬度 / 設計稿寬度 * 設備屏幕寬度

  3. 例如:獲取寬度

    const echartWidth = 700 / 750 * wx.getSystemInfoSync().windowWidth;
    const echartHeight = 540 / 750 * wx.getSystemInfoSync().windowWidth;
    複製代碼

    其中,700與540是設計稿上量出來的尺寸; 750是設計稿的寬度; wx.getSystemInfoSync().windowWidth 這個方法是獲取屏幕寬度;

    結果就是寬度跟高度會根據機型的不一樣會自適應,單位是px;

九、請求方法的封裝

  1. 小程序已經封裝好的請求的api :wx.request()
    網址: developers.weixin.qq.com/miniprogram… 但咱們仍是要對它進行二次封裝,由於根據各項目的業務需求不一樣,要添加請求頭上的信息等等,確定是只封裝一次,到處調用;
  2. 如下是基本的封裝方法,具體仍是要根據後端要求的請求頭配置參數來配:
export default function request({
  url,
  data = '',
  header = { 'Content-Type': 'application/json' },
  method = 'GET',
  dataType = 'json',
  responseType = 'text',
}) {
  wx.request({
    url: `${baseUrl}${url}`,
    method,
    data,
    header: header,
    dataType,
    responseType,
    success: res => {
      // 對響應進行統一處理,具體規則要與後端協調
      const responseData = res.data;
      if ([200].indexOf(res.statusCode) !== -1) {
        response.success = responseData;
      } else {
        response.fail = res;
      }
    },
    fail: error => {
      response.fail = error;
    },
    complete() {
      resolve(response.success);
    },
  });
}
複製代碼
  1. 接下來能夠在單獨文件夾裏引入將全部的請求都寫在那個文件裏,方便管理; 如:
import request from './request';
export function getList() {
  return request({
    url: '/index/hotcity',
  });
}
複製代碼
  1. 在頁面中調用 :
import { getList} from './api'
getList().then(res => {}).catch(err => {})
複製代碼

十、MD5加密庫

  1. 這個MD5加密的庫也許你會用得上,能夠直接複製過去用:
var rotateLeft = function(lValue, iShiftBits) {
  return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
};

var addUnsigned = function(lX, lY) {
  var lX4, lY4, lX8, lY8, lResult;
  lX8 = lX & 0x80000000;
  lY8 = lY & 0x80000000;
  lX4 = lX & 0x40000000;
  lY4 = lY & 0x40000000;
  lResult = (lX & 0x3fffffff) + (lY & 0x3fffffff);
  if (lX4 & lY4) return lResult ^ 0x80000000 ^ lX8 ^ lY8;
  if (lX4 | lY4) {
    if (lResult & 0x40000000) return lResult ^ 0xc0000000 ^ lX8 ^ lY8;
    else return lResult ^ 0x40000000 ^ lX8 ^ lY8;
  } else {
    return lResult ^ lX8 ^ lY8;
  }
};

var F = function(x, y, z) {
  return (x & y) | (~x & z);
};

var G = function(x, y, z) {
  return (x & z) | (y & ~z);
};

var H = function(x, y, z) {
  return x ^ y ^ z;
};

var I = function(x, y, z) {
  return y ^ (x | ~z);
};

var FF = function(a, b, c, d, x, s, ac) {
  a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
  return addUnsigned(rotateLeft(a, s), b);
};

var GG = function(a, b, c, d, x, s, ac) {
  a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
  return addUnsigned(rotateLeft(a, s), b);
};

var HH = function(a, b, c, d, x, s, ac) {
  a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
  return addUnsigned(rotateLeft(a, s), b);
};

var II = function(a, b, c, d, x, s, ac) {
  a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
  return addUnsigned(rotateLeft(a, s), b);
};

var convertToWordArray = function(string) {
  var lWordCount;
  var lMessageLength = string.length;
  var lNumberOfWordsTempOne = lMessageLength + 8;
  var lNumberOfWordsTempTwo =
    (lNumberOfWordsTempOne - lNumberOfWordsTempOne % 64) / 64;
  var lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;
  var lWordArray = Array(lNumberOfWords - 1);
  var lBytePosition = 0;
  var lByteCount = 0;
  while (lByteCount < lMessageLength) {
    lWordCount = (lByteCount - lByteCount % 4) / 4;
    lBytePosition = (lByteCount % 4) * 8;
    lWordArray[lWordCount] =
      lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition);
    lByteCount++;
  }
  lWordCount = (lByteCount - lByteCount % 4) / 4;
  lBytePosition = (lByteCount % 4) * 8;
  lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
  lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
  lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
  return lWordArray;
};

var wordToHex = function(lValue) {
  var WordToHexValue = '',
    WordToHexValueTemp = '',
    lByte,
    lCount;
  for (lCount = 0; lCount <= 3; lCount++) {
    lByte = (lValue >>> (lCount * 8)) & 255;
    WordToHexValueTemp = '0' + lByte.toString(16);
    WordToHexValue =
      WordToHexValue +
      WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
  }
  return WordToHexValue;
};

var uTF8Encode = function(string) {
  string = string.replace(/\x0d\x0a/g, '\x0a');
  var output = '';
  for (var n = 0; n < string.length; n++) {
    var c = string.charCodeAt(n);
    if (c < 128) {
      output += String.fromCharCode(c);
    } else if (c > 127 && c < 2048) {
      output += String.fromCharCode((c >> 6) | 192);
      output += String.fromCharCode((c & 63) | 128);
    } else {
      output += String.fromCharCode((c >> 12) | 224);
      output += String.fromCharCode(((c >> 6) & 63) | 128);
      output += String.fromCharCode((c & 63) | 128);
    }
  }
  return output;
};

function md5(string) {
  var x = Array();
  var k, AA, BB, CC, DD, a, b, c, d;
  var S11 = 7,
    S12 = 12,
    S13 = 17,
    S14 = 22;
  var S21 = 5,
    S22 = 9,
    S23 = 14,
    S24 = 20;
  var S31 = 4,
    S32 = 11,
    S33 = 16,
    S34 = 23;
  var S41 = 6,
    S42 = 10,
    S43 = 15,
    S44 = 21;
  string = uTF8Encode(string);
  x = convertToWordArray(string);
  a = 0x67452301;
  b = 0xefcdab89;
  c = 0x98badcfe;
  d = 0x10325476;
  for (k = 0; k < x.length; k += 16) {
    AA = a;
    BB = b;
    CC = c;
    DD = d;
    a = FF(a, b, c, d, x[k + 0], S11, 0xd76aa478);
    d = FF(d, a, b, c, x[k + 1], S12, 0xe8c7b756);
    c = FF(c, d, a, b, x[k + 2], S13, 0x242070db);
    b = FF(b, c, d, a, x[k + 3], S14, 0xc1bdceee);
    a = FF(a, b, c, d, x[k + 4], S11, 0xf57c0faf);
    d = FF(d, a, b, c, x[k + 5], S12, 0x4787c62a);
    c = FF(c, d, a, b, x[k + 6], S13, 0xa8304613);
    b = FF(b, c, d, a, x[k + 7], S14, 0xfd469501);
    a = FF(a, b, c, d, x[k + 8], S11, 0x698098d8);
    d = FF(d, a, b, c, x[k + 9], S12, 0x8b44f7af);
    c = FF(c, d, a, b, x[k + 10], S13, 0xffff5bb1);
    b = FF(b, c, d, a, x[k + 11], S14, 0x895cd7be);
    a = FF(a, b, c, d, x[k + 12], S11, 0x6b901122);
    d = FF(d, a, b, c, x[k + 13], S12, 0xfd987193);
    c = FF(c, d, a, b, x[k + 14], S13, 0xa679438e);
    b = FF(b, c, d, a, x[k + 15], S14, 0x49b40821);
    a = GG(a, b, c, d, x[k + 1], S21, 0xf61e2562);
    d = GG(d, a, b, c, x[k + 6], S22, 0xc040b340);
    c = GG(c, d, a, b, x[k + 11], S23, 0x265e5a51);
    b = GG(b, c, d, a, x[k + 0], S24, 0xe9b6c7aa);
    a = GG(a, b, c, d, x[k + 5], S21, 0xd62f105d);
    d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
    c = GG(c, d, a, b, x[k + 15], S23, 0xd8a1e681);
    b = GG(b, c, d, a, x[k + 4], S24, 0xe7d3fbc8);
    a = GG(a, b, c, d, x[k + 9], S21, 0x21e1cde6);
    d = GG(d, a, b, c, x[k + 14], S22, 0xc33707d6);
    c = GG(c, d, a, b, x[k + 3], S23, 0xf4d50d87);
    b = GG(b, c, d, a, x[k + 8], S24, 0x455a14ed);
    a = GG(a, b, c, d, x[k + 13], S21, 0xa9e3e905);
    d = GG(d, a, b, c, x[k + 2], S22, 0xfcefa3f8);
    c = GG(c, d, a, b, x[k + 7], S23, 0x676f02d9);
    b = GG(b, c, d, a, x[k + 12], S24, 0x8d2a4c8a);
    a = HH(a, b, c, d, x[k + 5], S31, 0xfffa3942);
    d = HH(d, a, b, c, x[k + 8], S32, 0x8771f681);
    c = HH(c, d, a, b, x[k + 11], S33, 0x6d9d6122);
    b = HH(b, c, d, a, x[k + 14], S34, 0xfde5380c);
    a = HH(a, b, c, d, x[k + 1], S31, 0xa4beea44);
    d = HH(d, a, b, c, x[k + 4], S32, 0x4bdecfa9);
    c = HH(c, d, a, b, x[k + 7], S33, 0xf6bb4b60);
    b = HH(b, c, d, a, x[k + 10], S34, 0xbebfbc70);
    a = HH(a, b, c, d, x[k + 13], S31, 0x289b7ec6);
    d = HH(d, a, b, c, x[k + 0], S32, 0xeaa127fa);
    c = HH(c, d, a, b, x[k + 3], S33, 0xd4ef3085);
    b = HH(b, c, d, a, x[k + 6], S34, 0x4881d05);
    a = HH(a, b, c, d, x[k + 9], S31, 0xd9d4d039);
    d = HH(d, a, b, c, x[k + 12], S32, 0xe6db99e5);
    c = HH(c, d, a, b, x[k + 15], S33, 0x1fa27cf8);
    b = HH(b, c, d, a, x[k + 2], S34, 0xc4ac5665);
    a = II(a, b, c, d, x[k + 0], S41, 0xf4292244);
    d = II(d, a, b, c, x[k + 7], S42, 0x432aff97);
    c = II(c, d, a, b, x[k + 14], S43, 0xab9423a7);
    b = II(b, c, d, a, x[k + 5], S44, 0xfc93a039);
    a = II(a, b, c, d, x[k + 12], S41, 0x655b59c3);
    d = II(d, a, b, c, x[k + 3], S42, 0x8f0ccc92);
    c = II(c, d, a, b, x[k + 10], S43, 0xffeff47d);
    b = II(b, c, d, a, x[k + 1], S44, 0x85845dd1);
    a = II(a, b, c, d, x[k + 8], S41, 0x6fa87e4f);
    d = II(d, a, b, c, x[k + 15], S42, 0xfe2ce6e0);
    c = II(c, d, a, b, x[k + 6], S43, 0xa3014314);
    b = II(b, c, d, a, x[k + 13], S44, 0x4e0811a1);
    a = II(a, b, c, d, x[k + 4], S41, 0xf7537e82);
    d = II(d, a, b, c, x[k + 11], S42, 0xbd3af235);
    c = II(c, d, a, b, x[k + 2], S43, 0x2ad7d2bb);
    b = II(b, c, d, a, x[k + 9], S44, 0xeb86d391);
    a = addUnsigned(a, AA);
    b = addUnsigned(b, BB);
    c = addUnsigned(c, CC);
    d = addUnsigned(d, DD);
  }
  var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
  return tempValue.toLowerCase();
}
export default md5;
複製代碼
  1. 在要使用它的文件裏引入使用:
import md5 from '@/utils/md5';
 md5('要加密的字符串');
複製代碼

十一、拼接key與value生成字符串

  1. key與value生成字符串方法,也許你在配置請求頭時用得上:
export function joinParams(obj) {
  let str = '';
  const keys = Object.keys(obj);
  const values = Object.values(obj);
  keys.forEach((item, index, arr) => {
    str +=
      arr.length - 1 === index
        ? `${item}=${values[index]}`
        : `${item}=${values[index]}&`;
  });
  return str;
}
複製代碼
  1. 在要使用的地方引入使用:
import { randomString, joinParams } from '@/utils';

const key = prk;
const nonce = randomString(4);
const timestamp = new Date().getTime();
joinParams({ key, nonce, timestamp })
複製代碼

十二、生成隨機字符串

  1. 生成隨機字符串
    說明: length 生成隨機字符串的長度, chars 字符集
export function randomString(
  length,
  chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
) {
  let result = '';
  for (let i = length; i > 0; i -= 1)
    result += chars[Math.floor(Math.random() * chars.length)];
  return result;
}
複製代碼
  1. 在要使用的頁面中引入使用:
import { randomString } from '@/utils';
const nonce = randomString(4);
複製代碼

1三、生命週期鉤子

  1. mpvue的生命週期跟vue的同樣,它也結合了小程序的生命週期,能夠直接使用,可是mpvue的生命週期鉤子在小程序頁面加載進來時只會執行一次,就是說在頁面切換從新渲染時是不會再執行了的,若是須要每當頁面打開都須要執行的話,要使用小程序的鉤子,注意如下幾點應該夠用了:
    (1)、 只會執行一次的鉤子:created、mounted、onLoad
    (2)、 頁面每次進來都會執行的鉤子:onShow、onHide
  2. 其中比較經常使用的有:
    (1)、頁面進來只要獲取一次數據時能夠用: onLoad
    (2)、頁面進來每次都要獲取數據時能夠用: onShow
  3. 具體能夠本身在頁面中打印檢測執行次數;
  4. 我的建議:
    由於mpvue在頁面切換時data裏面的數據不會自動清除,每一次切換數據狀態都會保留;因此獲取後端數據渲染頁面用onLoad 鉤子獲取一次就行了,否則若是使用onShow的話,頁面每次切換都要去從新獲取數據再渲染,頁面會出現重渲染閃爍;
    數據的獲取咱們能夠這樣作:
    (1)、用onLoad首次獲取數據進行頁面渲染;
    (2)、使用下拉刷新或者根據業務須要切換列表時去從新獲取數據;
    (3)、這樣的話頁面切換時就不用去請求數據,不會形成給人感受好卡,又會閃;

1四、頁面數據清除

  1. mpvue對頁面的數據狀態在頁面切換時是不會自動清除的,也就是在頁面切換後數據狀態不會像vue同樣清除,依然存在的,若是業務需求要清除頁面數據狀態的話,能夠在頁面hide或頁面打開時清除數據狀態:
    方法:
Object.assign(this.$data, this.$options.data());
複製代碼
  1. 例:
onShow(){
        Object.assign(this.$data, this.$options.data());
    }
    onHide(){
        Object.assign(this.$data, this.$options.data());
    }  
複製代碼

1五、檢測用戶是否受權、白名單

  1. 小程序打開後,根據各個項目的需求不一樣,第一步可能就是要檢測用戶是否已經受權,若是已經受權,就去拿token,而後跳轉到首頁;若是沒受權,就直接去受權頁面;檢測小程序是否受權使用:wx.checkSession()
    官網: developers.weixin.qq.com/miniprogram…
  2. 此方法能夠在 app.vue頁面的created鉤子中調用,若是進入成功回調,說明登陸態沒有失效,處於受權狀態,若是進入fail,說明登陸態失效,這時能夠直接跳轉到登陸頁面:
wx.checkSession({
        success: () => {
            console.log('受權狀態,能夠去獲取token,若是沒有token,說明沒有登陸,仍是要去受權登陸 ')
        },
        fail: () => {
            console.log('沒有受權,能夠跳轉到登陸頁面')
        }
    })
複製代碼
  1. 配置頁面白名單:
    有時候,可能有幾個頁面是不用受權登陸就能夠進去的,這時咱們能夠在app.vue頁面檢測受權登陸態時去作判斷;
    具體方法能夠這樣:
    (1). 在單獨文件夾裏配個方法,方便統一管理,注意:安卓與IOS獲取回來的路徑不同,而後在app.vue頁面引入使用:
//  注意:安卓與IOS獲取回來的路徑不同,在使用mp-vue時
   //   在安卓中
    const list = [
      'pages/subPackages/cardDetail/main',
      'pages/subPackages/invitationRegister/main',
    ];
   
   //   在IOS中, 在頭部多一個"/"
   
     const list = [
      '/pages/subPackages/cardDetail/main',
      '/pages/subPackages/invitationRegister/main',
    ];
    //  因此引用時要作一下判斷系統的判斷,這裏就不詳細講了
    
    export function permission(val, callback) {
      if (list.indexOf(val) === -1) {
        callback();
      }
    }
複製代碼
//  在app.vue頁面中
    import { permission } from '@/permission/index.js';
    onShow() {
        this.checkLogin();
      },
      methods: {
        checkLogin() {
    //	獲取當前頁面的路徑 this.$root.$mp.appOptions.path;
          const path = this.$root.$mp.appOptions.path;
          permission(path, () => {
            //	執行檢測代碼 
            
               wx.checkSession({
                     success: () => {
                          console.log('受權狀態,能夠去獲取token,若是沒有token,說明沒有登陸,仍是要去受權登陸 ')
                             },
                    fail: () => {
                        console.log('沒有受權,能夠跳轉到登陸頁面')
                             }
                 })
            
          });
        },
      },
複製代碼

1六、受權登陸

  1. 經過上一步的檢測後,這一步進行小程序的受權登陸了;
    官方網址:developers.weixin.qq.com/miniprogram…
  2. 小程序的受權流程有點繁鎖,但仍是要一步一步走:
    1. 經過 wx.login({}) 獲取用戶的code,二次請求獲取用戶信息時要用到
    2. 經過wx.getSetting({})檢測用戶是否受權,若是進入了success說明已受權,若是進入 fail說明未受權,要拉起受權窗口;
    3. 經過wx.getUserInfo({})獲取用戶基本信息跟code一塊兒傳給後臺進行二次請求,前端也能夠作二次請求;
    4. 很重要的一點,要拉起受權窗口,必需要使用小程序的button,且type爲getUserInfo;
    5. 看以下代碼:
    <button
        open-type="getUserInfo"
        @getuserinfo="toAuth"
        class="button_auth">受權登陸</button>
    
            methods:{
            toAuth(){
            let code = '';
            // 一、獲取code
            wx.login({
              success: res => {
                if (res.code) {
                  code = res.code;
                  // 二、獲取判斷用戶是否受權
                  wx.getSetting({
                    success: res1 => {
                      // 用戶已受權,會自動執行此處
                      if (res1.authSetting['scope.userInfo']) {
                        wx.showLoading({
                          title: '受權中...',
                        });
                        // 三、獲取用戶信息
                        wx.getUserInfo({
                          success: res2 => {
                            console.log(res2) //  用戶信息,二次請求解密用的,傳給後臺,前端也能夠作二次請求
                          },
                        });
                      } else {
                        // 用戶沒有受權,須要受權,從新拉起受權
                        wx.authorize({
                          scope: 'scope.userInfo',
                        });
                      }
                    },
                    fail: () => {
                    },
                  });
                }
              },
              fail: () => {
                // console.log(err);
              },
            });
            }
            }
    複製代碼
  3. 將上一步的代碼下接複製過去是能用的了,但筆者爲了老鐵使用mpvue時更方便,已經將此受權封裝了一個庫,名字是: mp-auth-button;全部的受權邏輯都有,你只要去npm/github上下載下來直接引入使用就能夠了,它是一個button組件,你下載下來就是一個button,獲取到有用戶信息會在方法中的參數裏回調給你,上面有寫使用方法;
    github網址:github.com/search?q=mp…
    npm網址:www.npmjs.com/package/mp-…

1七、二次請求獲取session_key解密

  1. 先講一遍受權登陸的流程吧,再來講二次請求:
    1. wx.login獲取到code,在二次請求時要做爲請求參數;
    2. wx.getUserInfo獲取到用戶信息,其中信息包括:
      rawData 不包括敏感信息的原始數據字符串,用於計算簽名
      signature 使用 sha1( rawData + sessionkey ) 獲得字符串
      encryptedData 包括敏感數據在內的完整用戶信息的加密數據
      iv 加密算法的初始向量
      其中encryptedData 是加密後的用戶數據,解密後能夠獲得,解密要用到iv , 及二次請求獲取回來的 session_key,接下來就講二次請求;
    3. 二次請求是官方提供的接口,照着文檔走就能夠了,官方網址:
      developers.weixin.qq.com/miniprogram…
      前端可使用wx.request這個api來請求獲取:
    // 二次驗證獲取successkey/open_id
                    wx.request({
                      url: "https://api.weixin.qq.com/sns/jscode2session",
                      header: { "Content-Type": "application/json" },
                      method: "GET",
                      data: {
                        appid: "",	//	開發平臺上的appid
                        secret: "",	//	開發平臺上的secret
                        js_code: code,	//	第一步獲取到的code
                        grant_type: "authorization_code"	//	這個是官方要求固定的
                      },
                      success: e => {     
                          e.data.session_key  //  session_key就是解密要用到的key
                      }
                    }); 
    複製代碼
    1. 解密看下一步;

1八、 解密用戶信息

  1. 用戶信息解密官方提供了多種編程語言的示例代碼,官方網址:
    developers.weixin.qq.com/miniprogram…
    接下來就一步一步進行解密:
  2. 下載解密包,裏面有案例:
  3. 下載下來後解壓,獲得:
  4. 咱們可使用node,跟js最接近;用vscode打開Node那個文件夾後,能夠看到咱們還要下載一個庫:
  5. 因而就要下載這個庫: npm install crypto --save
  6. 將WXBizDataCrypt.js和demo.js這兩個文件複製到項目中,單獨起個文件夾放;
  7. WXBizDataCrypt.js這個文件不用管,咱們只需在demo.js文件中修改decode.js就能夠了,將encryptedData , iv 傳進去,具體也能夠看官網:
var WXBizDataCrypt = require('./WXBizDataCrypt')
            
            let appId = 'wx168b9fc4343434434'
            // var sessionKey = wx.getStorageSync("openId_key").session_key
            const encryptedData =
            	'CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM'+
            	'QmRzooG2xrDcvSnxIMXFufNstNGTyaGS'+
            	'9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+'+
            	'3hVbJSRgv+4lGOETKUQz6OYStslQ142d'+
            	'NCuabNPGBzlooOmB231qMM85d2/fV6Ch'+
            	'evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6'+
            	'/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw'+
            	'u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn'+
            	'/Hz7saL8xz+W//FRAUid1OksQaQx4CMs'+
            	'8LOddcQhULW4ucetDf96JcR3g0gfRK4P'+
            	'C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB'+
            	'6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns'+
            	'/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd'+
            	'lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV'+
            	'oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG'+
            	'20f0a04COwfneQAGGwd5oa+T8yO5hzuy'+
            	'Db/XcxxmK01EpqOyuxINew=='
            
            // var pc = new WXBizDataCrypt(appId, sessionKey)
            
            // var data = pc.decryptData(encryptedData , iv)
            
            // console.log('解密後 data: ', data)
            
            const decode = (sessionKey,encryptedData,iv) => {
            	let pc = new WXBizDataCrypt(appId, sessionKey)
            	let data = pc.decryptData(encryptedData , iv)
            //	獲取到的用戶信息,能夠存起來
              wx.setStorage({
                key:"openId",
                data:data.openId
              })
              console.log(data);
            }
            export default decode
複製代碼
  1. 在頁面引入使用:
import decode from "@/utils/node_decode/decode.js";
            decode(
                      e.data.session_key,
                      userinfo.encryptedData,
                      userinfo.iv
                    );
複製代碼

1九、圖片保存

  1. 圖片的保存也是須要用戶進行受權的,若是用戶拒絕了再點擊,仍是要再次拉起用戶受權窗口,因此也要用button,具體網址: developers.weixin.qq.com/miniprogram…
  2. 小程序項目中是不太可能放圖片進去的,由於很佔體積,要知道,放在static裏面的圖片也算是主包裏的東西,因此通常圖片都是由後端提供;保存的圖片有兩種:
    1、普通圖片:
    圖片通常由後端返回前端渲染,若是想要保存圖片就要使用到canvas,利用canvas畫布輸出臨時路徑再保存圖片,canvas能夠用樣式將它移出屏幕以外的地方就看不見了:
    HTML:
         <cover-view
         class="text-2" 
        @click="saveQrcode"
        >保存到手機相冊</cover-view>
         <canvas
         canvas-id="saveCanvasId"
         class="canvas-style" 
        style="width:200px;height:200px"
        ></canvas>
        JS:
             data:{
                return{
                     isShowAuthSaveImg: true
                }
             }
       
         methods:
          saveQrcode() {
              if (this.isShowAuthSaveImg) {
                let that = this;
                wx.getImageInfo({
                  src: this.qrCodeSrc,
                  success: e => {
                    const ctx = wx.createCanvasContext("saveCanvasId");
                    ctx.drawImage(e.path, 0, 0, 200, 200);
                    ctx.draw(false, that.drawCallback());
                  }
                });
              } else {
                wx.openSetting({
                  success: e => {
                    if (e.authSetting["scope.writePhotosAlbum"]) {
                      this.isShowAuthSaveImg = true;
                    }
                  }
                });
              }
            },
            drawCallback() {
              setTimeout(() => {
                wx.canvasToTempFilePath({
                  canvasId: "saveCanvasId",
                  fileType: "png",
                  x: 0,
                  y: 0,
                  success: res => {
                    wx.saveImageToPhotosAlbum({
                      filePath: res.tempFilePath,
                      success: e => {
                        this.onShowDownLoadImg = false;
                      },
                      fail: e => {
                        wx.getSetting({
                          success: e => {
                            if (!e.authSetting["scope.writePhotosAlbum"]) {
                              this.isShowAuthSaveImg = false;
                            }
                          }
                        });
                      }
                    });
                  }
                });
              }, 1000);
            },
    複製代碼
    2、圖片內容有動態數據填充:
    1.若是想要保存的圖片是動態數據的,能夠前端寫一個H5頁面給後端,讓後端去填充數據(若是有數據的話),而後由後端將H5生成一個圖片返回,前端用wx.downloadFile將圖片看成文件下載下來;
    2. 還有個問題,若是用戶拒絕了受權,而後又來保存圖片的話,咱們要將open-type設爲 openSetting,才能打開受權頁面,讓用戶去打開保存圖片的受權;可是若是將open-type設爲 openSetting,那麼每一次用戶點擊保存圖片按鈕時,都會打開受權頁面,這樣是不能夠的,因此咱們要在用戶點擊按鈕前,能夠在onShow裏將open-type設爲空;
    3. 看代碼:
    HTML:
            <button
                       class="picture_share"
                       :open-type="openTypebt"
                       @click="pictureShare"
                       plain="true"
                     >圖片分享</button>
           JS:
             data:{
                   retun{
                       openTypebt: '',
                   }
                },
           onShow() {
               wx.getSetting({
                 success: res => {
                   if (res.authSetting['scope.writePhotosAlbum']) {
                     this.openTypebt = '';
                   }
                 },
               });
           },
           methods:{
            pictureShare() {
                 wx.showLoading({
                   title: '圖片保存中...',
                 });
                 wx.downloadFile({   //	文件下載到本地    
                   url: `${baseUrl}/view/screenShot?url=${
                     this.hunterInfoData.view_url
                   }&with=540&height=1350`, // 圖片在後端的地址
                   header: headers,	//	後端要求的請求頭
                   success: e => {
                     if (e.statusCode === 500) {
                       wx.hideLoading();
                       $Toast({
                         content: '服務器繁忙,稍候重試',
                         type: 'warning',
                       });
                       return;
                     }
                     wx.saveImageToPhotosAlbum({	//	調用保存圖片方法
                       filePath: e.tempFilePath,	//	圖片的臨時路徑
                       success: () => {
                         wx.hideLoading();
                         $Toast({
                           content: '圖片保存成功',
                           type: 'success',
                         });
                       },
                       fail: () => {	//	用戶拒絕,在這個回調中將type設爲
                        //    openSetting,下次再點時調起受權								    
                         wx.hideLoading();
                         wx.getSetting({
                           success: res => {
                             if (!res.authSetting['scope.writePhotosAlbum']) {
                               this.openTypebt = 'openSetting';
                             }
                           },
                         });
                       },
                     });
                   },
                 });
               },
           }
    
    複製代碼

20、打開一個H5頁面

  1. 小程序要打開小程序之外的頁面可使用自帶的web-view,具體咱們能夠新建一個頁面,用戶點擊時跳轉到此頁面,而後將連接帶過去給web-view,
    網址: developers.weixin.qq.com/miniprogram…
    參考代碼 :
    <template>
              <div class="web_view">
                <web-view :src="url"></web-view>
              </div>
            </template>
            <script>
            export default {
              name: 'WebView',
              data() {
                return {
                  url: '',
                };
              },
              onShow() {
                this.setTitle();
              },
              methods: {
                setTitle() {
                  this.url = this.$root.$mp.query.url;
                  wx.setNavigationBarTitle({  //  動態設置標題
                    title: this.$root.$mp.query.title,
                  });
                },
              },
            };
            </script>
            <style lang="less">
            </style>
    複製代碼

2一、去除button默認邊框

  1. 在使用了受權按鈕button後,它有個默認的邊框,通常狀況是不符合項目樣式的,能夠在樣式中經過設置僞類去除:
    button::after {
              border-radius: none;
              border: none;
            }
    複製代碼

2二、動態設置頁面標題

  1. 頁面標題欄除了在app.json設置外,還能夠在頁面中動態更改的,使用api:
    wx.setNavigationBarTitle({
            title: '標題欄',
          });
    複製代碼

2三、綁定style

  1. mpvue不支持style綁定一個對象,若是想要這樣是不行的:
    <div :style="styleObj"></div>
            data:{
                return{
                     styleObj:{
                         color: '#fff'
                       }
                    }
                }
    複製代碼
    不過咱們可能經過computed將對象轉換成字符串就能夠解決問題:
    <div :style="btnStyle"></div>
                data:{
                    return{
                         style: {
                      width: '690rpx',
                      height: '88rpx',
                      'background-color': '#09bb07',
                      'border-radius': '10rpx',
                      'line-height': '88rpx',
                      'text-align': 'center',
                      color: '#ffffff',
                      'font-size': '36rpx',
                      margin: '57rpx auto',   
                         }, 
                     }
                  }
          computed:{
            btnStyle(){
              let s = ''
              let arr = []
              for(let i in this.style){
                      arr.push(i+':'+this.style[i]);
                  }
                  s = arr.join(';')
                  return  s
            }
          }
    
    複製代碼

2四、識別二維碼打開小程序

  1. 此功能是在微信中長按圖片識別圖片中的二維碼打開一個小程序,固然要在開發平臺上去配置打開的連接,這裏主要討論前端打開後獲取二維碼上的參數;注意了,它只能在體驗版以上才能夠實現這個功能,在開發版中是沒法調試的,因此咱們能夠將代碼發佈到體驗版中,而後識別二維碼打開小程序後只能在手機上的調試工具中打印二維碼上獲取到的參數,參數能夠在onLoad的參數中獲取,在q對象裏面,拿到後要用 decodeURIComponent() 方法進行解析出來;
    具體配置及獲取參考網址:
    developers.weixin.qq.com/miniprogram…
    參考代碼:
onLoad(options) {
         // options 中的 scene 須要使用 decodeURIComponent 
         // 才能獲取到生成二維碼時傳入的 scene
        Object.assign(this.$data, this.$options.data());
        if (JSON.stringify(options) !== '{}') {
          const scene = decodeURIComponent(options.q);
          console.log(scene)
         //	截取參數
          this.code = scene.substring(scene.indexOf('code=') + 5);
        }
      },
複製代碼

2五、使用echarts圖表

使用圖表,必然會想到百度的echarts,但它的體積驚人,嚇得趕忙喝了兩口水壓壓驚;不可能將整個包下載下來使用,隨便都超過2M沒法打包,咱們能夠到echarts的官網上去定製本身要用到的,並且要壓縮版的,而後由於咱們使用mpvue,因此這裏能夠引入mpvue-echarts來開發,下面就來說下如何使用: 具體步驟:

  1. 下載mpvue-echarts,網址:www.npmjs.com/package/mpv…
    npm install mpvue-charts --save
    複製代碼
  2. 到Echarts官網定製下載要使用到的圖表,網址:echarts.baidu.com/builder.htm…
    1. 選擇要使用的圖表:
    2. 選擇要使用到的圖片上的組件,若是用不到能夠不下載
    3. 下載要壓縮:
    4. 點擊下載,而後下載中:
    5. 將下載包複製到項目的static文件夾中
  3. 在頁面中引入echarts及mpvue-echarts
    import mpvueEcharts from 'mpvue-echarts';
    import * as echarts from '../../../static/echarts.min .js';
    複製代碼
    注意:echarts的路徑根據實際的文件位置引入;
  4. 註冊組件:
    components: {
          mpvueEcharts
            },
    複製代碼
  5. 在html中使用:
    <mpvue-echarts 
          :echarts="echarts" 
          :on-init="initChart" ></mpvue-echarts>
    複製代碼
  6. 在data中:
    data() {
             return {
              echarts,	//	echarts定製組件
              // 橫軸數據
              AxisXData: [],
              // 圖表動態數據
              echartsData: [],
            };
         }
    
    複製代碼
  7. 在methods中:
    methods:{
          // 圖表
            initChart(canvas) {
              let chart = null;
        //	動態獲取圖表寬度
              const echartWidth = 700 / 750 * wx.getSystemInfoSync().windowWidth;
        //	動態獲取圖表高度
              const echartHeight = 540 / 750 * wx.getSystemInfoSync().windowWidth;
              chart = echarts.init(canvas, null, {
                width: echartWidth,
                height: echartHeight,
              });
              canvas.setChart(chart);
              const option = {
        //	橫軸配置
                xAxis: {
                  type: 'category',
                  data: this.AxisXData,
                  axisLabel: {
                    interval: 0,
                    fontSize: 12,
                  },
                  splitLine: {
                    show: true,
                    lineStyle: {
                      color: '#f2f2f2',
                    },
                  },
                  axisTick: {
                    show: false,
                  },
                  axisLine: {
                    lineStyle: {
                      color: '#3488ea',
                      width: 2,
                    },
                  },
                },
        //	縱軸配置
                yAxis: {
                  // 縱軸標尺固定
                  type: 'value',
                  scale: true,
                  name: '簡歷數',
                  nameGap: 15,
                  max: 100,
                  min: 0,
                  boundaryGap: [0.2, 0.2],
                  splitLine: {
                    show: true,
                    lineStyle: {
                      color: '#f2f2f2',
                    },
                  },
                  axisTick: {
                    show: false,
                  },
                  axisLine: {
                    lineStyle: {
                      color: '#3488ea',
                      width: 2,
                    },
                  },
                },
        //	圖表類型及填充數據
                series: [
                  {
                    data: [{value:20},{value:40}],
                    type: 'bar',
                    itemStyle: {
                      color: '#3488ea',
                    },
                    barWidth: 20,
                  },
                ],
                grid: {
                  left: '6%',
                  right: '0',
                  // bottom: '0',
                  top: '30',
                  containLabel: true,
                },
              };
              chart.setOption(option);
        
              return chart; // 返回 chart 後能夠自動綁定觸摸操做
            },
        }
    複製代碼
  8. 你只要照着以上步驟應該能夠搞定,不過具體配置跟echarts官網上的如出一轍的,mpvue-echarts只是一個殼而已,具體樣式配置及series的設置能夠按照echarts官網的案例來;
    具體網址: echarts.baidu.com/examples/

2六、圖片路徑問題

  1. 當圖片路徑放到data裏做爲變量去綁定時,可能會出現圖片不出來的狀況,能夠這樣解決試下:
    1、將路徑改成絕對路徑或用require引入:
    data(){
           return{
           img_1:  "/static/images/xxx.png",
            img_2: require('../../../static/images/xxx.png')
          }
         }
    複製代碼
    2、到webpack.base.conf.js配置裏將圖片限制大小改大:
    {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 1000000000,			//	這裏改大點
              name: utils.assetsPath('img/[name].[ext]'),
            },
         },
    複製代碼

2七、this指向問題

  1. 關於這個this是說使用箭頭函數的問題,老掉牙了,有些老鐵會在使用了小程序的api後,在成功函數裏用了箭頭會形成this丟失,可使用匿名函數來代替:
    wx.showLoading({
            success: () => {	//	這樣就能夠了
            this.data = 123
            }
            })
    複製代碼

2八、頁面下拉刷新

  1. 配置小程序頁面下拉刷新請求接口,在頁面的json文件中配置:
    {
              "enablePullDownRefresh": true,
              "backgroundTextStyle": "dark",   // 配置小圓點顏色
            }
    複製代碼
  2. 在頁面中調用此鉤子,與onShow同級
    onPullDownRefresh() {
            wx.showLoading({
              title: '加載中...',
            });
            //	請求數據
          },
    複製代碼
  3. 在請求數據完成後要把這個下拉的調用中止掉,否則在時間內會一直在下拉狀態,調用此方法中止:
    wx.stopPullDownRefresh();
    複製代碼

2九、使用scroll-view組件

  1. scroll-view這裏主要講縱向滾動時的使用及注意點:
    1. 頁面切換時,想要回到頂部,能夠設 :scroll-top="0"
    2. 要給scroll-view設一個固定的高度,這裏有個問題,就是小程序雖然支持vw,vh這個單位自適應,但mpvue一直使用rpx,因此給scroll-view設vh這個自適應單位是不可行的,並且每一款手機的屏幕高度都不同,要保證scroll-view與其它元素加起來恰好是一整屏,咱們能夠這樣作:
      1. 經過以下方法獲取到手機屏幕的總高度:
        wx.getSystemInfoSync().windowHeight 
        複製代碼
      2. 再經過下面這個api獲取頁面中其它元素的高度,而後在rests 中能夠拿到所選元素的高度,它是個數組,其中val參數是其它元素的類名,id也能夠,其它元素是指頁面中除了scroll-view之外的元素,也就是總高度減去的其它元素高度:
        wx.createSelectorQuery().selectAll(val).boundingClientRect(rects =>{
                console.log(rects)  // rects是所選的元素屬性,包括寬、高等等
            })	
        複製代碼
      3. 遍歷出來後獲得的都是px的單位,因此咱們能夠將總高度減去其它元素高度的和,剩下就是scroll-view的高度了,直接傳進去就能夠了;
      4. 計算scroll-view的高度應該是在其它元素都渲染完後再去計算,否則會不許確,特別是若是其它元素上的內容是有異步請求數據填充的,數據請求回來後才顯示的,那這個計算最好是放在請求數據成功回來後再去計算;
    3. 代碼奉獻:
      1. 計算高度的方法,我是放在了一個公共方法文件裏導出,在callback回調裏把計算出來的值傳出去,下面的代碼直接拿去用就能夠了:
        export function scrollHeight(val, callback) {
              let clientHeight = 0;
              // 獲取屏幕高度與寬度
              try {
                const res = wx.getSystemInfoSync();
                clientHeight = res.windowHeight;
              } catch (e) {
                // Do something when catch error
              }
              setTimeout(() => {
                let allHeight = 0;
                wx
                  .createSelectorQuery()
                  .selectAll(val)
                  .boundingClientRect(rects => {
                    rects.forEach(rect => {
                      allHeight += rect.height;
                    });
                    if (allHeight) {
                      callback(`${clientHeight - allHeight}px`);
                    } else {
                      wx
                        .createSelectorQuery()
                        .selectAll(val)
                        .boundingClientRect(res => {
                          res.forEach(rec => {
                            allHeight += rec.height;
                          });
                          callback(`${clientHeight - allHeight}px`);
                        });
                    }
                  })
                  .exec();
              }, 400);
            }
        複製代碼
      2. 在使用的頁面裏引入使用:
        import { scrollHeight } from '@/你的文件名';
                data(){
                return {
                height: 0
                }
                }
                 methods:{
                // 動態獲取sroll-view高度
                    getScrollHeight() {
                      scrollHeight('.carousel_wrap,.send_tab',this.scrollCallBack);
                    },
                    scrollCallBack(val) {
                      this.height = val;
                    },
                }
        複製代碼
      3. 注意,元素的類名是個字符串,多個能夠用逗號隔開,如 ' .abc,.bcd,.efg'
      4. 在html中, @scrolltolower是下拉觸底的事件,能夠用它去觸發再次請求數據:
        <scroll-view
              @scrolltolower="觸底的事件,用來請求下一頁數據"
              scroll-y
              :style="{height:scrollHeight,overFlow:'hidden'}"
              v-if="height"
              scroll-top="0"
                >
                 <ul>
                <li></li>
                </ul>
             </scroll-view>
        複製代碼
      5. 觸底事件要注意:
        1. 應該作個開關,防止用戶狂拉不斷請求,應該 是數據請求回來後才把開關打開再次請求;
        2. 當沒有數據返回時,也應該作個開關,禁止下 拉觸發請求,提示沒有數據便可;

30、分享頁面

  1. 分享調用到的小程度api用 onShareAppMessage() ,與onShow同級:
    網址:developers.weixin.qq.com/miniprogram…
    <button open-type="share"></button>
         onShareAppMessage() {
            return {
              title: '分享頁面名字',
              path: `分享頁面路徑`, // 如 '/pages/xxx/main' 
              imageUrl: '圖片路徑,不能網絡圖片', // 如:'/static/images/xxx.jpg'
            };
          },
    複製代碼
  2. 只要設了onShareAppMessage,小程序右上角點擊就會出現轉發按鈕

3一、formid收集

  1. 後端可能會要求你在提交表單後收集formid給後端,formid會在from提交表單後在回調參數中返回,在接口沒有配置到開發平臺前,是拿不到formid的;
  2. 代碼奉獻:
    //	其中 report-submit="true" 表示是否返回formid
             <form 
              report-submit="true" 
              @submit="bindSubmit">
             //	 表單
            </form>
        methods:{
          bindSubmit(e) {
           	 console.log( e.mp.detail.formId); 
        		  },
            }
    複製代碼

3二、複製到剪切板

  1. 複製內容到剪切板很是簡單;
    具體網址:developers.weixin.qq.com/miniprogram…
  2. 調用apiwx.setClipboardData()進行復制;
  3. 調用 wx.getClipboardData()進行獲取;
  4. 具體能夠參照文檔;

3三、圖片預覽

  1. 圖片預覽調用 api: wx.previewImage()
  2. 注意圖片預覽是打開了一個新的頁面,關閉預覽時原來的頁面至關於從新打開,會調用onShow鉤子;

3四、圖片高度自適應

  1. 若是咱們設置了圖片的寬度,高度想要它自適應的話,能夠這樣作: 在img標籤內 加上 mode="widthFix" 便可:
    <img src="" mode="widthFix" width="200"/>
    複製代碼

3五、彈窗阻止頁面滾動

  1. 有時咱們會本身寫一個彈框,本身定義一個遮罩層,但頁面還能夠觸發滾動,咱們可使用這個去阻止頁面滾動:
    給彈框的最外層元素加上這個屬性 catchtouchmove,請在真機上預覽,調試工具上是看不出效果的;

3六、生成二維碼

  1. mpvue開發小程序生成二維碼,能夠借用 weapp-qrcode 這個插件,
    具體網址:www.npmjs.com/package/wea…
    這個是npm上的網址,具體配置也在裏面
  2. 使用方法:
    1. 下載:
      npm install weapp-qrcode --save
      複製代碼
    2. 在要使用到的頁面引入 :
      import drawQrcode from "weapp-qrcode";
          HTML:
          <canvas canvas-id="saveCanvasId" ></canvas>
          methods:{
          getQrcode(){
            drawQrcode({
                width: width,
                height: height,
                canvasId: canvasId,
                text: text,
                correctLevel:3,
                typeNumber:8,
                callback: () => {
                  // 將畫布中的元素轉成圖片臨時路徑
                       wx.canvasToTempFilePath({
                       canvasId: canvasId,
                         fileType:"png",
                            x:0,
                            y:0,
              success(res) {
                     console.log(res);	//	獲得圖片路徑,能夠展現
                    }
                  })
                }
              })
          }
          }
      複製代碼

3七、使用iview-weapp插件庫

  1. mpvue若是想要使用ui庫的話,可使用ivew-weapp;
    npm網址:www.npmjs.com/package/ivi…
    官網 :weapp.iviewui.com/docs/guide/…
  2. 具體使用細節能夠參考官網上的使用方式,但它是下載後是要將整個包複製到static文件下,而後做爲靜態資源引入使用的,具體使用這裏演示一下:
    1. 下載 :
      npm install iview-weapp --save-dev
      複製代碼
    2. 到node_modules文件裏面將它dist裏面的文件複製到static文件裏,把整個都複製過去,由於有些文件是搭配使用的,想要精簡,那就要看着文檔來選擇複製使用:
    3. 在頁面中能夠根據官網的說明來使用,這裏就拿toast 提 示框來舉例說明使用:
      1. 在頁面的json文件中配置:
      2. 在頁面中HTML中寫上元素:
      <div>
               <i-toast id="toast"/>
          </div>
          
      複製代碼
      1. 在js中引入,路徑使用相對路徑:
      import { $Toast } from '../../../static/iview/base/index.js';
      複製代碼
      1. 調用:
      $Toast({
            content: '此內容必填',
            type: 'warning',
          });
      複製代碼
相關文章
相關標籤/搜索