wevu
v6.6.9
Published
Vue 3 风格的小程序运行时,包含响应式、diff+setData 与轻量状态管理
Maintainers
Readme
wevu
Vue 3 风格的小程序运行时,复用同款响应式与调度器,通过快照 diff 最小化 setData,并内置 Pinia 风格的状态管理。
特性
ref/reactive/computed/watch与nextTick同源于 Vue 3 的响应式核心defineComponent+setup生命周期钩子(onShow/onPageScroll/onShareAppMessage 等)自动注册微信小程序Component(在微信中可用于页面/组件)- 快照 diff + 去重调度,最小化
setData体积,支持bindModel/useBindModel的双向绑定语法 - 插件、
app.config.globalProperties及小程序原生选项可自由组合 - 内置
defineStore/storeToRefs/createStore,支持 getters、actions、订阅与补丁 - TypeScript first,输出 ESM/CJS/types
安装
pnpm add 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('page ready'))
})
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。
状态管理
import { createStore, defineStore, storeToRefs } from 'wevu'
createStore() // 在小程序入口只需要调用一次,注入插件可选
export const useCounter = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
doubled: state => state.count * 2,
},
actions: {
inc() {
this.count += 1
},
},
})
// 在页面/组件内使用
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。
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与 Vue 3 行为一致。 - 对状态做快照 diff,只把变更路径传给
setData,避免大对象全量下发。 - 提供
batch/startBatch/endBatch用于同步更新合并触发;以及effectScope/onScopeDispose统一管理 effect/watch 的销毁,便于避免泄漏。
本地开发
# 从仓库根目录执行
pnpm dev --filter wevu
pnpm test --filter wevu
pnpm build --filter wevu更多资料
- 架构细节:
packages/wevu/ARCHITECTURE.md - 与 Vue 3 对比:
packages/wevu/VUE3_VS_WEVU.md - 兼容性说明:
packages/wevu/VUE3_COMPAT.md
