import 导入过的模块需要再次执行怎么办?
前言
在 ES6 中,import
语句引入模块后,模块会被缓存,后续的引用直接从缓存中获取,而不会重新执行。这种设计提升了性能,符合单例模式的思想。然而,在某些场景中,模块依赖的变量发生改变后,可能需要再次执行该模块以获得正确的值。
本文通过一个常见的场景,分享如何解决模块缓存带来的问题,欢迎大家交流分享其他解决方案。
目录
- 场景
- 解决一:
window.location.reload()
- 解决二:添加监听事件
- 解决三:将
export
变量改为export
方法 - 解决四:使用状态管理
场景
在组件1中引用了模块中的变量A后,修改其依赖的变量B。此时组件2再次引用模块变量A时,A的值并未根据B的变化而更新。
代码示例
base.js
:
console.log('执行 base.js')
const person = {
name: '张三',
age: 15
}
export const ageChange = (from) => {
person.age++
console.log(from + ' 执行张三年龄+1')
}
export const getLisiAge = () => {
return person.age + 1
}
myModule.js
:
import { getLisiAge } from './base'
console.log('执行 myModule.js')
export const lisi = {
name: '李四',
age: getLisiAge()
}
组件1:
import { lisi } from './myModule'
import { ageChange } from './base'
console.log('组件1:', lisi.name, lisi.age)
ageChange('组件1')
组件2:
import { lisi } from './myModule'
const handlePrint = () => {
console.log('组件2:', lisi.name, lisi.age)
}
组件1修改了张三的年龄,但在组件2中李四的年龄并未更新。
解决方案
解决一:window.location.reload()
通过 window.location.reload()
刷新页面,重新执行模块代码。可以将修改后的变量B存入本地存储,再刷新页面从缓存中获取更新后的变量A值。
注意事项:
- 若组件A与B在同一页面,刷新会显得突兀,但如果是通过页面跳转(如切换菜单)时执行刷新,体验较好。
- 界面刷新后全局状态会重置,需通过
localStorage
或sessionStorage
保存数据。 - 此方式性能较差,适用于小规模场景。
解决二:添加监听事件
通过事件监听来处理变量B的变化,在修改B时发布事件,模块响应事件并更新变量A。
优势:
- 避免整个模块重新执行,灵活更新指定数据。
- 相较其他方案,对原代码改动较小,适合逻辑较复杂的项目。
解决三:将 export
变量改为 export
方法
将模块中导出的变量A改为方法,通过调用方法重新计算变量A的值。
改造示例:
// myModule.js
import { getLisiAge } from './base'
console.log('执行 myModule.js')
export const getLisiObj = () => {
return {
name: '李四',
age: getLisiAge()
}
}
在组件中调用 getLisiObj()
方法,每次获取A时都会重新计算,保证变量值是最新的。
解决四:使用状态管理
对于需要频繁引用的变量,可以使用状态管理工具(如 vuex
)。状态管理工具通过统一的方法修改和获取变量,灵活应对变量变化。
优势:
- 适合复杂项目,提升代码的可维护性。
- 即便变量初始是常量,后续需求改变时也能灵活应对。
结语
不同场景下,选择合适的解决方案非常重要。本文列举了几种思路,欢迎大家根据实际需求选择,并分享你们的经验和其他解决方法。