【发布时间】:2018-01-28 20:44:08
【问题描述】:
我有一个 javascript 变量,我想在实例化时将其全局传递给 Vue 组件,因此每个注册的组件都将其作为属性,或者可以全局访问。
注意:: 我需要将 vuejs 的这个全局变量设置为 READ ONLY 属性
【问题讨论】:
标签: vue-component vue.js vuejs2
我有一个 javascript 变量,我想在实例化时将其全局传递给 Vue 组件,因此每个注册的组件都将其作为属性,或者可以全局访问。
注意:: 我需要将 vuejs 的这个全局变量设置为 READ ONLY 属性
【问题讨论】:
标签: vue-component vue.js vuejs2
比如所有组件都可以访问一个全局的appName,你只需要写一行代码:
Vue.prototype.$appName = 'My App'
$ 不是魔法,它是 Vue 用于所有实例的属性的约定。
或者,您可以write a plugin 包含所有全局方法或属性。
【讨论】:
this.$appName = 'Changed' 更改此设置时,其他组件不会注意到此更改。你如何改变这个全局变量?
您可以使用Global Mixin 来影响每个 Vue 实例。你可以向这个 mixin 添加数据,使一个/多个值可用于所有 vue 组件。
要使该值只读,您可以使用this Stack Overflow answer 中描述的方法。
这是一个例子:
// This is a global mixin, it is applied to every vue instance.
// Mixins must be instantiated *before* your call to new Vue(...)
Vue.mixin({
data: function() {
return {
get globalReadOnlyProperty() {
return "Can't change me!";
}
}
}
})
Vue.component('child', {
template: "<div>In Child: {{globalReadOnlyProperty}}</div>"
});
new Vue({
el: '#app',
created: function() {
this.globalReadOnlyProperty = "This won't change it";
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>
<div id="app">
In Root: {{globalReadOnlyProperty}}
<child></child>
</div>
【讨论】:
this.globalReadOnlyProperty。
axios.get(API_URL + '/videos')
在带有 createApp() 的 VueJS 3 中,您可以使用 app.config.globalProperties
像这样:
const app = createApp(App);
app.config.globalProperties.foo = 'bar';
app.use(store).use(router).mount('#app');
并像这样调用你的变量:
app.component('child-component', {
mounted() {
console.log(this.foo) // 'bar'
}
})
文档:https://v3.vuejs.org/api/application-config.html#warnhandler
如果您的数据是响应式的,您可能需要使用 VueX。
【讨论】:
你可以像这样使用 mixin 和改变 var。
// This is a global mixin, it is applied to every vue instance
Vue.mixin({
data: function() {
return {
globalVar:'global'
}
}
})
Vue.component('child', {
template: "<div>In Child: {{globalVar}}</div>"
});
new Vue({
el: '#app',
created: function() {
this.globalVar = "It's will change global var";
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>
<div id="app">
In Root: {{globalVar}}
<child></child>
</div>
【讨论】:
data: 是一个函数。因此,@amin 的上述示例提供了全局值的副本,并且他的示例也没有证明可以更改它。如果你想要可变的全局变量和状态,那么你真的应该使用 Vuex。
你可以使用 Vuex 来处理你所有的全局数据
【讨论】:
如果全局变量不应该被任何东西写入,包括 Vuejs,你可以使用Object.freeze 来冻结你的对象。将它添加到 Vue 的视图模型不会解冻它。
另一种选择是为 Vuejs 提供对象的冻结副本,如果该对象打算在全局范围内编写但不是由 Vue 编写:var frozenCopy = Object.freeze(Object.assign({}, globalObject))
【讨论】:
在你的 main.js 文件中,你必须像这样导入 Vue:
import Vue from 'vue'
然后你必须像这样在 main.js 文件中声明你的全局变量:
Vue.prototype.$actionButton = 'Not Approved'
如果你想从另一个组件改变全局变量的值,你可以这样做:
Vue.prototype.$actionButton = 'approved'
https://vuejs.org/v2/cookbook/adding-instance-properties.html#Base-Example
【讨论】:
在 main.js(或任何其他 js 文件)中
export const variale ='someting'
在 app.vue(或任何其他组件)中
import {key} from '../main.js' (file location)
在数据方法中定义变量的键并使用它。
【讨论】:
如果您想在多个组件中使用变量,但又不想污染全局范围。在这些情况下,您可以通过在Vue prototype 上定义它们来使它们对每个Vue instance 可用:
Vue.prototype.$yourVariable = 'Your Variable'
请记住在您的项目入口点创建Vue instance 之前添加此行,大部分时间是main.js
现在$yourVariable 可用于所有Vue instances,甚至在创建之前。如果我们运行:
new Vue({
beforeCreate: function() {
console.log(this.$yourVariable)
}
})
然后"Your Variable" 将被记录到控制台!
文档:https://vuejs.org/v2/cookbook/adding-instance-properties.html#Base-Example
如果想让这个变量不可变,可以使用静态方法Object.defineProperty():
Object.defineProperty(Vue.prototype, '$yourVariable', {
get() {
return "Your immutable variable"
}
})
默认情况下,此方法将防止您的变量从Vue prototype 中删除或替换
如果您想更进一步,假设您的变量是一个对象,并且您不希望对您的对象进行任何更改,您可以使用Object.freeze():
Object.defineProperty(Vue.prototype, '$yourVariable', {
get() {
return Object.freeze(yourGlobalImmutableObject)
}
})
【讨论】:
一种可能性是在 index.html 中声明变量,因为它实际上是全局的。可以添加一个javascript方法来返回变量的值,它将是只读的。我确实喜欢这样:
假设我有 2 个全局变量(var1 和 var2)。只需将以下代码添加到 index.html 标头:
<script>
function getVar1() {
return 123;
}
function getVar2() {
return 456;
}
function getGlobal(varName) {
switch (varName) {
case 'var1': return 123;
case 'var2': return 456;
// ...
default: return 'unknown'
}
}
</script>
可以为每个变量执行一个方法,也可以使用一个带有参数的方法。
这个解决方案适用于不同的 vuejs mixin,它是一个真正的全局值。
【讨论】: