begonia
v2.3.4
Published
A library for wx-miniprogram development.
Downloads
43
Readme
Begonia 介绍
begonia是一个为微信小程序开发而建立的开源、简单和轻量的开发框架。
具有如下特性:
- 基于代理模式构建小程序App实例、Page实例和Component实例
- 提供属性延迟生效的功能,减少多次调用setData;通过延迟时间在宏观上控制setData提交的频次和数量。
- 自动将Page实例的
data
和Component实例的data
中的属性转换为同名的getter
和setter
(自动提交属性变动),简化使用方式。 - 提供增强模块管理,可以基于begonia扩展功能。并借由模块生命周期细粒度的控制创建小程序Page实例和Component实例的过程。
- 支持npm安装,并符合小程序npm开发部署要求。
微信小程序基础库版本
^2.2.1
快速使用
1. 安装
请在小程序项目的根目录下(即 project.config.js
中的 miniprogramRoot
字段)执行npm
安装:
$ npm install begonia
接下来,我们需要做的,就是使用微信开发者工具中的工具->构建npm命令,对已经安装好的npm模块进行构建。 关于如何使用微信开发者工具构建npm模块,你可以参考官方文档
2. 导入模块
在小程序的app.js
、页面或者自定义组件实例中,导入入口文件:
import BE from 'begonia';
3. 创建实例
然后,就可以通过变量BE
来使用套件的具体功能:
创建根级App
实例
import BE, { APP } from 'begonia';
// 打开debug模式,可以在console面板查看运行时的日志输出
BE.debug = true;
// app.js
BE({
// 将转化为globalData
data() {
return {};
},
onLaunch(options) {},
onShow(options) {},
onHide() {},
onError(msg) {
console.error(msg);
},
onPageNotFound() {
console.error(msg);
},
methods: {
// 自定义方法
myInit() {
this.foo();
},
setUIDatas() {
this.bar();
}
},
methodAres: [
{
// 自定义方法分组
foo() {},
bar() {}
}
]
}, ['myInit', 'setUIDatas'])(APP); // 最后使用app方式渲染
创建页面对象
// /pages/example/example.js
import BE, { PAGE } from 'begonia';
BE({
/**
* 页面的初始数据
*/
data(){
return {
userId: 0
};
},
/**
* 生命周期函数--监听页面加载
* 相当于onLoad
*/
created(options) {
// 使用begonia为实例提供的commit()方法提交属性变动
this.commit('userId', 10);
// 另外一种提交形式
this.commit({
userId: 12
});
// 甚至,还可以这样
this.userId = 14;
},
/**
* 生命周期函数--监听页面初次渲染完成
* 相当于onReady
*/
ready () { },
/**
* 生命周期函数--监听页面显示
*/
onShow () { },
/**
* 生命周期函数--监听页面隐藏
*/
onHide () { },
/**
* 生命周期函数--监听页面卸载
* 相当于onUnload
*/
destroyed () { },
// 自定义方法
methods: {
pageInit() {
this.foo();
},
setUIData() {
this.bar();
}
},
// 函数分组
methodAreas: [
{
foo() {},
bar() {}
}
]
}, ['pageInit', 'setUIData'])(PAGE);
在created
方法中,有3次属性的提交,但是最终会真正采用setData()
改变的只有第三次的提交,框架在内部会舍去前两次的重复提交。
如果您想在提交一次属性变动之后,立即使其生效。可以使用如下形式:
//...
this.commit('userId', 10);
this.validateNow();
//...
通过调用框架赋予实例的validateNow()
方法,会使属性变动立即生效,其本质和直接使用setData
没有区别。当然,为了避免频繁使用setData
提交变动,请谨慎使用validateNow
。确保只在必要时使用它。
创建组件实例
import BE, { COMPONENT } from 'begonia';
BE({
/**
* 组件的属性列表
*/
properties: {
sysId: {
type: Number,
value: 0
}
},
/**
* 组件的初始数据
*/
data(){
return {
userId: 0
};
},
// 相当于lifetimes.created
created() {
// 根据小程序组件的内部机制,不可以在此提交属性变动
},
// 相当于lifetimes.attached
mounted() {
// 使用begonia为实例提供的commit()方法提交属性变动
this.commit('userId', 10);
// 另外一种提交形式
this.commit({
userId: 12
});
// 甚至,还可以这样
this.userId = 14;
},
// 相当于lifetimes.ready
ready() {},
// 相当于lifetimes.detached
destroyed() {},
// 相当于lifetimes.error
error(err) {},
// 相当于pageLifetimes.show
pageShow() {},
// 相当于pageLifetimes.hide
pageHide() {},
// 相当于pageLifetimes.resize
pageResize() {},
/**
* 组件的方法列表
*/
methods: {
comInit() {
this.foo();
}
setUIDatas() {
this.bar();
}
},
methodAreas: [
{
foo() {},
bar() {}
}
]
}, ['comInit', 'setUIDatas'])(COMPONENT);
编排方法队列
你可能注意到上面的例子在使用BE()
时传入了第二个参数,是一个元素为字符串的数组。
这是一个自定义的函数执行队列,可以编排方法的执行顺序。实际则是在特定的方法执行时(App是在onLaunch
执行时,Page在onLoad
执行时,Component是在lifetimes.attached
执行时)。
假设,我们在编码时,会这样调用函数:
Page({
onLoad() {
this.foo();
this.bar();
},
foo() {
},
bar() {
}
});
当我们利用BE()
的第二个参数时,却可以这样:
BE({
created() {
},
methods: {
foo() {
},
bar() {
}
}
}, ['foo', 'bar'])(PAGE);
其本质等同于第一个例子中调用foo()
和bar()
的方式。
考虑异步
普通的数组所形成的方法队列只能适用于同步的方式,而对于串行异步执行的方法则不能保证正确的顺序。
此时,我们可以使用begonia
提供的异步数组包装器来编排串行异步执行函数队列:
import BE, { PAGE, BEAsyncList } from 'begonia';
BE(
{
created() {
},
methods: {
foo({ next, error, end }, ...args) {
post('/api/foo', {})
.then(function(res) {
next(res);
});
.catch(function(err) {
console.error(err);
error(err);
// or end()
});
},
bar({ next, error, end }, ...args) {
console.log(args[0]); // 等于foo函数传入next()的res
// 执行同步逻辑或异步逻辑
end(); // 队列执行到此为止
// 或者 next(),执行下一步,如果bar是队列的最后一个,那么等同于end()
}
}
},
BEAsyncList(
['foo', 'bar'],
function(err, ...args) {
// Be invoked when async-list executed complete
}
)
)(PAGE);
使用序列的目的
当你的方法函数,纯度很高(不需要绝对),只专注于完成一项功能时,预定义的函数执行序列,可以更清楚的标明函数的执行顺序。
此外,数组的元素也不仅限于字符串。这里使用字符串的意思是,指明方法和函数时挂载在this
上的。
如果是一个单独的函数,也可以直接传入函数对象:
import BE, { PAGE, BEAsyncList } from 'begonia';
function baz() {
console.log('other function', this); // this 为page的实例
}
BE({
created() {
},
methods: {
foo() {
},
bar() {
}
}
}, ['foo', 'bar', baz])(PAGE);
当baz
被调用时,函数的this
变量将会指向页面的实例。
其他功能
使用默认带有的延迟属性变更的功能
小程序开发中,如果想要修改实例的data
对象中属性,必须使用setData()
方法。
begonia框架内部使用ViewModelProxy
(VMP
)提供了延迟属性更改,从而可以收集一段时间内的属性变动,
在规定的更新间隔到来时,一次性的提交属性变动。
在实例创建的过程中,框架会为每个实例附加2个方法commit()
和validateNow()
,用来提交属性变动。
此外,对于页面实例和组件实例的data
,框架也为实例创建了同名属性的getter
和setter
方法,用于获取属性值和提交属性值。
其中setter
方法的内部,也采用了延迟生效的机制(即与使用commit()
情况类似)。
形式1:提交一项属性更改:
this.commit('groupList',[{
id:'1800',
name:'一年级B班',
}]);
形式2:直接传入一个对象:
this.commit({
groupList:[{
id:'1800',
name:'一年级B班',
}],
});
形式3:直接为属性赋值(本质是利用setter间接提交):
this.groupList = [{
id:'1800',
name:'一年级B班',
}];
更新间隔到期,属性变动生效
默认设置是100
毫秒更新间隔,当间隔到期,VMP内部会使用setData()
方法,将搜集到的属性改动一次性提交微信小程序框架进行计算生效。
某些情况下,也许你想将提交的属性立即生效,可以使用
this.validateNow();
这样,到当前时间为止,所有提交的属性变更将会立即生效。VMP会清空缓存的对象,等待下一轮时间间隔内提交的属性变动。
延迟更新的时间间隔是可以改变的,首先使用BE
的方法getModules
获取已经装载模块的映射,然后调用vmp
模块的interval
即可,方法接受安全的、非零自然数作为值。
这种方式较1.x
有了改变,原因是内部将VMP
模块隔离为一个更加独立的模块进行装载,减少了1.x
中的耦合部分。
import BE from 'begonia';
//...
BE.getModules.vmp.interval = 200; //设置200毫秒间隔
销毁并回收
当页面发生切换,页面实例和组件实例会被微信小程序框架销毁,此时onUnload
方法会被触发。
在钩子函数中,begonia会自动清理附加在实例对象上的内部属性和方法,释放内部的代理对象。
使用增强模块
begonia遵循模块化原则,提供的各项功能均保持相对独立的状态。包括内部使用的代理对象和延迟提交模块VMP
也是独立的。
只不过,框架在建立之初就进行了自动装载。
begonia
提供的装载模块的方法非常简单:
BE.use(MyModule);
例如,我们也提供了一个简版的redux
模块,您可以首先在一个独立的名为store.js
的文件中,编写store
相关的代码:
// store.js
//导入begonia
import BE from 'begonia';
//导入beleaf模块
import Bex from 'beleaf';
//=====>>>装载bex模块<<<=========
BE.use(Bex);
完成之后,在小程序页面或组件实例中:
Page(BE.page({
//...
onLoad: function () {
//访问store实例
let store = this.$store;
//查看state状态树
let state = this.$store.state;
//通过getters对象访问具体的state属性
let list = this.$getters.groupList;
//发起一个action,引起状态变更
this.$actions.getGroupList('10');
},
//...
}));
更多关于beleaf
的使用细节,您可以访问模块的GitHub项目仓库,详细了解。
说明文档和开发文档
诚如所见,为方便使用,begonia
和beleaf
在API的名称设计上借鉴了很多vue框架的API名称,
不过内部实现和实际使用还是不同的。并且从整体上来说,begonia也远不如vue框架及其衍生的众多代码库的功能强大,限于其使用的场景,够用即好。
如果想要具体了解各种使用方法,可以查看如下文档:
初衷
begonia框架是适用于小程序开发的框架,其所追求的也仅仅是提高小程序开发的效率和改善。 更多的意义在于借由对其他框架优点的认识,自行实现,进而达到研究原理的目的。 也许以后的发展中会追求多种小程序平台开发的统一,但绝不会努力实现在多种设备终端开发中的统一。
开源协议
MIT
关于名称
秋海棠(学名:Begonia
grandis Dry):秋海棠科秋海棠属多年生草本植物。根状茎近球形,茎直立,高可达60厘米,有纵棱无毛。茎生叶互生,叶片轮廓宽卵形至卵形两侧不相等,上面褐绿色,常有红晕,下面色淡,带紫红色,托叶长圆形至披针形膜质,花葶有纵棱,无毛;花较多数粉红色,苞片长圆形,先端钝,早落;花药倒卵球形,子房长圆形,蒴果下垂,轮廓长圆形,种子长圆形小,淡褐色数极多,7月开花,8月开始结果。
分布中国河北、河南、湖北、福建等地。有栽培。生山谷潮湿石壁上、密林、灌丛中,该种花、叶、茎、根均可入药。花形多姿,叶色柔媚。盆栽秋海棠常用来点缀客厅、橱窗或装点家庭窗台、阳台、茶几等地方。