如何在.VUE文件中修改引入的外部JS文件内的数据?
直接修改logs.data().infomation无法持久生效的核心原因是:data.js导出的对象中,data()方法每次被调用都会返回一个全新创建的独立对象。你在adddata方法里写的logs.data().infomation.log1d = xxx,本质是修改了当次调用临时生成的对象,这个临时对象没有被任何变量持久持有,执行完这行代码就会被垃圾回收;下次再调用logs.data()时,又会生成一个带初始值的全新对象,之前的修改自然不会保留。
而组件内this.logitems修改能生效,是因为组件初始化阶段执行logitems: logs.data().infomation时,把当次调用生成的对象引用存到了组件自身的响应式数据里,后续修改的是组件持有的这个固定引用指向的对象,但这个对象和其他次调用logs.data()生成的对象没有任何关联,自然无法实现跨位置的共享修改。
要实现对data.js中存储数据的可持久修改,核心是把要共享的数据改成模块内持久持有的单例,不要每次调用方法都新建对象。
基础通用改造(无框架依赖)
先修改DATA.JS,把共享数据定义在方法外层作为模块单例:
// DATA.JS // 模块初始化时就创建唯一的共享数据,仅创建一次 const sharedStore = { infomation: { log1d: 1, logDetail: "This is some log detail for log 1", logType: "general", createdBy: "name", CreatedAt: "date", } } export default { getStore() { return sharedStore }, // 推荐额外封装修改方法,避免任意位置随意修改属性导致的逻辑混乱 increaseLog1d() { sharedStore.infomation.log1d += 1 } }
再调整TEST.VUE中的调用逻辑,统一使用同一个单例引用:
<!-- TEST.VUE --> <template> <div> <button @click="test()">test</button> <button @click="adddata()">add</button> </div> </template> <script> import logs from './data.js' export default { data () { return { // 初始化时拿到共享数据的引用,全程指向同一个对象 logitems: logs.getStore().infomation, } }, methods:{ test(){ console.log(logs.getStore().infomation) }, adddata(){ // 现在直接修改共享数据可以持久生效 logs.getStore().infomation.log1d += 1 console.log(logs.getStore().infomation) // 组件内持有的是同一个对象的引用,修改会自动同步 this.logitems.log1d +=1 console.log(this.logitems) } } } </script>
Vue项目响应式改造
如果需要多个组件引用这个共享数据时自动触发视图更新,可以把单例数据改成Vue响应式对象:
- Vue2 环境下使用
Vue.observable包裹共享数据 - Vue3 环境下使用
reactive包裹共享数据
以Vue2为例,修改DATA.JS:
import Vue from 'vue' const sharedStore = Vue.observable({ infomation: { log1d: 1, logDetail: "This is some log detail for log 1", logType: "general", createdBy: "name", CreatedAt: "date", } }) export default { getStore() { return sharedStore } }
改造后所有引用sharedStore的组件,只要数据变化就会自动触发视图重渲染,不需要额外做事件监听。
注意:不要在共享数据模块里导出会返回新对象的工厂函数作为数据获取方式,除非你的业务场景明确需要每次拿到独立的副本,否则必然会出现修改不生效、数据不同步的问题。
内容的提问来源于stack exchange,提问作者Metalzone Rockneverdie

