Vue comes with it's own unique levels of scope, in addition to what Javascript has already.

Scope controls what variables can be used and where. It controls how "visible" they are to different parts of the application.

Understanding the differences between the levels of scope that Vue gives you will help you to write clearer code.

These are the 4 unique levels of scope:

  • 🌍 Global scope
  • 🌲 Sub-tree scope
  • ⚙️ Component scope
  • 🐶 Instance scope

Let's explore what these scopes are.

🌍 Global scope

Global scope in a Vue application is like global scope in any programming language — these variables are available anywhere in the application.

You can also think of this scope as app scope, because it scopes the variable to the entire application.

Using global scope

The main technique for using global scope is to add a value to the Vue prototype:

Vue.prototype.$globalValue = 'Global Scope!';

By adding it to the prototype of the Vue object, it's automatically available on every single component in our application. You can access it directly off of the component like this:

export default {
  mounted() {
    console.log(this.$globalValue);  // 'Global Scope!'
  },
};

It's a standard practice to prefix these variables with a $, so we know that they are global values and not unique to each component.

Vue, vue-router, and vuex (and many other libraries) all use this technique to define global values. For example, the $route object from vue-router is a globally scoped variable like this.

You can also use Vuex or any other state management system to create global scope.

🌲 Sub-tree scope

Most of the time global scope is a bit of a sledgehammer, and you need something a little more precise.

The next level of scope is sub-tree scope, where a variable is scoped to a specific part of the application instead of the whole thing.

This level of scope is probably the least used, but is extremely handy when you do need to use it. Oftentimes a group of components need to share a lot of the same data, and passing it through props gets very tedious.

This scope is best used to share contextual information that can change based on where a component is in the application. This can be things like:

  • Local state and data — no need to make state global using Vuex if only a small part of the application needs it. And if passing it around using props gets tedious and cumbersome, sub-tree scope might just be what you need.
  • Configuration — sometimes you might need components in to behave a certain way, but only in part of your application. For example, all the Input components in a registration form should require validation, but you don't want to require validation in the whole application.

Using sub-tree scope

Sub-tree scope is created by using provide and inject. You provide the values you want to be available to the entire sub-tree, and then inject them into the components that need them.

In fact, being able to scope this way is the main reason that these two features exist.

⚙️ Component scope

A little more specific, component scope makes a variable available to a single component.

But this shouldn't be confused with the more specific instance scope.

If a variable has component scope, it is a single variable that's available to all instances of a component. You can have several of the same component, and they'll all be able to access the same variable.

You may be familiar with this as module scope in Javascript. Anything defined in a single module — or file — is all in the same module scope. Since a component is defined in a single file, everything in the component is in the same module scope.

Using component scope

To use component scope we need to define a variable in the same file as our component:

<template>
  <div class="new-component">
    {{ componentScope }}
  </div>
</template>

<script>
const componentScope = 'This is in the component scope';

export default {
  data() {
    return {
      componentScope: componentScope,
    };
  },
};
</script>

The variable componentScope that gets rendered in this component is the same variable, no matter how many times this component is used. There aren't multiple copies of componentScope.

If one instance of this component modifies the value of componentScope, it will change for every single other instance of this component. This shouldn't be used to communicate between this components, but it is a good way of sharing data.

On to our final level of scope!

🐶 Instance scope

Instance scope is the most specific form of Vue scope you can get.

Any variable that has instance scope is only available to a specific usage of the component. We often refer to this as internal state or sometimes local state.

Using instance scope

Whenever you use the data() function or use computed props, you're using instance scope.

Even adding properties directly to the component instance can get you this effect:

someMethod() {
  this.newProperty = 'Instance scope';
}

But if you add properties this way, you have to remember that they won't be reactive.