8 Star 54 Fork 18

孢子组 / miniapp-spore

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

🍭小程序渐进框架 miniapp-spore

前言

原生方式开发小程序,经过前面版本迭代和项目积累进行了重构,增加全局存储对象,精简去除不常用的特性,仍然坚持无感知、渐进增强和易用性,基于事件和插件拓展。

平台支持:微信小程序、支付宝小程序、淘宝小程序、钉钉小程序等。

特性

  • 跨平台同时支持微信小程序和阿里小程序
  • 全局存储对象
  • 极简化API,轻松上手
  • 页面onBack生命周期 (页面跳转后返回时触发)
  • 组件didPropsUpdate生命周期 (组件props更新时触发)(仅阿里小程序)
  • 组件props监听器(仅阿里小程序)
  • 生命周期事件系统

Demo

https://herbox.online/p/109000020/app_IMXPoe87_

安装

npm i miniapp-spore -s

使用入门

使用包

app.js 文件引入包 miniapp-spore,引入此包即可生效。

import spore from "miniapp-spore";

全局存储 new Store (namespace, data, [options])

实例化的Store对象,小程序每个页面可以共用此store数据,注意如果有多个Store对象应该保持namespace的唯一性,根据命名空间,数据初始化和更新都会自动同步到对应页面的data[namespace]下。

//在app.js下
import { Store } from "miniapp-spore";

new Store('$global', { count: 1024 })

此时,所有页面的axml模板都可共用此$global数据

<view>{{$global.count}}</view>
<!-- 1024 -->

全局数据更改 Store.prototype.setData(update, [callback])

更改数据与原生框架中页面/组件的setData使用保持一致。更改后会自动触发所有页面数据更新。

import { Store } from "miniapp-spore";

let store = new Store('$global', { count: 1024 })

//将全局数据count加1
store.setData({
	count: store.data.count + 1
})


// 与原生页面和组件的setData一致:

// 1. 直接修改store.data无效,无法改变页面/组件的状态,还会造成数据不一致。

// 2. 请尽量避免一次设置过多的数据。

// 3. setData接受一个对象作为参数。对象的键名key可以非常灵活,以数据路径的形式给出,如 array[2].message、a.b.c.d,并且不需要在store.data中预先定义。

// 4. setData第二个参数为更新后触发的回调,在视图更新后可以拿到最新的data数据。

除此之外,更新数组可以同样可以使用 Store.prototype.$spliceData(update, [callback]) 方法

//在 obj.arr 下的这个数组下标1后插入 'a','b','c'
store.$spliceData({
  'obj.arr': [1, 0, 'a','b','c']
})

另外,提供了Promise版setData方法 Store.prototype.asyncSetData(update)

await store.asyncSetData({
  count: store.data.count + 1
})
//...等待设置生效后处理逻辑

同样的,这里不要去修改页面的data.$global.count,这样修改不会更新store的数据,也同时违背数据修改的一致性(只在同一个接口修改数据),因此应该只在store实例的方法中修改数据。

在页面修改全局数据

通常,将store放到app上,方便页面/组件获取到store对象

app.js

import { Store } from "miniapp-spore";

let store = new Store('$global', { count: 1024 })

App({
	store
})

pages/index/index.js

let store = getApp().store;

//方便拿到store
Page({
	onLoad(){
		store.setData({
			count: store.data.count - 1
		}, ()=>{
			console.log('数据已更新')
		})
	}
})

组件使用全局数据

在组件中,由于担心性能问题,这里的机制是进行手动配置绑定存储,需要在组件中定义 stores 字段,数组类型。 将存储对象的实例放入即可自动绑定此对象,没配置的不会自动生效。

components/test/test.js

let store = getApp().store;

Component({
  // 新增可定义此stores字段
  stores: [
    store,
	//... 支持多个store实例
  ],

  data: {},
  props: {},
  didMount() {
  
  },
});

配置了stores后就可以在此组件axml模板中使用此数据。

components/test/test.axml

<view>{{$global.count}}</view>
<!-- 1024 -->

计算属性

//创建一个全局存储对象 isOdd属性是依赖count的,count变化会自动影响isOdd更新
let store = new Store("$global", { count: 1024 }, {
  computed:{
    isOdd(){
      return this.count % 2;
    }
  }
});
<view>{{$global.count}} 是否为奇数:{{$global.isOdd}}</view>

<!-- 1024 是否为奇数:0 -->

方法封装

为了方便数据维护管理,将常用的修改data逻辑进行封装,在业务代码中进行调用。

//配置actions,方法会在融入到实例中
let store = new Store("$global", { count: 1024 }, {
  actions:{
    add(){
      this.setData({count: this.data.count+1})
    }
  }
});


store.add(); //页面/组件等具体业务逻辑中调用方法即可修改count

数据强制更新

如果在某些生命周期中实例化Store后,可能没有更新页面/组件 这时可以调用Store.prototype.update([callback])进行强制更新。

store.update((data)=>{
  //强制更新完成
});

性能更新方案

默认情况,当store更新时,会将store的data完整的setData到页面/组件。对于应用场景中store更新setData频率比较频繁或组件比较多时,此方案占优,但数据量过大可能失效无法更新。

另外一种方案,当store更新时,将store的data与页面/组件进行diff比对获得差异,对差异的部分数据对页面/组件进行更新。对于场景中,更新频率小,组件比较少,数据量大但不担心更新延迟的情况适用。

如果需要使用第二种方案。在配置中开启diff即可

//创建一个全局存储对象 使用diff更新
let store = new Store("$store", { count: 1024 }, {
  diff: true
});

生命周期事件系统

【阿里小程序的生命周期】

对于App生命周期有:onLaunch,onShow,onHide,onError,onShareAppMessage

对于Page生命周期有:onLoad,onShow,onBack, onReady, onHide, onUnload, onTitleClick, onPullDownRefresh, onReachBottom, onShareAppMessage, onOptionMenuClick, onPullIntercept, onTabItemTap, onPageScroll ( 其中onBack是框架模拟的 )

对于Component生命周期有:onInit, deriveDataFromProps, didMount, didUpdate, didUnmount, didPropsUpdate ( 可能部分生命周期可能和Component2模式有关,其中didPropsUpdate是框架模拟的后面有使用说明 )

【微信小程序的生命周期】

对于App生命周期有:onLaunch,onShow,onHide,onError,onPageNotFound,onUnhandledRejection,onThemeChange

对于Page生命周期有:onLoad,onShow,onBack, onReady, onHide, onUnload, onPullDownRefresh, onReachBottom, onShareAppMessage, onShareTimeline, onAddToFavorites, onPageScroll, onResize,onTabItemTap ( 其中onBack是框架模拟的 )

对于Component生命周期有:created, attached, ready, moved, detached

(如果生命周期有遗漏欢迎提issue、pr)

对于以上生命周期,在此框架内可以通过事件监听到对应生命周期。通过:before、:after来区分周期触发前还是触发后处理逻辑。

参考示例:

import { Store, on } from "miniapp-spore";
//监听事件

// 格式 on(`{类型}.{生命周期}:{前后}`, handler)

// 监听页面onLoad生命周期触发前
on("Page.onLoad:before", function(){
  // this 指 页面实例
  console.log('页面加载前')
});

// 支持同步方法
on("Component.didMount:before", async function(){
  // await 调用接口
  // 用async需要注意特别是before,会影响到生命周期的触发时间,当前async方法执行完成后才会触发Component.didMount
});

生命周期事件使用过程中需要注意,由于是先监听后触发,所以这些事件监听通常不应该放到任何一个生命周期内,或者在触发前的生命周期中监听。

组件属性变化生命周期(仅阿里小程序)

微信小程序有observers监听器,而阿里小程序没有一个专门检测属性变化的机制。因此框架内为阿里小程序提供了didPropsUpdate生命周期,仅在props变化时才会触发此生命周期。

通常我们在使用组件对组件传入属性时,属性的变化判断可能会用到didUpdate生命周期,对于简单值变化可以判断是否相等即可,但对于复杂对象结构就麻烦了。

<hello foo="{{foo}}"/>
Component({
  didUpdate(prevProps, prevData) {
    if(prevProps.foo != this.props.foo){
      // foo 更新了,如果foo是对象类型,这种判断就不对了
    }
  },
});

所以,此框架提供了新的生命周期,处理props变化的情况 当传入的属性foo.xxx变化时,触发didPropsUpdate

Component({
  didPropsUpdate(diff, prevProps) {
    if('foo.xxx' in diff){
      //diff为props变化前后的差异,如果键存在代表对应键的值变化
    }
  },
});

组件属性变化观察器(仅阿里小程序)

通过didPropsUpdate可以处理props变化,你还可以通过定义观察器来监听具体某个路径下的值变化。

Component({
  watchProps: {
    'foo.a.b': function(diff, prevProps){
      //foo.a.b变化时
    },
    'foo.cc': function(diff, prevProps){
      //foo.cc变化时
    }
  },
});

//注:这里不能是箭头函数,否则this指向了watchProps对象

页面/组件 asyncSetData

在页面或组件中,也可以直接使用asyncSetData方法代替当前页面/组件的setData。用法和Store的asyncSetData相同。

插件机制

使用插件通过use方法加载插件,可以自己开发插件在项目中灵活添加功能。

import { Store, use } from "miniapp-spore";

import reduxPlugin from "./redux.plugin.js";

use(reduxPlugin);

插件的结构如下:

//redux.plugin.js
export default function(spore, options){

  //闭包内 定义方法等逻辑

  return {
    install(){
      //安装入口

      //可以灵活使用生命周期事件系统处理相关逻辑
    }
  }
}

示例

如果有好的建议欢迎 issue 讨论 🥰

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2020 tangoboy Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

微信、阿里小程序渐进框架,全局存储状态管理、跨页面通讯、生命周期事件系统、组件props监听。支持微信小程序、支付宝小程序、淘宝小程序、钉钉小程序、高德小程序等 展开 收起
JavaScript
Apache-2.0
取消

发行版 (4)

全部

贡献者

全部

近期动态

加载更多
不能加载更多了
JavaScript
1
https://gitee.com/SporeTeam/miniapp-spore.git
git@gitee.com:SporeTeam/miniapp-spore.git
SporeTeam
miniapp-spore
miniapp-spore
2.x

搜索帮助