[global-variables] What is the best way to declare global variable in Vue.js?

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.

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


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:

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