Sharing Data Between Components in Vue.js
Tags: vue, javascript, frontend, beginners
Published: 2018-11-29 23:06:40

---
title: Sharing Data Between Components in Vue.js
published: true
description: A tutorial on generating data in one component, and passing it to another in Vue.js.
tags: Vue.js, Javascript, Vue, frontend, beginners
cover_image: https://scontent-iad3-1.cdninstagram.com/vp/3da28287bed980a03096a2ba1e7ce0e3/5CA669DE/t51.2885-15/e35/20766913_166159657288547_5652710636992331776_n.jpg
---

In this tutorial, we'll explore generating data in one component, and passing it to another in [Vue.js](https://vuejs.org/). 

**TL;DR**
Here is an example of a working CodeSandbox
https://codesandbox.io/s/l4yj6jxpqz
![working-example](https://thepracticaldev.s3.amazonaws.com/i/2n8ll0586j6qtn0wdp8v.gif "working example")

####Why would we need to do this?
If you've worked on a large-scale Vue application, chances are, at some point you've wanted to generate data in one component and then do something with it in a separate component. In this tutorial, we will pass user inputted text from one component and display it as a list in another. We will not be using any dependencies outside of Vue.js.

####How do we do this?
First, we'll need to have Vue.js up and running. This is covered [here](https://vuejs.org/v2/guide/), or you can set up a [CodeSandbox](https://codesandbox.io).

If you used the Vue CLI or CodeSandbox to set up your app, you'll likely already have the initial structure of your project in place. In case you don't, we'll need a place to display our future components.


```html
// App.vue file
<template>
  <div id="app">
  </div>
</template>
<script>
  export default {
    name: "App"
  }
</script>
```
The above code is a good starting point for this tutorial. In the provided [CodeSandbox example](https://codesandbox.io/s/l4yj6jxpqz), **this file is named `App.vue`**. The code shown here will serve as the foundation for displaying the components we will build.

**Next, we'll start building our components.**

In the [example](https://codesandbox.io/s/l4yj6jxpqz) listed, there have been two components created in a folder named `components`.
 
![file structure](https://thepracticaldev.s3.amazonaws.com/i/d4qvos4gv2jrrtqasse6.JPG "Vue.js file structure")


The first file we'll look at is **UsrMsg.vue**.

```html
// UsrMsg.vue file
<template>
  <div>
    <input
      placeholder="Enter Text Here"
      v-model="tempMessage"
      @keyup.enter="submit"
    />
  </div>
</template>

<script>
export default {
  name: "UsrMsg",
  data() {
    return {
      tempMessage: ""
    };
  },
  methods: {
    submit: function() {
      this.$emit("inputData", this.tempMessage);
      this.tempMessage = "";
    }
  }
};
</script>
```
In this file, you'll see an `input` element. The `input` element updates the data field `tempMessage` by using Vue's `v-model`.

```html
<input
    placeholder="Enter Text Here"
    v-model="tempMessage"
    @keyup.enter="submit"
/>
```
Upon hitting `enter`, the method `submit` is called. Inside this method, we use `$emit` _(emit: "to send out a beam")_ to make `tempMessage` available to a parent component. `$emit` takes a string as the first parameter, in this case, `inputData`. It can also accept a second parameter, which is usually a piece of data. In our example, we are passing the value of  `tempMessage`. This could also be an integer, a variable, an array, or an object. You'll also notice that we set `tempMessage = ""` after the `$emit`. This clears out the input field to accept the next value.

```javascript
submit: function() {
    this.$emit("inputData", this.tempMessage);
    this.tempMessage = "";
}
```
Let's add the `UsrMsg` component to our `App.vue` file.

```html
// App.vue file
<template>
  <div id="app">
    <UsrMsg @inputData="updateMessage" />
  </div>
</template>

<script>
import UsrMsg from "./components/UsrMsg";

export default {
  name: "App",
  components: {
    UsrMsg
  },
  data: function() {
    return {
      childData: ""
    };
  },
  methods: {
    updateMessage(variable) {
      this.childData= variable;
    }
  }
};
</script>

```
First, we want to make the data that we are emitting from the component available. We do that by adding a listener around the data we are emitting. We chose `inputData` as the data name in our component, so this will be our listener. The second piece executes a method called `updateMessage`.
```html
<UsrMsg @inputData="updateMessage" />
``` 
Whenever the data inside our component changes, the `updateMessage` method will be executed. Inside this method, we make the component data available through the data field `childData`. It's now ready to be passed as a prop to another component.  
```javascript
updateMessage(variable) {
    this.childData= variable;
}
```
Now, let's build the component we will be passing the data to.

We'll start by creating a file named **Results.vue**.

```html
// Results.vue file
<template>
  <div>
    <li v-for="(message, index) in messageList" :item="message" :key="index">
      {{ message }}
    </li>
  </div>
</template>

<script>
export default {
  name: "Results",
  props: {
    msg: {
      type: String
    }
  },
  data: function() {
    return {
      messageList: []
    };
  },
  watch: {
    msg: function() {
      this.messageList.push(this.msg);
    }
  }
};
</script>

```

In this example, we are creating a list based off an array called `messageList`. It is not required to push the data into an array but it is a bit more exciting for demo purposes.😜

```html
<li v-for="(message, index) in messageList" :item="message" :key="index">
    {{ message }}
</li>
```
The `messageList` array is keying off the data prop `msg`. 
```javascript
props: {
    msg: {
      type: String
    }
}
```
As data is passed to this component, through the data prop `msg`, it is pushed to the `messageList` array. We use the `watch` property to add on to the array upon new data in the `msg` prop.

```javascript
watch: {
    msg: function() {
      this.messageList.push(this.msg);
    }
}
```
Our `<li>` element will update when new items are added to the `messageList` array.

Now, we can add the Results component to our `App.vue` file.

```html
<template>
  <div id="app">
    <UsrMsg @inputData="updateMessage" /> <Results :msg="childData" />
  </div>
</template>

<script>
import UsrMsg from "./components/UsrMsg";
import Results from "./components/Results";

export default {
  name: "App",
  components: {
    UsrMsg,
    Results
  },
  data: function() {
    return {
      childData: ""
    };
  },
  methods: {
    updateMessage(variable) {
      this.childData = variable;
    }
  }
};
</script>
```

We add in our component `Results` and pass in `childData` through the prop `msg`.

```html
<Results :msg="childData" />
```

We can now generate data in the `UsrMsg` component and pass it through to the `Results` component.


{% codesandbox l4yj6jxpqz %}