我的vue项目中设置了两个路径,当路径为a时渲染A组件,当路径为b时渲染B组件。两个组件都需要可以访问并修改x变量。因此必须设置全局变量x和修改x变量的全局函数changeX。
因为项目比较小,我没有使用vuex,在网上搜了一下大家好像都是在Vue.prototype来定义全局函数,如何定义全局变量我没有找到。
无意中,我发现可以在根目录的index.html里,在<script src="/dist/build.js"></script>
(这是经过webpack打包后引入的文件)之前再放插入一个<script>标签,标签内声明的变量和函数可以在任意组件中访问。像下面这样
//index.html
<body>
<div id="app">
<router-view></router-view>
</div>
<script>
//定义全局变量与全局函数,在任意组件中都能访问与使用。
let x
function changeX () {
//对x进行操作
}
</script>
<script src="/dist/build.js"></script>
</body>
在上面这种情况下,A组件和B组件中均可调用changeX函数,如:
//B.vue
<script>
export default {
methods:{
aaa:function(){
changeX()
}
}
}
</script>
上面这样是可行的,但是当全局函数和全局变量很多的时候放在index.html会很难看,于是我就写专门写了一个global.js文件,把x和changeX放到里面,然后用<script>标签引到index.html中,如下:
//index.html
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="./src/global.js"></script> //里面放x和changeX
<script src="/dist/build.js"></script>
</body>
这时再运行,控制台报错:“changeX不是一个函数”。
把同样的js代码从文件中引过来和直接放在<script>标签中出现了不一样的效果,这是为什么呢?
另外一个问题,main.js是webpack的入口,我们在里面引入组件,定义Vue实例,我直接在这个文件里定义变量和函数,在组件中也是不能访问的,如下:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
let x //在组件中无法访问
function changeX () {...} //在组件中无法访问
import A from './components/A.vue';
import B from './components/B.vue';
let routes = [
{path:'/', component: A},
{path:'/:id', name:'user',component: B}
];
let router = new VueRouter({
mode: 'history',
routes
})
new Vue({
router,
el: '#app'
})
我实在被作用域的问题给搞迷糊了,现在只能把全局的东西都写在index.html中,有懂的前辈希望指点一下。
既然楼主写了个global.js文件,就可以考虑遵循模块化的概念,使用import在各个组件中引用
下面从利于楼主理解的角度来说明,可能会存在一些不严谨的地方:
关于作用域问题,简单来说,你访问不到不是因为作用域不正确,而是打包工具通过修改变量名,包裹函数,等等多种方法帮你做到了隔离作用域,这样做的好处就是为了保证每个组件,每个模块都是相对独立的.
楼主如果感兴趣可以看看编译之后的代码,webpack之类的打包工具会讲每一个模块,包括入口文件(入口文件也被认为是一个模块)包裹成一个函数,函数返回值导出引用,所以不论你变量怎么写,看似作用域在window下,实际上已经被包裹进了函数中,这也是遵循了ES6_module或者commonjs模块的规范
推荐楼主使用import去引用global.js
如果楼主一定想要按上面的方法来实现,可以考虑把全局变量和方法挂载在window下,比如 window.xxx