Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to declare global variables in Vue.js?

I need access to my hostname variable in every component.

Is it a good idea to put it inside data?

Am I right in understanding that if I do so, I will able to call it everywhere with this.hostname?

like image 747
Dmitry Bubnenkov Avatar asked May 21 '16 20:05

Dmitry Bubnenkov


People also ask

Where should I declare global variables?

If you intend to use the global variables in multiple . c files, it is better to declare them in . h files. However, if you want to keep the variables like private member data of classes in C++, it will be better to provide access to the global data through functions.

Is it good to declare global variables?

Using global variables causes very tight coupling of code. Using global variables causes namespace pollution. This may lead to unnecessarily reassigning a global value. Testing in programs using global variables can be a huge pain as it is difficult to decouple them when testing.


2 Answers

As you need access to your hostname variable in every component, and to change it to localhost while in development mode, or to production hostname when in production mode, you can define this variable in the prototype.

Like this:

Vue.prototype.$hostname = 'http://localhost:3000' 

And $hostname will be available in all Vue instances:

new Vue({   beforeCreate: function () {     console.log(this.$hostname)   } }) 

In my case, to automatically change from development to production, I've defined the $hostname prototype according to a Vue production tip variable in the file where I instantiated the Vue.

Like this:

Vue.config.productionTip = false Vue.prototype.$hostname = (Vue.config.productionTip) ? 'https://hostname' : 'http://localhost:3000' 

An example can be found in the docs: Documentation on Adding Instance Properties

More about production tip config can be found here:

Vue documentation for production tip

like image 169
Josiel Faleiros Avatar answered Sep 21 '22 21:09

Josiel Faleiros


Warning: The following answer is using Vue 1.x. The twoWay data mutation is removed from Vue 2.x (fortunately!).

In case of "global" variables—that are attached to the global object, which is the window object in web browsers—the most reliable way to declare the variable is to set it on the global object explicitly:

window.hostname = 'foo'; 

However form Vue's hierarchy perspective (the root view Model and nested components) the data can be passed downwards (and can be mutated upwards if twoWay binding is specified).

For instance if the root viewModel has a hostname data, the value can be bound to a nested component with v-bind directive as v-bind:hostname="hostname" or in short :hostname="hostname".

And within the component the bound value can be accessed through component's props property.

Eventually the data will be proxied to this.hostname and can be used inside the current Vue instance if needed.

var theGrandChild = Vue.extend({    template: '<h3>The nested component has also a "{{foo}}" and a "{{bar}}"</h3>',      props: ['foo', 'bar']  });    var theChild = Vue.extend({    template: '<h2>My awesome component has a "{{foo}}"</h2> \               <the-grandchild :foo="foo" :bar="bar"></the-grandchild>',    props: ['foo'],    data: function() {      return {        bar: 'bar'      };    },    components: {      'the-grandchild': theGrandChild    }  });      // the root view model  new Vue({    el: 'body',    data: {      foo: 'foo'    },    components: {      'the-child': theChild    }  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.js"></script>  <h1>The root view model has a "{{foo}}"</h1>  <the-child :foo="foo"></the-child>

In cases that we need to mutate the parent's data upwards, we can add a .sync modifier to our binding declaration like :foo.sync="foo" and specify that the given 'props' is supposed to be a twoWay bound data.

Hence by mutating the data in a component, the parent's data would be changed respectively.

For instance:

var theGrandChild = Vue.extend({    template: '<h3>The nested component has also a "{{foo}}" and a "{{bar}}"</h3> \               <input v-model="foo" type="text">',      props: {        'foo': {          twoWay: true        },          'bar': {}      }  });    var theChild = Vue.extend({    template: '<h2>My awesome component has a "{{foo}}"</h2> \               <the-grandchild :foo.sync="foo" :bar="bar"></the-grandchild>',    props: {      'foo': {        twoWay: true      }    },    data: function() {      return { bar: 'bar' };    },      components: {      'the-grandchild': theGrandChild    }  });    // the root view model  new Vue({    el: 'body',    data: {      foo: 'foo'    },    components: {      'the-child': theChild    }  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.js"></script>  <h1>The root view model has a "{{foo}}"</h1>  <the-child :foo.sync="foo"></the-child>
like image 32
Hashem Qolami Avatar answered Sep 21 '22 21:09

Hashem Qolami