- 前端
- 小程序
- 开发工具
【免费下载链接】wepy
小程序组件化开发框架 - 已归档
导读
@wepy/x是 WePY 2.0 官方提供的 Vuex 集成方案。它把 Vuex 的Store、mapState、mapActions等能力原样引入小程序组件化开发环境,让你在app.wpy中注册一次插件、创建一个全局 store,即可在任意页面或组件中通过computed与methods直接消费全局状态、派发 action。读完本文,你将掌握在 WePY 2.0 项目中安装、注册、初始化 Vuex store,并通过mapState/mapActions把状态与操作映射到组件中的完整实战流程,同时了解@wepy/x内部如何借助全局 mixin 与计算属性机制保证页面数据实时同步。
一、@wepy/x 是什么:WePY 2.0 的 Vuex 桥接层
在 WePY 2.0(基于@wepy/core的小程序组件化框架)中,多个页面与组件之间共享一份全局数据是常见需求,例如用户登录态、购物车数量、全局配置等。@wepy/x正是为解决这一问题而提供的官方插件:它以 Vuex 为基础(依赖vuex@^3.1.1,见 packages/x/package.json),通过wepy.use(vuex)安装,将 Vuex 的能力桥接进 WePY 组件的computed与methods体系。
从源码看,packages/x/index.js 几乎完整导出了 Vuex 的核心 API:
export default { Store, install: wepyInstall, version, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers };同时以具名导出的方式暴露Store、install、mapState、mapMutations、mapGetters、mapActions、createNamespacedHelpers,因此你在代码里既可以import vuex from '@wepy/x'整体使用,也可以import { mapState, mapActions } from '@wepy/x'按需引入。
注意:
@wepy/x的package.json中main指向dist/index.js,即发布产物为编译后的文件;当前仓库中的packages/x/index.js为源码形态,二者导出内容一致。
二、安装
在 WePY 2.0 项目根目录执行:
npm install @wepy/x vuex --save--save会把依赖写入package.json的dependencies。需要说明的是:
@wepy/x自身声明了vuex@^3.1.1依赖(见 packages/x/package.json),因此理论上安装@wepy/x时会自动带上 vuex;- README 中仍显式列出
vuex,是为了保证版本可控、语义清晰,建议按官方说明两者一起安装; - 当前仓库
packages/x的版本为2.1.1-alpha.0,属于 WePY 2.x 的早期发布形态,后续在 npm 上以@wepy/x分发。
三、三步接入:注册插件 → 初始化 Store → 映射到组件
README 给出了一套完整的最小可运行流程,下面逐一步骤展开,并结合仓库源码解释每一步背后发生的事。
步骤 1:在 app.wpy 中安装 Vuex 插件
// app.wpy import wepy from '@wepy/core'; import vuex from '@wepy/x'; wepy.use(vuex);wepy.use是 WePY 2.0 的插件机制,实现在 packages/core/weapp/apis/use.js:
export function use(plugin, ...args) { if (plugin.installed) { return this; } let install = plugin.install || plugin; if (isFunc(install)) { install.apply(plugin, [this].concat(args)); } plugin.installed = 1; }关键行为:
- 插件通过
plugin.installed标记去重,重复wepy.use(vuex)不会二次安装; @wepy/x暴露的install即wepyInstall函数(见 packages/x/index.js),它接收wepy实例作为第一个参数;- 安装过程会调用 Vuex 自身的
install(wepy),并在 WePY 上注册一个全局 mixin(详见下文“底层原理”)。
应用入口
app.wpy中wepy.use(vuex)需在创建页面/组件之前执行,确保所有实例都能感知 store。
步骤 2:初始化 store
// ~/store.js import Vuex from '@wepy/x'; export default new Vuex.Store({ state: { num: 0 }, mutations: { increment (state) { state.num++; } }, actions: { increment ({ commit }) { commit('increment'); }, incrementAsync ({ commit }) { setTimeout(() => commit('increment'), 1000); } } })这里Vuex.Store直接来自@wepy/x重新导出的 Vuex 构造函数,配置语法与 Web 端 Vuex 完全一致:
| 配置项 | 作用 | 示例说明 |
|---|---|---|
state | 全局响应式数据 | num: 0作为计数器初始值 |
mutations | 同步修改 state 的唯一途径 | increment执行state.num++ |
actions | 可异步、可组合的提交逻辑 | incrementAsync延迟 1 秒后commit('increment') |
getters(未在示例中,但由@wepy/x完整导出) | 派生的计算状态 | 可用mapGetters映射 |
需要特别注意的是,页面或组件如何拿到这个 store:@wepy/x的全局 mixin 会在组件初始化时把 store 注入,使每个组件实例都能访问this.$store。Vuex 的install(wepy)调用链会负责把 store 绑定到wepy.prototype.$store上,因此你不需要在每个.wpy文件里手动 import store。
步骤 3:映射到组件
// ~/counter.wpy <template> <div> {{num}} </div> <button @tap="increment"> Increment </button> <button @tap="incrementAsync"> Increment Async </button> </template> <script> import wepy from '@wepy/core'; import { mapState, mapActions } from '@wepy/x'; wepy.component({ computed: { ...mapState([ 'num' ]) }, methods: { ...mapActions([ 'increment', 'incrementAsync' ]) } }) </script>映射规则:
...mapState([ 'num' ]):把 store 的state.num映射为组件的计算属性num,模板里直接用{{num}}渲染;state 变化时计算属性自动更新,进而驱动视图刷新;...mapActions([ 'increment', 'incrementAsync' ]):把 store 的actions.increment/actions.incrementAsync映射为组件 methods,模板中@tap绑定的同名处理函数即调用对应 action;- 若组件内已有同名 computed/methods 键,展开运算符会按顺序覆盖,因此建议将
mapState/mapActions展开放在对象末尾,避免覆盖组件自身逻辑。
组件与 store 的联动流程为:用户点击按钮 →incrementaction →commit('increment')→ mutation 修改state.num→ Vuex 通知依赖 → 组件的计算属性num重新求值 → 视图更新。incrementAsync则演示了异步场景:action 内部setTimeout延迟 1 秒后再提交 mutation,这是 Vuex 处理异步的标准姿势。
四、底层原理:@wepy/x 如何驱动小程序数据同步
4.1 全局 mixin 与计算属性重算
packages/x/index.js 中的wepyInstall除了调用 Vuex 官方install(wepy)外,还注册了一个全局 mixin:
wepy.mixin({ created: function() { let computed = this.$options.computed; for (let k in computed) { if (computed[k].vuex) { this.$watch( k, function() { this._computedWatchers[k].evaluate(); }, { deep: true } ); } } }, onUnload: function () { // ... 清理页面卸载后的依赖 } });这里有两个值得展开的点:
created钩子:遍历组件$options.computed,凡是带vuex标记的计算属性,都用this.$watch(k, ..., { deep: true })深度监听其变化,变化时调用this._computedWatchers[k].evaluate()强制重新求值。_computedWatchers由 WePY 的计算属性初始化逻辑创建,实现在 packages/core/weapp/init/computed.js——每个计算属性对应一个Watcher,dirty置位后evaluate()会重新执行 getter 并更新缓存值。这样,当 store 数据变化触发 Vuex 内部响应式依赖时,页面计算属性会被显式重算,从而把新值同步到视图。onUnload钩子:小程序页面卸载后实例会销毁,但 store 数据的依赖关系可能残留,造成内存泄漏或跨页脏数据。因此onUnload中遍历this._computedWatchers,把当前页面实例(sub.vm === this)从所有dep.subs订阅者中移除;当某个 dep 不再有订阅者时,同时从item.depIds中删除该依赖 id。这段代码直接对应 README “Other” 一节中“页面卸载后实例丢失、但 store 依赖仍然存在”的注释说明。
4.2 全局 mixin 的合并机制
wepy.mixin注册的全局 mixin 会进入$global.mixin,在组件/页面实例化时通过 packages/core/weapp/init/mixins.js 的patchMixins合并进组件配置:created、onUnload属于生命周期键,走WEAPP_LIFECYCLE的生命周期合并策略(合并为数组、依次调用),因此不会覆盖你在组件里自己写的created/onUnload,而是共存执行。这也是@wepy/x能对每个组件无侵入生效的原因。
五、完整 API 一览:@wepy/x 导出了什么
@wepy/x完整导出(默认导出与具名导出等价):
| 导出 | 来源 | 用途 |
|---|---|---|
Store | Vuex | 创建全局 store 实例 |
install/wepyInstall | @wepy/x 自身 | 供wepy.use()调用的插件安装函数 |
version | Vuex 版本号(编译期注入__VERSION__) | 运行时获取 Vuex 版本 |
mapState | Vuex | 映射 state 到 computed |
mapMutations | Vuex | 映射 mutations 到 methods |
mapGetters | Vuex | 映射 getters 到 computed |
mapActions | Vuex | 映射 actions 到 methods |
createNamespacedHelpers | Vuex | 创建基于命名空间的辅助函数(配合 modules 使用) |
虽然 README 示例只演示了mapState与mapActions,但mapMutations/mapGetters的使用方式与 Vuex 官方一致,例如:
import { mapGetters, mapMutations } from '@wepy/x'; wepy.component({ computed: { ...mapGetters([ 'total' ]) }, methods: { ...mapMutations([ 'increment' ]) } })六、限制与注意事项
README 明确说明了两点限制,务必在项目中使用时注意:
不支持 Vuex 模块(Module):当前版本不支持
Vuex的 modules 特性。虽然@wepy/x导出了createNamespacedHelpers,但 README 的 “Other” 一节明确声明 “Vuex Module is not supported currently”,并指向仓库的 issue #2191 跟踪该问题。因此:不要在new Vuex.Store({ modules: {...} })中依赖模块化分片,或至少验证后再使用;需要拆分状态时,可先用多个 store 字段或普通对象组织数据。文档指向:README 将官方 Vuex 文档(https://vuex.vuejs.org/)作为完整参考,
@wepy/x的 API 语义与 Vuex 3.x 保持一致,除 modules 支持外,state / mutations / actions / getters 的使用约定可完全参照 Vuex 文档。
此外,从当前仓库形态看,packages/x处于早期 alpha 阶段(版本2.1.1-alpha.0),且package.json中test脚本为占位(echo "Error: no test specified"),即该包没有独立的自动化测试覆盖。在选用时建议:锁死版本、做足业务侧回归验证,并关注 WePY 官方后续版本是否合并了相关修复。
七、相关文件速览
| 文件 | 说明 |
|---|---|
| packages/x/README.md | 官方使用文档(简体中文,本文主体依据) |
| packages/x/README_EN.md | 英文版使用文档 |
| packages/x/index.js | 插件源码:install + 全部导出 |
| packages/x/package.json | 包元信息:版本、vuex 依赖、main 指向 dist |
| packages/core/weapp/apis/use.js | wepy.use插件安装实现 |
| packages/core/weapp/init/computed.js | 计算属性与_computedWatchers的实现 |
| packages/core/weapp/init/mixins.js | 全局/局部 mixin 合并策略 |
| packages/redux/index.js | 同仓库的 Redux 集成方案(@wepy/redux,可作为对比参考) |
总结
@wepy/x用极小的接入成本(一次npm install、一行wepy.use、一份 store 配置、两个 map 辅助函数)为 WePY 2.0 小程序带来了完整的 Vuex 全局状态管理能力。其底层通过 Vuex 官方 install 注入$store,再借助全局 mixin 在created阶段深度监听带vuex标记的计算属性、在onUnload阶段清理跨页依赖,实现了状态更新与页面渲染的同步以及内存泄漏的规避。接入时唯一需要警惕的是:当前版本尚未支持 Vuex modules,涉及模块化场景请谨慎验证后再使用。
- 前端
- 小程序
- 开发工具
【免费下载链接】wepy
小程序组件化开发框架 - 已归档
相关推荐
WePY状态管理:Redux集成与数据流管理方案
WePY状态管理:Redux集成与数据流管理方案 WePY框架作为微信小程序开发的优秀解决方案,提供了强大的状态管理能力。通过内置的Redux集成,开发者可以轻
前端小程序开发工具WePY数据管理终极指南:Redux状态管理完整集成教程
WePY数据管理终极指南:Redux状态管理完整集成教程 在复杂的小程序开发中,数据管理一直是开发者面临的重大挑战。WePY作为优秀的小程序组件化开发框架,通过
前端小程序开发工具SteamDB扩展与SteamDB.info集成:如何实时查看游戏价格和历史数据
SteamDB扩展与SteamDB.info集成:如何实时查看游戏价格和历史数据 想要在Steam上做出明智的购买决策吗?SteamDB扩展与SteamDB.i
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考