1. 程式人生 > >微信H5開發(一)

微信H5開發(一)

H5開發,一般是指移動端的頁面開發。移動端可分為app和普通瀏覽頁面。從嵌入的環境來歸類:可以分為app、微信H5及手機瀏覽器裡面開啟的頁面。
以前粗略的涉略過h5開發的一些知識,感覺H5並不是很難。在這半年內,接手並完成了兩個微信H5專案(一期)的過程中,發覺h5開發過程中需要注意的細節有很多,碰到的相容問題也有一些。在這裡我先總結下,H5專案的一些思路及碰到的難點和解決方法。
在剛接到H5專案時,因為前端有很多框架,所有需要先確定使用什麼技術。對於用vue和還是react,考慮到專案的規劃時間和對框架的熟練度。這兩個H5的專案我都用react來完成。
webpack+react+react-dom+react-route+redux+axios +Java+mysql ,一個完整的技術棧。
比較基礎的前端開發環境搭建(webpack+react…),各位可以參考我前面寫的文章。由於webpack的技術更新及部分程式碼優化,基礎配置裡面有些東西需要稍微調整下。
比如:
1. nodeJs 的指令更改
以前安裝一個模組的指令:

npm install url-loader file-loader --save-dev

現在更改為:

npm install url-loader file-loader -S -D
  1. Happypack 外掛將不再支援cache
new Happypack({
    id:"happybabel",
    loaders:['babel-loader'],
    threadPool:happypackThreadPool,
    cache:true,   **//需要刪除這句cache的配置**
    verbose:true
})
  1. 在webpack plugins 裡面新增配置使用(生產)環境的外掛
new webpack.DefinePlugin({
  "process.env": { 
     NODE_ENV: JSON.stringify("production") 
   }
})

4.為了降低最後打包的壓縮體積,把devtool:’eval-soure-map’ 改成 devtool:false。
配置css-loader將css檔案進行壓縮:

 {
    test:/\.css$/,        
    use:ExtractTextPlugin.extract({//使用ExtractTextPlugin 外掛
        fallback:"style-loader"
,//用於開發環境 use:[{loader:"css-loader",options:{minimize:true}},"postcss-loader"] }), }
  redux 以前的程式碼:
   const reducer = (state = defaultState, action) => {     
    switch (action.type) {//通過action的返回值來選擇更新哪個state的狀態
        case 'AlterMain':
            return  Object.assign({},state,{ mainText:action.payload});
        case 'AlterTopic':
            return  Object.assign({},state,{ topicText:action.payload});
        default:
            return state;
    }
};
精簡為:
const reducer = (state = defaultState, action) => {
    if (action.type.indexOf("@@redux") != -1) {
        return state;
    } else {
        var ob = {};
        ob[action.type] = action.payload;
        return Object.assign({}, state, ob);
    }
};
action 舊程式碼:
const actions = {
 changeText:function(num){
     console.log("呼叫actions");
      switch(num){
      case 1:
      return {type:'AlterMain',payload:"mainContainer had been changed"};
      case 2:
       return {type:'AlterTopic',payload:"topicContainer had been changed"};
       default:
       return action;
   }
}
};
export default actions;

優化為:
const actions = {
 changeInfo:(infotype,string)=>{   
    if(infotype == ""){
      return action;
    }else{
      return {type:infotype,payload:string};
    }
},
};
export default actions;

現在轉入主要內容。
h5 開發,第一個面臨的難題是畫素問題,移動端的畫素有物理畫素及邏輯畫素的說法,同一個畫素在不同的手機,顯示的大小都不一致。而且PC端瀏覽器的最小畫素為1px,但手機端卻可以顯示出0.5px甚至可能更小。
一、這個畫素問題要怎麼解決?
h5 裡面有個視口(viewport)這個標籤。這個視口標籤就設定邏輯畫素和物理畫素的比值。initial-scale=1表示1倍的關係。user-scalabe=no,表示不允許使用者更改當前頁面的比例。

根據網上推薦的方案,通過 docEl.clientWidth 獲取移動端網頁的可見區域的寬度,把可見區域分成320小分,然後規定根字型佔10(pc端預設字號為10px)小分,單位取px。

(function (doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
    recalc = function () {
        var clientWidth = docEl.clientWidth;
        if (!clientWidth) return;
        docEl.style.fontSize = 10 * (clientWidth / 320) + 'px';       
    }; 
    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

上面這個js,在react的app..js 引入。當代碼成功執行,可以看到根字型的大小。
這裡寫圖片描述

當根字型確定下來之後,後面所有設計到尺寸的地方都以跟父元素的百分比或者用以根字型的比例關係設定(以rem)。如果用rem做單位,需要所有指定尺寸的地方都需要 用UI圖紙標註的尺寸除以根字型大小。如果每次尺寸都用人工轉換,這個將會是個很浪費時間一件事。為了解決這個費力不討好的問題,我啟用了less。less只需要在整個文件前面設定一個根字型大小的變數(比如:@rootFontSize:23.4375),後面所有涉及到尺寸的地方直接除以這個變數就好。例子:設定div 的高度 height:44rem/@rootFontSize。 這樣div設定的高度就等同於圖紙(設計尺寸比例1:1的關係)上的44px。

二、 Object.assign() 相容問題
以前碰到一個這樣的現象:引入redux成功後,專案在pc端谷歌 瀏覽器上除錯頁面可以正常渲染。但如果在安卓模擬機和實體手機的環境下,頁面就變成了空白。後來經過排查,發現object.assign 存在移動端相容性問題。
這個相容問題怎麼解決?
網上有現成的方案:引入polyfill 檔案,重新定義object.assign。

 if (typeof Object.assign != 'function') {
    // Must be writable: true, enumerable: false, configurable: true
    Object.defineProperty(Object, "assign", {
      value: function assign(target, varArgs) { // .length of function is 2
        'use strict';
        if (target == null) { // TypeError if undefined or null
          throw new TypeError('Cannot convert undefined or null to object');
        }

        var to = Object(target);

        for (var index = 1; index < arguments.length; index++) {
          var nextSource = arguments[index];

          if (nextSource != null) { // Skip over if undefined or null
            for (var nextKey in nextSource) {
              // Avoid bugs when hasOwnProperty is shadowed
              if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                to[nextKey] = nextSource[nextKey];
              }
            }
          }
        }
        return to;
      },
      writable: true,
      configurable: true
    });
  }

這篇就先到這。解決了移動端剛開始碰到的兩個問題,處理好這個兩個問題,移動端頁面和pc頁面開發的區別就不會很大了。
下一篇講微信相關的知識及使用微信模組碰到的一些棘手的問題。