如何在petite-vue应用外部访问或修改内部响应式数据
背景
- 轻量UI更新场景下选用petite-vue,用于控制DOM显隐、类名、样式属性
- 项目包含多个JS文件,需要支持在任意文件中修改UI状态
- 标准Vue中可直接通过应用实例访问修改响应式数据,参考写法:
const vueApp = new Vue({ el: "#vue-app", data(){ return { count: 1} }}) setTimeout(() => { vueApp.count = 2 }, 1000)
- 照搬上述写法在petite-vue中无法生效,错误写法示例:
// 该写法无法触发UI更新 const petiteVueApp = PetiteVue.createApp({ count: 0, }).mount("#petite-vue"); setTimeout(() => { petiteVueApp.count = 2 }, 1000);
问题成因
petite-vue的API设计和标准Vue存在差异:PetiteVue.createApp().mount()返回的对象是应用挂载句柄,仅暴露directive、mount等全局方法,不会直接把传入createApp的响应式状态挂载到这个返回对象上。
手动给返回的petiteVueApp对象添加count属性时,只是给普通JS对象加了个非响应式属性,和petite-vue内部用于渲染的响应式状态完全无关,自然无法触发视图更新。打印对象时看到的count就是手动新增的普通属性,不是框架内部的响应式数据。
可行实现方案
方案1:提前创建独立响应式状态(推荐优先使用)
先通过PetiteVue.reactive单独创建响应式状态对象,再将该对象传入createApp完成挂载,外部只要能访问到这个状态对象,直接修改属性就能触发UI更新。
// 单独初始化响应式状态 const uiState = PetiteVue.reactive({ count: 0, isVisible: false }) // 传入状态完成挂载 PetiteVue.createApp(uiState).mount("#petite-vue") // 任意位置只要能访问uiState,直接修改即可触发更新 setTimeout(() => { uiState.count = 2 }, 1000)
如果需要跨多个JS文件访问,可以把状态挂载到全局作用域:
window.uiState = uiState // 其他JS文件直接读写window.uiState的属性即可
方案2:从根DOM节点获取内部实例
petite-vue会把内部组件实例绑定在挂载根节点的__vue_app__属性上,可通过该属性拿到内部响应式状态:
PetiteVue.createApp({ count: 0 }).mount("#petite-vue") // 从根DOM取内部实例 const vm = document.getElementById("petite-vue").__vue_app__ setTimeout(() => { vm.count = 2 }, 1000)
注意:
__vue_app__属于框架内部私有属性,版本迭代时存在变更风险,不建议在生产环境使用。
方案3:全局注入共享状态
多组件、多模块场景下,可以在初始化应用时全局注入共享状态,所有模板作用域和外部逻辑都能访问同一份响应式数据:
const sharedState = PetiteVue.reactive({ count: 0, theme: "light" }) PetiteVue.createApp({ // 根组件逻辑 }, { $state: sharedState }).mount("#petite-vue") // 外部直接修改sharedState即可更新UI setTimeout(() => { sharedState.count = 2 }, 1000)
内容的提问来源于stack exchange,提问作者Djave
相关产品推荐
相关产品推荐

