数据流转

先上一张图看清 Westore 怎么解决小程序数据难以管理和维护的问题:

非纯组件的话,可以直接省去 triggerEvent 的过程,直接修改 store.data 并且 update,形成缩减版单向数据流。

Github: https://github.com/dntzhang/westore

组件

这里说的组件便是自定义组件,使用原生小程序的开发格式如下:


Component({properties: { },data: { },methods: { }
})

使用 Westore 之后:

import create from '../../utils/create'create({properties: { },data: { },methods: { }
})

看着差别不大,但是区别:

  • Component 的方式使用 setData 更新视图
  • create 的方式直接更改 store.data 然后调用 update
  • create 的方式可以使用函数属性,Component 不可以,如:
export default {data: {firstName: 'dnt',lastName: 'zhang',fullName:function(){return this.firstName + this.lastName}}
}

绑定到视图:

<view>{{fullName}}</view>

小程序 setData 的痛点:

  • 使用 this.data 可以获取内部数据和属性值,但不要直接修改它们,应使用 setData 修改
  • setData 编程体验不好,很多场景直接赋值更加直观方便
  • setData 卡卡卡慢慢慢,JsCore 和 Webview 数据对象来回传浪费计算资源和内存资源
  • 组件间通讯或跨页通讯会把程序搞得乱七八糟,变得极难维护和扩展

没使用 westore 的时候经常可以看到这样的代码:

使用完 westore 之后:

上面两种方式也可以混合使用。

可以看到,westore 不仅支持直接赋值,而且 this.update 兼容了 this.setData 的语法,但性能大大优于 this.setData,再举个例子:

this.store.data.motto = 'Hello Westore'
this.store.data.b.arr.push({ name: 'ccc' })
this.update()

等同于

this.update({motto:'Hello Westore',[`b.arr[${this.store.data.b.arr.length}]`]:{name:'ccc'}
})

这里需要特别强调,虽然 this.update 可以兼容小程序的 this.setData 的方式传参,但是更加智能,this.update 会先 Diff 然后 setData。原理:

纯组件

常见纯组件由很多,如 tip、alert、dialog、pager、日历等,与业务数据无直接耦合关系。
组件的显示状态由传入的 props 决定,与外界的通讯通过内部 triggerEvent 暴露的回调。
triggerEvent 的回调函数可以改变全局状态,实现单向数据流同步所有状态给其他兄弟、堂兄、姑姑等组件或者其他页面。

Westore里可以使用 create({ pure: true }) 创建纯组件(当然也可以直接使用 Component),比如 :


import create from '../../utils/create'create({pure : true,properties: {text: {type: String,value: '',observer(newValue, oldValue) { }}},data: {privateData: 'privateData'},ready: function () {console.log(this.properties.text)},methods: {onTap: function(){this.store.data.privateData = '成功修改 privateData'this.update()this.triggerEvent('random', {rd:'成功发起单向数据流' + Math.floor( Math.random()*1000)})}}
})

需要注意的是,加上 pure : true 之后就是纯组件,组件的 data 不会被合并到全局的 store.data 上。

组件区分业务组件和纯组件,他们的区别如下:

  • 业务组件与业务数据紧耦合,换一个项目可能该组件就用不上,除非非常类似的项目
  • 业务组件通过 store 获得所需参数,通过更改 store 与外界通讯
  • 业务组件也可以通过 props 获得所需参数,通过 triggerEvent 与外界通讯
  • 纯组件与业务数据无关,可移植和复用
  • 纯组件只能通过 props 获得所需参数,通过 triggerEvent 与外界通讯

大型项目一定会包含纯组件、业务组件。通过纯组件,可以很好理解单向数据流。

小程序插件

小程序插件是对一组 JS 接口、自定义组件或页面的封装,用于嵌入到小程序中使用。插件不能独立运行,必须嵌入在其他小程序中才能被用户使用;而第三方小程序在使用插件时,也无法看到插件的代码。因此,插件适合用来封装自己的功能或服务,提供给第三方小程序进行展示和使用。

插件开发者可以像开发小程序一样编写一个插件并上传代码,在插件发布之后,其他小程序方可调用。小程序平台会托管插件代码,其他小程序调用时,上传的插件代码会随小程序一起下载运行。

  • 插件开发者文档
  • 插件使用者文档

插件开发

Westore 提供的目录如下:

|--components
|--westore
|--plugin.json
|--store.js

创建插件:

import create from '../../westore/create-plugin'
import store from '../../store'//最外层容器节点需要传入 store,其他组件不传 store
create(store, {properties:{authKey:{type: String,value: ''}},data: { list: [] },attached: function () {// 可以得到插件上声明传递过来的属性值console.log(this.properties.authKey)// 监听所有变化this.store.onChange = (detail) => {this.triggerEvent('listChange', detail)}// 可以在这里发起网络请求获取插件的数据this.store.data.list = [{name: '电视',price: 1000}, {name: '电脑',price: 4000}, {name: '手机',price: 3000}]this.update()//同样也直接和兼容 setData 语法this.update({ 'list[2].price': 100000 })}
})

在你的小程序中使用组件:

<list auth-key="{{authKey}}" bind:listChange="onListChange" />

这里来梳理下小程序自定义组件插件怎么和使用它的小程序通讯:

  • 通过 properties 传入更新插件,通过 properties 的 observer 来更新插件
  • 通过 store.onChange 收集 data 的所有变更
  • 通过 triggerEvent 来抛事件给使用插件外部的小程序

这么方便简洁还不赶紧试试 Westore插件开发模板 !

特别强调

插件内所有组件公用的 store 和插件外小程序的 store 是相互隔离的。

原理

页面生命周期函数

名称 描述
onLoad 监听页面加载
onShow 监听页面显示
onReady 监听页面初次渲染完成
onHide 监听页面隐藏
onUnload 监听页面卸载

组件生命周期函数

名称 描述
created 在组件实例进入页面节点树时执行,注意此时不能调用 setData
attached 在组件实例进入页面节点树时执行
ready 在组件布局完成后执行,此时可以获取节点信息(使用 SelectorQuery )
moved 在组件实例被移动到节点树另一个位置时执行
detached 在组件实例被从页面节点树移除时执行

由于开发插件时候的组件没有 this.page,所以 store 是从根组件注入,而且可以在 attached 提前注入:

export default function create(store, option) {let opt = storeif (option) {opt = optionoriginData = JSON.parse(JSON.stringify(store.data))globalStore = storeglobalStore.instances = []create.store = globalStore}const attached = opt.attachedopt.attached = function () {this.store = globalStorethis.store.data = Object.assign(globalStore.data, opt.data)this.setData.call(this, this.store.data)globalStore.instances.push(this)rewriteUpdate(this)attached && attached.call(this)}Component(opt)
}

总结

  • 组件 - 对 WXML、WXSS 和 JS 的封装,与业务耦合,可复用,难移植
  • 纯组件 - 对 WXML、WXSS 和 JS 的封装,与业务解耦,可复用,易移植
  • 插件 - 小程序插件是对一组 JS 接口、自定义组件或页面的封装,与业务耦合,可复用

Star & Fork 小程序解决方案

https://github.com/dntzhang/westore

License

MIT @dntzhang

小程序解决方案 Westore - 组件、纯组件、插件开发相关推荐

  1. 微信小程序开发03-这是一个组件

    编写组件 基本结构 接上文:微信小程序开发02-小程序基本介绍 我们今天先来实现这个弹出层: 之前这个组件是一个容器类组件,弹出层可设置载入的html结构,然后再设置各种事件即可,这种组件有一个特点: ...

  2. 微信小程序学习笔记(四)自定义组件

    文章目录 1. 组件的创建与引用 1.1 创建组件 1.2 引用组件 1.3 全局引用 VS 局部引用 1.4 组件和页面的区别 2. 样式 2.1 组件样式隔离 2.2 修改组件的样式隔离选项 3. ...

  3. 微信小程序如何封装自己的组件?

    在现在前端领域,最常见的话语就是组件化.工程化的内容.所有的框架都在朝着这方面发展.作为前端生态中的新兴热人物小程序的出现,同样支持组件化开发. 在我们的日常开发中,可以封装一些常用的组件达到复用效果 ...

  4. 小程序日期加时间筛选组件

    小程序日期加时间筛选组件 新建component->date-time-picker .wxml <picker mode="multiSelector" class= ...

  5. 微信小程序,自定义导航栏组件

    微信小程序,自定义导航栏组件,可兼容iPhone 11及以上留海屏显示,关于参数获取设置参照微信小程序-收藏_羽筠的博客-CSDN博客 可定义设置的内容如下: 文字及返回箭头颜色 背景图片(优先级高于 ...

  6. 微信小程序简易搭建之框架/组件库

    微信小程序简易搭建之框架/组件库 Vant weapp 下面看看如何导入 https://github.com/youzan/vant-weapp 使用教程: 1.下载后找到dist 2. 在你的项目 ...

  7. uniapp 小程序封装左滑效果组件

    uniapp 小程序封装左滑效果组件 引言 封装组件 页面使用 注意事项 引言 小程序电商项目购物车,往往都会有左滑删除功能,在不想使用插件的前提下,就需要自己编写,因此我个人写了一个左滑效果组件 封 ...

  8. 微信小程序---swiper轮播图组件

    微信小程序-swiper轮播图组件 在components中新建文件夹swiper components/swiper/swiper.wxml <!--components/swiper/swi ...

  9. vant weapp 下拉_Vant Weapp小程序蹲坑之使用submit-bar组件

    本文介绍在Vant Weapp小程序开发中使用submit-bar组件时需要注意的部分问题.坑来坑去,先上示例代码吧,由简单到复杂顺序. main.js代码 main.json代码 index.vue ...

最新文章

  1. linux ``与 ''区别
  2. 医疗在线服务InQuicker,融资0元年盈利400万美元!拒绝风投与炒作
  3. Lambda省略格式Lambda使用前提
  4. live555 源码分析: PLAY 的处理
  5. ASA 9.21 in Vmware Workstation 10
  6. 细说flush、ob_flush的区别
  7. MyBatis_ibatis和mybatis的区别【转】
  8. 简单配置laravel
  9. 寻找电路布线最短路径算法BFS
  10. 【元胞自动机】基于matlab元胞自动机人流疏散【含Matlab源码 665期】
  11. 网站搭建教程(详细步骤 )
  12. win10重置系统后右键一直转圈,解决鼠标右键一直转圈问题
  13. python 计算标准体重程序
  14. xcode 免cleanup build
  15. com.apple.Boot.plist 和SMBIOS.plist 的设置
  16. 苹果youtube无法连接网络_当手机无信号或者无法连接网络时的正确解决步骤
  17. 小项目1——猫眼电影top100(2.0)
  18. 计算机毕业设计JAVA图书个性化推荐系统mybatis+源码+调试部署+系统+数据库+lw
  19. 软件“生命”系统进化论——软件以负熵为生!
  20. 【小程序云开发】不用后端也能构建完整的微信小程序

热门文章

  1. 51Nod 1058 N的阶乘的长度
  2. 第十五章,读取txt文件(C++)
  3. (转载)Hadoop map reduce 过程获取环境变量
  4. tablix“Tablix1”有一个具有内部成员的详细信息成员
  5. Windows 7 常用快捷键 命令
  6. [转] android学习和广告平台赚钱
  7. abap--关于集(set)的读取(如读取成本中心组下的所有成本中心)
  8. C++_数据类型_布尔类型_以及数据的输入_以及算术运算符_加减乘除运算---C++语言工作笔记013
  9. 大数据_Hbase-分布式介绍_分布式发展历程_去中心化_客户端负载均衡_服务器端负载均衡---Hbase工作笔记0001
  10. Netty工作笔记0021---NIO编写,快速入门---编写服务器