wevu
| Install | |
|---|---|
npm install wevu |
|
| Latest Version: | 7.5.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Oct 21, 2026 |
| Links: | GitHub · npm |
wevu
Vue 3 风格的小程序运行时,复用同款响应式与调度器,通过快照 diff 最小化 setData,并内置 Pinia 风格的状态管理。
特性
ref/reactive/computed/watch与nextTick同源于 Vue 3 的响应式核心,并提供面向静态 WXML 的useAsyncDerivationdefineComponent+setup生命周期钩子(onShow/onPageScroll/onShareAppMessage 等)自动注册微信小程序Component(在微信中可用于页面/组件)- 快照 diff + 去重调度,最小化
setData体积,支持bindModel/useBindModel的双向绑定语法 - 插件、
app.config.globalProperties及小程序原生选项可自由组合 - 内置
defineStore/storeToRefs/createPinia,支持 getters、actions、订阅与补丁 - TypeScript first,输出 ESM/CJS/types
安装
pnpm add -D wevu
# 或 npm/yarn/pnpm dlx 按需安装
快速上手:页面定义
import {
computed,
defineComponent,
nextTick,
onMounted,
onPageScroll,
onShareAppMessage,
ref,
} from 'wevu'
defineComponent({
data: () => ({ count: 0 }),
computed: {
doubled() {
return this.count * 2
},
},
methods: {
inc() {
this.count += 1
},
},
watch: {
count(n) {
console.log('count changed', n)
},
},
setup(_props, { state }) {
const title = computed(() => `count: ${state.count}`)
const local = ref(0)
onMounted(() => {
nextTick(() => console.log('reactive queue flushed'))
})
onPageScroll((e) => {
console.log('scrollTop', e?.scrollTop)
})
onShareAppMessage(() => ({ title: title.value }))
return { local }
},
})
defineComponent的data必须是函数(与 Vue 3 一致,和小程序原生对象写法不同)。原生小程序在实例化时会拷贝data对象以隔离实例;wevu 需要为每个实例创建独立的响应式 state/代理与快照 diff,因此必须返回新对象,避免共享引用污染与 diff 不稳定。- 小程序部分页面事件是“按需派发”(分享/滚动等):使用 weapp-vite 时,若你调用了
onPageScroll/onShareAppMessage/...,编译阶段会自动补齐features.enableOnXxx = true;非 weapp-vite 场景可在defineComponent({ features: ... })中手动开启。 - 当全局存在
Component构造器时自动注册;否则可拿到component.__wevu_runtime手动挂载适配器。 - 分享/朋友圈/收藏是否触发由微信官方机制决定(例如右上角菜单/
open-type="share";朋友圈通常需配合wx.showShareMenu()开启菜单项)。 - 组件场景使用
defineComponent,SFC 构建产物可调用createWevuComponent。
异步派生状态
useAsyncDerivation() 把异步结果表示为静态模板可读取的 status/value/error,默认立即加载:
import { useAsyncDerivation } from 'wevu'
const users = useAsyncDerivation(({ signal }) => fetchUsers({ signal }))
initial-pending表示首次加载,refreshing保留最近一次成功值。- 首次失败的
value为undefined;刷新失败保留旧值。加载错误进入status/error,refresh()本身正常完成。 - 连续刷新只允许最新任务提交,新刷新会通过
signal取消旧任务;旧任务不响应取消也不会阻塞等待。 - 返回值自动跟随当前 effect scope 清理,也可幂等调用
dispose()。模板数据只包含可枚举的status/value/error,继续经过现有序列化链路。 - 加载函数不会自动追踪响应式依赖;它不是 Promise 版
computed(),依赖变化后需要显式refresh()。
状态管理
旧项目升级前请阅读 Store 迁移指南。本次按 minor 发布,初始化、Setup 状态访问、重置和订阅行为仍需按指南迁移。
新代码推荐 createPinia();旧名称 createStore() 为同一个函数,StoreManager 类型继续保留。只创建实例不会激活它。
在 app.vue 中安装一次 manager:
<script setup lang="ts">
import { createPinia, use } from 'wevu'
use(createPinia())
</script>
使用 createApp() 时调用 app.use(pinia);use() 只能在 app setup 中调用。定义 Store 并在安装后的页面/组件中使用:
import { defineStore, storeToRefs } from 'wevu'
export const useCounter = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
doubled: state => state.count * 2,
},
actions: {
inc() {
this.count += 1
},
},
})
// 在已安装 manager 的页面/组件内使用
const counter = useCounter()
const { count, doubled } = storeToRefs(counter)
counter.$subscribe(({ type }) => console.log('mutation', type))
counter.inc()
事件派发(emit)
在 setup(props, ctx) 中可使用 ctx.emit(eventName, detail?, options?),底层调用宿主事件能力。微信和抖音使用 triggerEvent;支付宝通过 props.onXxx 回调传递事件,并保留模板监听器需要的 detail 和数据集。支付宝回调不提供微信的冒泡、捕获和跨组件传播选项。
组件边界遵循 Vue 的大小写约定:camelCase prop 与事件会统一映射为小程序 kebab-case 宿主名称,例如 maxQuantity 映射为 max-quantity,emit('quantityChange') 可由父组件的 @quantity-change 监听。update:modelValue 等带冒号事件继续沿用既有的 update-modelvalue 映射。
组件模板中的 tag、普通/函数/model prop 和监听器源码可使用 camelCase 或 kebab-case,两者会生成相同且唯一的 kebab-case 宿主名称,不会输出重复别名。运行时 emit('quantityChange') 与 emit('quantity-change') 每次都只派发一个 quantity-change 宿主事件。
SFC 中静态可识别的组件函数 prop 绑定默认会进入 setData 快照,例如 :callback="fn"、:on-save="handlers.save"。动态绑定或手写组件无法被编译器精确标记时,可设置 allowFunctionProps: true 全量放行;需要恢复严格过滤时,可设置 allowFunctionProps: false。常规父子通信仍可优先使用 emit / 小程序事件。
options 支持:
bubbles:事件是否冒泡(默认false)composed:事件是否可以穿越组件边界(默认false)capturePhase:事件是否拥有捕获阶段(默认false)
与 Vue 3 不同:小程序事件只有一个 detail 载荷,不支持 emit(event, ...args) 的多参数透传。
双向绑定(bindModel / useBindModel)
在 setup(props, ctx) 中使用 ctx.bindModel();在 <script setup> 中使用 useBindModel():
import { useBindModel } from 'wevu'
const bindModel = useBindModel()
const titleModel = bindModel<string>('form.title').model({ event: 'change' })
<t-input v-bind="titleModel" />
注意:weapp-vite 模板编译目前不支持 v-bind="object" 的对象展开语法(不会生成任何属性),建议使用显式绑定。
最佳实践(适配 t-switch 这类 value + change 组件):
import { ref, useBindModel } from 'wevu'
const isActive = ref(true)
const bindModel = useBindModel({ event: 'change', valueProp: 'value' })
const onActiveChange = bindModel.model<boolean>('isActive').onChange
<t-switch :value="isActive" @change="onActiveChange" />
调度与适配
- 更新被批量加入微任务队列;
nextTick只等待当前 JavaScript/响应式任务队列排空,不等待小程序setData回调或视图提交。 - 对状态做快照 diff,只把变更路径传给
setData;宿主提交失败时,下一次响应式更新会发送完整恢复快照。 - 可用
setData.debugPhases: true在现有debug回调中关联 prepare、物理 dispatch 与 commit。合并调用按 ID 去重;callback/Promise/同步返回不等于可见视图完成,未观测边界保持null。参见 阶段观测与测量示例。 weapp.wevu.preset: 'performance'默认开启 patch、隐藏时暂停和diagnostics: 'fallback'。首次快照收集也会记录needsFullSnapshot;启用阶段观测后,同一 revision 可有多条日志,不能将 warning 条数视为失败或回退次数。配置覆盖见 预设说明。- 提供
batch/startBatch/endBatch用于同步更新合并触发;以及effectScope/getCurrentScope/onScopeDispose统一管理 effect/watch 的销毁,setup()同步阶段内创建的副作用会自动归属到实例级 scope,便于避免泄漏。
开发产物与源码调试
使用 weapp-vite 构建时,现有 --platform / weapp.platform 会自动注入编译期常量 import.meta.env.PLATFORM,取值为 weapp、alipay、tt、swan、jd、xhs 或 web。Wevu 发布包保留平台表达式,消费构建替换后即可移除非目标平台分支及构建、IDE 等元数据,无需额外裁剪配置。
能力裁剪取决于实际使用:继续从 wevu 使用具名导入,未使用的 Store、router 和 API/fetch 不会因根入口导出而强制进入产物。SFC / JSX 编译器根据 Binding Manifest 安装所需能力;普通 SFC 不依赖 JSX island 处理器,没有创建 router 时不加载首航 guard 状态机。公开动态工厂仍保留兼容能力安装,不能把编译器精简入口的测量值当成任意动态工厂的体积承诺。
直接在其他工具链中使用时,未提供构建目标会保留宿主探测;显式使用 API/fetch 后,其动态跨平台 adapter 仍保留。Web 继续使用自己的宿主桥接,不等同于 Vue DOM runtime,也不表示已支持原生 App 渲染。
wevu 默认导出压缩后的生产产物,用于降低小程序包体积。包内同时提供未压缩并带 sourcemap 的开发产物:
- 支持
developmentexport condition 的构建器会在开发模式下优先解析到dist/dev/*。 - 需要手动切换时,可以把
wevualias 到wevu/dev,也可以把wevu/routeralias 到wevu/dev/router等同名开发入口。 - 生产构建默认仍使用
dist/*.mjs压缩产物,避免开发产物进入正式包。
本地开发
# 从仓库根目录执行
pnpm dev --filter wevu
pnpm test --filter wevu
pnpm build --filter wevu
更多资料
- 架构细节:
packages-runtime/wevu/ARCHITECTURE.md - 与 Vue 3 对比:
packages-runtime/wevu/VUE3_VS_WEVU.md - 兼容性说明:
packages-runtime/wevu/VUE3_COMPAT.md
Related Packages
Volar plugin for weapp-vite - Provides IntelliSense and type checking for WeChat...
Version History
| Version | Released | License |
|---|---|---|
| 7.5.0 | MIT | |
| 7.4.0 | MIT | |
| 7.3.0 | MIT | |
| 7.2.2 | MIT | |
| 7.2.1 | MIT | |
| 7.2.0 | MIT | |
| 7.1.4 | MIT | |
| 7.1.3 | MIT | |
| 7.1.2 | MIT | |
| 7.1.1 | MIT | |
| 7.1.0 | MIT | |
| 7.0.4 | MIT | |
| 7.0.3 | MIT | |
| 7.0.2 | MIT | |
| 7.0.1 | MIT | |
| 7.0.0 | MIT | |
| 6.25.1 | MIT | |
| 6.25.0 | MIT | |
| 6.24.0 | MIT | |
| 6.23.0 | MIT | |
| 6.22.0 | MIT | |
| 6.21.0 | MIT | |
| 6.20.5 | MIT | |
| 6.20.4 | MIT | |
| 6.20.3 | MIT | |
| 6.20.2 | MIT | |
| 6.20.1 | MIT | |
| 6.20.0 | MIT | |
| 6.19.4 | MIT | |
| 6.19.3 | MIT |
Showing the latest 30 of 193. See every release on npm
Pre-releases (6)
| Version | Released | License |
|---|---|---|
| 1.0.0-alpha.5 | MIT | |
| 1.0.0-alpha.4 | MIT | |
| 1.0.0-alpha.3 | MIT | |
| 1.0.0-alpha.2 | MIT | |
| 1.0.0-alpha.1 | MIT | |
| 0.0.2-alpha.0 | MIT |