眾所周知,微信推出小程序以來,可謂火遍大江南北,就像當前互聯網興起時,大家忙着搶域名與開私人博客一樣。小程序之所以這么火,是因為微信擁有龐大的用戶量,並且騰訊幫你搞定后台問題及眾多功能問題(如分享,支付,視頻播放,文件上傳),相當於你一個人也能做一個公司的事情。在手機上,每個人不可能裝超過100個以上的APP,因此這么多小公司想生存下來很不容易,但傍上微信這個大平台,個人也能出一個有上千萬人玩的爆款游戲,也能搞一些小商城,避開淘寶京東的鋒芒。對於大公司,這也是一個賺錢導流的新途徑。相信今后,小程序會越來越火。
但是,小程序對開發人員來說,則不怎么給力。它的API非常原始,沒有類繼承,npm支持滯后,不能使用CSS預處理器。於是市面上出現各種轉譯框架。轉譯框架與我們常用的框架不太大一樣,轉譯框架是將我們寫的代碼翻譯成小程序支持的各種文件形式,比如說wxml, wxss。而轉譯框架在編寫業務時,允許我們使用更為流行的框架形式來寫(之所以說形式,因為以vue方式寫,它實際不是跑一個真正的vue,以react方式寫,也不是跑一個真正的react)。由於小程序不存在DOM,因此流行那幾個框架是無法跑在微信中,但可以用它們的仿造品。
轉譯框架的最高目標是統一公司的技術棧,讓以react為技術棧的公司不用再搞vue,為vue為技術棧的公司不用學react。這在招聘與維護上有很大優勢。
目前,市面上的轉譯框架有wepy, mpvue, taro。前兩者是vue風格,使用的是vue1的語法,但還是有這么多vue語法無法支持。taro是京東近半年出品的,react風格,目前還不夠穩定,最大的問題是組件不包含組件。
好了,到本文的主角出場。anu原本是一個迷你React框架,對react16的兼容程度非常高,能跑react-router, react-redux, antd, rematch等等。而anu小程序只是在其上面的一個擴展,為它添加了一個cli及一個新的render.cli用在編譯期,將JSX轉換成wxml等,而miniapp render用在運行期,讓它跑在微信內部。
https://github.com/RubyLouvre/anu/tree/master/packages/cli
由於小程序的限制,一切涉及DOM的API都不能用,即findDOMNode, dangerouslySetInnerHTML及refs.dom。目前也不支持使用render props時,因為wxml里面不能運行函數。其他,都可以正常使用,包括
- 各種生命周期鈎子,頁面組件還有componentDidShow, componentDidHide兩個新鈎子
- div, h1, span, b等html標簽
- 用戶已經用小程序方式寫好的各種組件
- 事件里面可以傳參,多次bind this(這是一個重大特殊,其他轉譯框架做不到)
- 多重循環支持
- es6, es7語法糖支持
- 組件標簽包含組件標簽(solt機制)
- 無狀態組件的支持
- onClick屬性自動映射成bindtap
- React.wx對象擁有原wx對象的所有方法,並且對所有請求接口進行Promise化
11 提供兩個通用別名@components與@react,方便用戶import React與通用組件目錄的內容
說了這么多,我們看一下如何使用。
1.到https://github.com/RubyLouvre/anu 下載anu
git clone https://github.com/RubyLouvre/anu.git
2.進入anu/packages/cli目錄, 執行npm link
命令 (如果之前執行過,需要npm unlink)
3.回到anu目錄,這時可以使用mpreact <projectname>
創建一個小程序項目
4.執行npm start命令,構建工程
5.然后使用微信開發工具,打開<projectname>
下面的dist目錄
作為一個演示項目。去哪兒網模板包含一些簡單的使用演示。大家可以用 vs code打 <projectname>
。src目錄是源碼,dist目錄是最終生成給微信運行的代碼。
根據微信小程序的要求,src 主要分為三大塊, app.js, pages目錄的頁面組件, components目錄的通用組件。
app.js會import所有用到的頁面組件的JS文件
頁面組件的源碼與生成代碼大概如下
import React from '@react';
import Dog from '@components/Dog/index';
class P extends React.Component {
render() {
return (
<div>
<div>類繼承的演示</div>
<Dog age={12} />
</div>
);
}
}
export default P;
會生成兩個文件
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ReactWX = require("../../../../ReactWX");
var _ReactWX2 = _interopRequireDefault(_ReactWX);
var _index = require("../../../../components/Dog/index");
var _index2 = _interopRequireDefault(_index);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
function P() {}
P = _ReactWX2.default.miniCreateClass(
P,
_ReactWX2.default.Component,
{
render: function() {
var h = _ReactWX2.default.createElement;
return h(
"view",
null,
h("view", null, "\u7C7B\u7EE7\u627F\u7684\u6F14\u793A"),
h(_ReactWX2.default.template, {
age: 12,
templatedata: "data09558693",
is: _index2.default
})
);
},
classUid: "c70258"
},
{}
);
Page(_ReactWX2.default.createPage(P, "pages/demo/syntax/extend/index"));
exports.default = P;
wxml
<import src="../../../../components/Dog/index.wxml" />
<view>
<view>類繼承的演示</view>
<template is="Dog" data="{{...data}}" wx:for="{{data09558693}}" wx:for-item="data" wx:for-index="index" wx:key="*this"></template>
</view>
我們再來看一下另一個拼多多商城模板。那是使用sass做預處理器。
由於用到https請求數據,因此需要大家打開右上角進行一個設置
它的全貌如下
第三模板
從這里三個示例來看,anu小程序是能hold住非常復雜的應用。
如果想了解 anu小程序的進度或一些注意事項,大家可以訪問這里
https://github.com/RubyLouvre/anu/issues/133
也歡迎大家試用與提PR!