Vue中如何监听从外部JS文件导入的变量变化?
核心问题原因
- 基础类型值拷贝问题:
a是布尔值属于基础数据类型,你代码中export var loadingvar = a只是将a初始化时的false值复制给loadingvar,后续修改a的值时,loadingvar不会同步更新,二者是完全独立的变量。 - 非响应式数据无法监听:普通JS变量没有被Vue响应式系统代理,Vue的watch只能监听实例自身的
data、props、computed等响应式属性的变化,外部普通变量的变更Vue无法感知。 - 组件data初始化时的赋值是一次性值拷贝:
test: loadingvar只是把loadingvar的初始值赋值给组件内的test变量,后续loadingvar的变更不会同步到test,watch自然不会触发。
解决方案
方案一:修改get.js用引用类型存储状态,接入Vue响应式系统
因为引用类型的属性变更可以被Vue追踪,我们把加载状态存在对象里导出:
// get.js修改后代码 var a = false // 导出引用类型的状态对象 export const loadingState = { loadingvar: a } export function get(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = () => { // 修改对象的属性而不是基础变量 loadingState.loadingvar = true if (xhr.status === 200) { resolve(xhr.response) } else { reject(xhr) } } xhr.onerror = () => { reject(xhr) } xhr.onloadstart =() => { // 修改对象的属性而不是基础变量 loadingState.loadingvar = false } xhr.open('GET', url); xhr.send(); }); }
组件内修改为监听状态对象的对应属性:
import { get, loadingState } from './get'; export default { template: '#calendar', name: "Calendar", data() { return { // 把状态对象直接挂载到data,成为响应式数据 loadingState: loadingState, } }, watch: { 'loadingState.loadingvar'(newVal) { console.log(newVal) // 此时可以正常触发 } } }
方案二:调用接口时手动更新组件内响应式状态
如果不想改动get.js的代码,可以在调用get方法的前后手动更新组件内的响应式变量:
// 组件内调用接口的逻辑 this.test = false get('/你的接口地址') .then(res => { // 处理接口返回逻辑 }) .catch(err => { // 处理报错逻辑 }) .finally(() => { this.test = true })
内容的提问来源于stack exchange,提问作者BeHFaR
相关产品推荐
相关产品推荐

