Skip to content

The Vue.js 101 - Sharing data between components

#javascript #learning #vuejs2 #framework #code
The Vue.js 101 series is about things I wish someone had told me about when I first started working with the framework. Components often need to react to what happens in another component. But how exactly do they know when something is updated elsewhere? Let's explore this one.

In Vue.js, there are three main types of interactions you should be aware of when it comes down to the communication between components:

  • passing data to a child component
  • passing data to a parent component
  • globally available data that any component can access

Props

The easiest way to pass data from a parent component to its child is through the props attribute. They let you define what sort of data your child component is expecting in order to render properly. You can define the props as an array of names, or you can go the more elaborate way to ensure that your component receives a suitable type of data.

// method 1
Vue.component('component-example', {
  props: ['age', 'name', ‘userType’],
})

// method 2
Vue.component('component-example', {
  props: {
    age: Number,
    name: {
      type: String,
      required: true
    },
    userType: {
      type: String,
      default: ‘guest’
    }
  }
})

The second method offers prop validation, which means that it will give you a warning if you are trying to pass data that doesn’t match the type the child component is expecting, and you will also receive a warning if you fail to pass a prop that was flagged as required.

The default attribute lets you predefine a value even if you don’t pass any data to the prop. In case of Object types, default values have to be defined through a function.

Vue.component('component-example', {
  props: {
    favorites: {
      type: Object,
      default: () => ({})
    }
  }
})

Events

But what if you want to pass data from the child component back to the parent? Events serve exactly this purpose, through the built-in $emit method.

<!-- in the child component: -->
<button v-on:click="$emit(‘childClicked’, ‘foo’)">Click me</button> <!-- v-on:click is a built-in event -->
<button @click="$emit(‘childClicked’, ‘foo’)">Click me</button> <!-- @ is a useful shorthand for v-on: -->
<!-- in the parent component: -->
<child v-on:childClicked="logMe"></child>
<child v-on:child-clicked="logMe"></child> <!-- this variant is using kebab-case, it will work even if you define your event name in camel case -->

The $emit method first registers the event, and takes the event name as a first parameter. It lets you pass a value as its second parameter. You can of course use $emit within your script tag, which allows you to pass more elaborate values.

<button @click=”passMyVal”>Click me</button>
methods: {
  passMyVal() {
    var myVal = Math.floor(Math.random() * 10) + 1
    this.$emit(‘childClicked’, myVal)
  }
}

The parent can process the value passed to the event:

methods: {
  logMe(num) {
    console.log(num)
  }
}

Vuex

Vuex is a state management tool that creates a container called store, in which you can have information that any of your components are able to access. So what kind of information should you put here?

When you first start using Vuex, it’s very tempting to put everything in the store, because who knows when you might need that data in some component, right? Wrong.

The Vuex store is best used when you have to keep track of data that might alter your application’s behavior altogether, data that might also change based on the way the user is interacting with the app. What does this mean?

For example, you create a tutorial and you need to keep track of which chapter the user is at. This information will be used by the navigation bar that might change automatically based on the user’s progress, and it will also be used by your main content. This is supposed to be application-level data.

Think of how sessionStorage would be used – Vuex has many similarities.

  • It works on the client side only (unlike cookies which can also be accessed by the server)
  • It’s automatically deleted on forced page refresh or tab close (unlike localStorage which persists through refresh and close)

There are several advantages over a regular sessionStorage. Actions and mutations are Vuex-specific methods which lets you define how you want to alter (mutations) or send/receive (actions) the store information to and from the backend. These methods are accessible for all of your components. Unlike sessionStorage, Vuex store also retains your data structure, therefore you can store specific types of data (objects, arrays) unchanged, while sessionStorage only handles strings.

How do you know when you need Vuex?

You definitely don’t need a Vuex store for every application. It can become an overhead for smaller apps and single-page-applications. However, if you are building a more complex website that needs to track user-related information through several stages of progress, Vuex will be invaluable. A good example is a webshop frontend where the cart information can be stored in the Vuex store.

End of article