问题
PM提了个需求:查询广告 接口上送的 PlayRuleId(广告字段)的值改成可配置的,而这个值会在 查询数据字典 接口中返回。
交易流程:调用 查询数据字典 接口,然后将结果存储到 store 里,数据字典文件通过一个 getDictJson 函数获取到处理后的数据字典,在需要使用数据字典的页面 import 数据字典文件对应变量即可。
数据字典文件 newCenterDict.js 如下:
其中 dictTran.js 如下:
由于,查询数据字典 与 查询广告 接口是在同一个vue页面 shopShow.vue,因此我在 shopShow.vue 中 import newCenterDict.js 中的变量时,会导致变量是 [],并且会导致后续路由到的界面(凡是import newCenterDict.js文件中的变量)都获取到 []。
记得阮一峰老师在ES6中对于模块加载有说过:ES6 的 import 原始值变了,import加载的值也会跟着变,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。但是现在遇到的情况好像不是这样,因为阮老师博客验证的是基本类型赋值,于是我写了个 demo 来验证我的一些猜想。
探究
我直接用 vue-cli 搭建了个 vue 工程,然后简单配置了两个路由,分别从 App.vue 路由到 test.vue、anotherTest.vue。
demo 目录如下:
猜想:export 的变量是引用赋值,被引用对象改变,import 的变量会跟着变
验证一
思路:模块 export 一个方法,该方法可以改变模块中变量的引用。
test1.js:
let Obj = {
key : '1'
};
export var Big_Value = Obj;
export function change_BigValue() {
Obj.key = '2';
console.log('test1.js里,change_BigValue调用,Big_Value值为:');
console.log(Big_Value)
}
test.vue:
<template>
<div>
<h1>测试</h1>
<div @click="back">返回</div>
</div>
</template>
<script>
import router from '../../router/index';
import { Big_Value, change_BigValue } from '../../test1';
export default {
created() {
console.log('test.vue创建时 Big_Value:');
console.log(Big_Value);
change_BigValue();
console.log('test.vue调用 change_BigValue 后 Big_Value:');
console.log(Big_Value);
},
methods: {
back() {
router.push('/')
}
}
}
</script>
结果:
验证二
思路:模块里通过 setTimeout 在5秒后改变导出的变量值,在引入变量的页面先打印该值,然后在10秒后再打印一次。
test1.js
let Obj = {
key : '1'
};
export var Big_Value = Obj;
setTimeout(() => {
Obj.key = '2';
console.log('test1.js里,在5秒后 Big_Value 变成:');
console.log(Big_Value);
}, 5000);
anotherTest.vue
<template>
<div>
<h1>另一个测试</h1>
<div @click="back">返回</div>
</div>
</template>
<script>
import { Big_Value } from '../../test1';
import router from '../../router/index';
export default {
created() {
console.log('anotherTest.vue创建时:');
console.log(Big_Value);
setTimeout(() => {
console.log('来自anotherTest,10秒后 Big_Value:');
console.log(Big_Value);
}, 10000);
},
methods: {
back() {
router.push('/')
}
}
}
</script>
结果:
验证三
还有一种引用类型-函数。虽然在 Js 中,函数也是对象。但是我遇到的问题,就是通过函数取值的。所以在此需要验证一下。
test1.js:
console.warn('test1.js执行');
let a = "1"
function getValue() {
setTimeout(() => {
a = '2';
console.log('5秒后 getValue 将 a 变成:' + a);
console.log('此时 Big_Value:' + Big_Value);
}, 5000);
return a;
}
export var Big_Value = getValue();
console.log('test1.js刚执行时,Big_Value:' + Big_Value);
test.vue:
<template>
<div>
<h1>测试</h1>
<div @click="back">返回</div>
</div>
</template>
<script>
import router from '../../router/index';
import { Big_Value } from '../../test1';
export default {
created() {
console.log('test.vue创建时 Big_Value:' + Big_Value);
setTimeout(() => {
console.log('来自test.vue,10秒后 Big_Value:' + Big_Value);
}, 10000);
},
methods: {
back() {
router.push('/')
}
}
}
</script>
anotherTest.vue
<template>
<div>
<h1>另一个测试</h1>
<div @click="back">返回</div>
</div>
</template>
<script>
import { Big_Value } from '../../test1';
import router from '../../router/index';
export default {
created() {
console.log('anotherTest.vue创建时:' + Big_Value);
},
methods: {
back() {
router.push('/')
}
}
}
</script>
结果:
结论
综上:ES6 的模块加载,import 加载的值,如果是通过调用函数得到的返回值,该函数若内部返回值发生改变,加载的值并不会发生改变(并不会重新调用函数去获取返回值)。