一次微信小程序的快速開發體驗

原由

事情是這樣的javascript

一天早上組裏還早激烈的討論某個項目的可用性和發展前景,忽然老大說了句,能不能作個小程序的版本呢?而後你們紛紛討論起來,有反對有支持,我就說了一句,剛出來的時候搞過一會。。。而後就把我推出來了(日了狗了~~)html

這個項目大概一個星期以後就要推出去了,換句話說,我要一個星期內搞個小程序的版本出來,寶寶有點慌了~~vue

不過既然接手了仍是要好好作的,首先的,徹底本身搞確定是來不及,項目的模塊絕對要複用起來,思索下大概有3點須要搞java

  • HTMLnode

  • CSSgit

  • javascript module程序員

CSS

其中CSS在小程序的叫作WXSS,基本和CSS語法相似了,也就須要將標籤選擇器改了,好比github

table{
    //XXX
}
//改爲
.table{

}

還有就是WXSS的尺寸單位比較推薦使用rpx,可是這裏仍是繼續使用px,固然在響應式方面還須要本身改改,工程量不是很大json

JS

對於JS方面就比較棘手了一點,惟一慶幸的是,原項目是用vue來作框架搭建的,仔細觀察下小程序框架的語法結構,發現其實和vue很相似,都具有生命週期和各類事件綁定等等,因此在總體JS結構上面大概有幾點須要修改canvas

  • 生命週期函數

created: function () {
    //xx
  }

  //改爲
  onLoad: function() {

  }
  • 數據綁定

this.container = '';
//改爲
this.setData({
    "container": ''
});

剩下的就是模塊的引用,小程序自己也支持ES6語法,但仍是有缺陷,好比不支持promise,能夠經過引入相應的polyfill 來解決,還能順便讓小程序自己的API也應用上promise

//util.js
import Promise from './bluebird.min';
export const wxPromise = function(fn) {
  return function (obj = {}) {
    return new Promise((resolve, reject) => {
      obj.success = function(res) {
        resolve(res);
      }

      obj.fail = function(err) {
        reject(err);
      }

      fn(obj)
    })
  }
}

能夠在須要調用的地方引入,或者直接在APP.js裏面封裝原API,而後掛載在全局上面

import {wxPromise} from '../../utils/util';
let login = wxPromise(wx.login);
let getUserInfo = wxPromise(wx.getUserInfo);
login()
    .then((res) => {
        console.log(res);
        return getUserInfo();
    })
    .then((res) => {
        console.log(res);
    })
    .catch((res) => {
        console.log(res);
    })

原項目裏面的模塊還調用了window對象的屬性,好比localstorage、innerWidth、innerHeight等等,在開發工具裏面輸出console.log(window)直接甩了我一個大大undefined,呵呵,都快崩潰了,後來想一想,也不是徹底沒有辦法,小程序也有相似的API來實現這些方法和屬性,我要作的就是造一個window對象給它就能夠了,老樣子,直接掛載全局就行

App({
        window: {},
        location: {
            href: 'http://localhost/index.html?clear'
        },
        onLaunch: function() {
            let _this = this;
            getSystemInfo()
                .then((res)=>{
                    _this.window.innerWidth = res.windowWidth;
                    _this.window.innerHeight = res.windowHeight;
                })
            _this.window.localStorage = {};
            _this.window.localStorage.setItem = wx.setStorageSync;
            _this.window.localStorage.getItem = wx.getStorageSync;
            _this.window.localStorage.clear = wx.removeStorageSync;
        }
    })
//注入到頁面或者模塊
let {window, location} = app;

HTML

最後一個難題就是HTML了,首先HTML直接套在WXML上面是行不通的,結果是能夠編譯顯示出來,可是徹底失去了HTML各個標籤的意義,好比div塊級標籤所具有的屬性都不存在了,固然你能夠經過WXSS添加屬性來兼容,好比

div, p {
    display:blcok
}

我我的並不贊同這種作法,由於在HTML中img、canvas等等並無要求閉合標籤,可是WXML是嚴格要求每一個標籤都要有閉合,就是說你想經過添加WXSS屬性來兼容的話,首先要手動加img和canvas的閉合標籤(在小程序中img標籤應該是image,否則仍是沒法顯示圖片),其次就是怕官方下次更新迭代忽然加入div這個組件,而後又要改版,煩~~
那麼惟一的出路就是將HTML轉成符合小程序的WXML出來,做爲一個程序員,手動改也太掉價了。。。直接上工具,google查下,發現網上也有相似的工具出來,工具的轉換原理是這樣的話,首先HTML先轉換成json對象,而後注入到模版,由模版生成。
可是有2個問題
一、轉換出來的WXML是依賴模版渲染的,首先小程序的模版是不支持遞歸調用的,就是說,假如你的標籤有6層嵌套的話,那麼你須要複製6份模版出來,而後tmp1嵌套tmp2...temp6,這樣的話你只能祈禱工具帶來的模版有嵌套了足夠多。
二、沒法實現數據綁定,好比

<div>{{text}}</div>
//轉換後原樣輸出了{{text}}
<view>{{text}}</view>

既然模版輸出這條路走不通,那就只能藉助node動態的輸出WXML,思路和上面差很少,也是HTML生成json dom,而後遞歸渲染wxml節點,最後輸出一份wxml文件,工具的實如今這裏,細節就很少說了,目前尚未作canvas、audio、video標籤的轉換,有BUG的話直接提issue,最後求star

總結

沒事別BB

相關文章
相關標籤/搜索