众所周知,微信推出小程序以来,可谓火遍大江南北,就像当前互联网兴起时,大家忙着抢域名与开私人博客一样。小程序之所以这么火,是因为微信拥有庞大的用户量,并且腾讯帮你搞定后台问题及众多功能问题(如分享,支付,视频播放,文件上传),相当于你一个人也能做一个公司的事情。在手机上,每个人不可能装超过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!