0% found this document useful (0 votes)
21 views

Smashingmagazine Com 2020 01 Data Components Vue Js

This document summarizes three common ways to pass data between components in Vue.js: 1. Using props to pass data from a parent component to a child component. Props allow declaring custom attributes that child components can access. 2. Emitting custom events to pass data from a child component to a parent component. A child can emit an event using $emit which the parent can listen for using v-on. 3. Using Vuex to create a centralized state that any component can access. Vuex allows components to commit mutations that update the state and access the state via getters.

Uploaded by

Arjun Gautam
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views

Smashingmagazine Com 2020 01 Data Components Vue Js

This document summarizes three common ways to pass data between components in Vue.js: 1. Using props to pass data from a parent component to a child component. Props allow declaring custom attributes that child components can access. 2. Emitting custom events to pass data from a child component to a parent component. A child can emit an event using $emit which the parent can listen for using v-on. 3. Using Vuex to create a centralized state that any component can access. Vuex allows components to commit mutations that update the state and access the state via getters.

Uploaded by

Arjun Gautam
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

Menu

Search articles...

ABOUT TH E AUTH OR

Matt Maribojoc runs LearnVue.co, studies at the University of


Pittsburgh, and shares his programming thoughts online.
More
More
More
Moreabout
about
about
aboutMatt
Matt
Matt
Matt……

J ANU AR Y 22, 2020 11112222comment


comment
comment
commentssss

How To Pass Data


Between Components In
Vue.js
11 min read
Vue
Vue
Vue,
Vue
Vue JavaScript
JavaScript
JavaScript
JavaScript
Share onTwitter
Twitter
Twitter
Twitteror LLinkedIn
LinkedIn
LinkedIn
inkedIn

Q U I C K S U M M A RY ↬ With so many different


ways to share data across components, you should
know which technique is best for your situation.
Let’s analyze three of the most common ways to
pass data in VueJS.

SHARING DATA ACROSS

components is one of the core


functionalities of VueJS. It
allows you to design a more
modular project, control data scopes, and
create a natural flow of data across your app.

Unless you’re creating your entire Vue app in one


component (which wouldn’t make any sense), you’re
going to encounter situations where you need to
share data between components.

By the end of this tutorial, you will know three ways


to get this done.

Using
Using
Using
Usingprops
props
props
propsto
to
to
toshare
share
share
sharedata
data
data
data from parent to child,

Emitting
Emitting
Emitting
Emittingcustom
custom
custom
customevents
events
events
eventsto share data from child
to parent,
Using
Using
Using
UsingVuex
Vuex
Vuex
Vuex to create an app-level shared state.

Okay — let’s get right into it!

BUILDING AN APP WITH NUXT

With Spotify, your friends can check out


what you’re jamming to. What if the rest of
the Internet could experience your algo-
rhythm, too? Learn how to compose your
own app to share what you’re listening to
on Spotify using Vue.js and Nuxt.

Read more →

More after jump! Continue reading below ↓

Our practical handbook, in which Alla


Kholmatova explores how to create
effective and maintainable design
systems to design great digital products.
Meet Design
Design
Design
DesignSystems
Systems
Systems,
Systems
Systems with common
traps, gotchas and the lessons Alla has
learned over the years.

Jump to table of contents ↬

1. Using Props To Share Data From


Parent To Child
VueJS props are the simplest way to share data
between components. Props are custom attributes
that we can give to a component. Then, in our
template, we can give those attributes values and —
BAM — we’re passing data from a parent to a child
component!

For example, let’s say we’re working on a user profile


page and want to have a child component accept a
username prop. We’ll need two components.

01 The child component accepting the prop, let’s


call this AccountInfo.vue .

02 The parent component passing the prop, let’s


call this ProfilePage.vue .

Inside AccountInfo.vue , we can declare the props it


accepts using the props option. So, inside the
component options, let’s make it look like the
following.

// AccountInfo.vue

<template>
<div id='account-info'>
{{username}}
</div>
</template>

<script>
export default {
props: ['username']
}
</script>

Then, to actually pass the data from the parent (


ProfilePage.vue ), we pass it like a custom
attribute.

// ProfilePage.vue

<account-info username='matt' />

Now if we load our page, we can see that our


AccountInfo component properly renders the value
passed in by its parent.

As when working with other VueJS directives, we


can use v-bind to dynamically pass props. For
example, let’s say we want to set the username prop
to be equal to a variable. We can accomplish this by
using shorthand for the v-bind directive (or just :
for short). The code would look a little like this:

<template>
<div>
<account-info :username="user.username" />
</div>
</template>

<script>
import AccountInfo from "@/components/AccountInf

export default {
components: {
AccountInfo
},
data() {
return {
user: {
username: 'matt'
}
}
}
}
</script>

This means that we can change our data and have


any child props using that value will also update.

TIP: ALWAYS VERIFY YOUR PROPS

If you’re looking to write clearer Vue code, an


important technique is to verify your props. In
short, this means that you need to specify the
requirements for your prop (i.e. type, format, and so
on). If one of these requirements is not met (e.g. if
the prop is passed an incorrect type), Vue will print
out a warning.

Let’s say we want our username prop to only accept


Strings. We would have to modify our props object
to look like this:

export default {
props: {
username: String
}
}

Verifying props is essential when working in large-


scale Vue apps or when designing plugins. It helps
ensure that everyone is on the same page and use
props the way that they were intended.

For a full list of the verifications we can include on


props, I’d definitely recommend checking out the
official documentation for an in-depth review.

TIP: FOLLOW PROP NAMING


CONVENTIONS

According to the VueJS style guide, the best way to


name your props is by using camelCase when
declaring them in your script and kebab-case when
referencing them in template code.

The reasoning behind this is actually quite simple. In


Javascript, camelCase is the standard naming
convention and in HTML, it’s kebab-case.

So, Vue recommends that we stick to the norms of


each language. Thankfully, Vue is able to
automatically convert between the two styles so
there’s no additional setup for developers.

// GOOD
<account-info :my-username="user.username" />
props: {
myUsername: String
}

// BAD
<account-info :myUsername="user.username" />
props: {
"my-username": String
}

2. Emitting Events To Share Data


From Child To Parent
Now that we have data passing down the hierarchy,
let’s pass it the other way: from a child component to
a parent. We can’t use props, but we can use custom
events and listeners.

Every Vue instance can call a .$emit(eventName)


method that triggers an event. Then, we can listen
for this event in the same way as any other, using
the v-on directive.

CREATING A CUSTOM EVENT

Let’s build on our user profile example by adding a


button that changes the username. Inside our child
component ( AccountInfo.vue ), let’s create the
button.

Then, when this button is clicked, we’ll emit an


event called changeUsername .

<template>
<div id='account-info'>
<button @click='changeUsername()'>Change User
{{username}}
</div>
</template>

<script>
export default {
props: {
username: String
},
methods: {
changeUsername() {
this.$emit('changeUsername')
}
}
}
</script>

Inside the parent, we handle this event and change


the user.username variable. Like we were
discussing earlier, we can listen to events using the
v-on directive or "@" for short.

<template>
<div>
<account-info :username="user.username" @chan
</div>
</template>

Let’s try it out. You should see that when you click
the button, the username changes to "new name".

TIP: CUSTOM EVENTS CAN ACCEPT


ARGUMENTS

The most common use case for passing arguments


to your events is when you want a child component
to be able to set a specific value for its prop. You
never want to directly edit the value of a prop from
the component itself.

However, luckily we can use pass arguments with


our custom events to make the parent component
change values.

Let’s say we want to modify the changeUsername


event so that we can pass it a value.

The $emit method takes an optional second


parameter for arguments. So all we do is add our
new username value after the name of our event.

this.$emit('changeUsername', 'mattmaribojoc')

Then, in our parent component, we can either access


these values inline by using a special $event
variable, or we can write a handler method that
takes a parameter.

<account-info :username="user.username" @changeU

OR

<account-info :username="user.username" @changeU

export default {
...
methods: {
changeUsername (username) {
this.user.username = username;
}
}
}

3. Using Vuex To Create An


Application-Level Shared State
Okay — we know how to share data between
parents/children, but what about other components?
Do we have to create an extremely complex
hierarchy system if we want to pass data?

Thankfully not. The wonderful Vuex state


management library has been simplifying
developers' lives for years. In short, it creates a
centralized data store that is accessible by all
components.

In the methods we used previously (props / emitting


events), each component has its own data state that
we then share between components. However, Vuex
lets us extract all the shared data into a single state
that each component can access easily. This shared
state is called a store.

Let’s try it out.

Because Vuex is separate from the core code of Vue,


we’ll first have to install and import it into our
project. First, we’ll have to run
npm install vuex --save inside our project CLI.

Then, create a src/store folder with an index.js file


that contains the following code.

// store/index.js

import Vue from "vue";


import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({


state: {},
getters: {},
mutations: {},
actions: {}
});

To include this in our root Vue instance, we have to


import our store/index.js file and pass it in our Vue
constructor.

// main.js

import store from "./store";

new Vue({
store,
...

ACCESSING VUE STORE INSIDE


COMPONENTS

Since we added our Vuex store onto our root Vue


instance, it gets injected into all of the root’s
children. If we want to access the store from a
component, we can via this.$store .

Now, let’s dive into the specifics of each of the four


parts of a Vuec store.

1. STATE

The Vuex state is an object that contains application-


level data. All Vue instances will be able to access
this data.

For our store, let’s create a user object that stores


some more user profile data.

export default new Vuex.Store({


state: {
user: {
username: 'matt',
fullName: 'Matt Maribojoc'
}
},
getters: {},
mutations: {},
actions: {}
});

We can access this data inside any instance


component like this.

mounted () {
console.log(this.$store.state.user.username);
},

2. GETTERS

We use Vuex getters to return a modified value of


state data. A good way to think of getters is to treat
them like computed properties. For example, getters,
like computed properties, cache their results and
only re-evaluate when a dependency is modified.

Building onto our earlier store, let’s say we want to


make a method that returns a user’s first name based
off the full name attribute.

getters: {
firstName: state => {
return state.user.fullName.split(' ')[0]
}
}

Vuex getter properties are available to components


on the store.getters object.

mounted () {
console.log(this.$store.getters.firstName);
}

Tip: Know the Default Getter Arguments

By default, Vuex getters accept two arguments.

01 state — the state object for our application;

02 getters — the store.getters object, meaning that


we can call other getters in our store.

Every getter you declare will require the first state


argument. And depending on how you design your
code, your getters can reference each other using
the second 'getters' argument.

Let’s make a last name getter that simply removes


our first name value from our full name state
property. This example would require both the state
and getters objects.

lastName (state, getters) {


return state.user.fullName.replace(getters.
}

Tip: Pass Custom Arguments to Vuex Getters

Another cool feature of getters is that we can pass


them custom arguments by making our getter
return a method.

prefixedName: (state, getters) => (prefix) => {


return prefix + getters.lastName;
}

// in our component
console.log(this.$store.getters.prefixedName("Mr

3. MUTATIONS

Mutations are the only way to properly change the


value of the state object. An important detail to note
is that mutations must be synchronous.

Like getters, mutations always accept the Vuex state


property as their first argument. They also accept a
custom argument — called a payload — as the second
argument.

For example, let’s make a mutation to change a user’s


name to a specific value.

mutations: {
changeName (state, payload) {
state.user.fullName = payload
}
},

Then, we can call this method from our component


using the store.commit method, with our payload
as the second argument.

this.$store.commit("changeName", "New Name");

More often than not, you are going to want your


payload to be an object. Not only does this mean that
you can pass several arguments to a mutation, but
also, it makes your code more readable because of
the property names in your object.

changeName (state, payload) {


state.user.fullName = payload.newName
}

There are two different ways to call mutations with


a payload.

01 You can have the mutation type as the first


argument and the payload as the second.

02 You can declare pass a single object, with one


property for the type and another for the
payload.

this.$store.commit("changeName", {
newName: "New Name 1",
});

// or

this.$store.commit({
type: "changeName",
newName: "New Name 2"
});

There isn’t a real difference between how the two


work so it’s totally up to personal preference.
Remember that it’s always best to be consistent
throughout your entire project, so whichever one
you choose, stick with it!

4. ACTIONS

In Vuex, actions are fairly similar to mutations


because we use them to change the state. However,
actions don’t change the values themselves. Instead,
actions commit mutations.

Also, while Vuex mutations have to be synchronous,


actions do not. Using actions, we can call a mutation
after an API call, for example.

Whereas most of the Vuex handlers we’ve seen


accept state as their main parameter, actions accept a
context object. This context object allows us to
access the properties in our Vuex store (e.g. state,
commit, getters).

Here’s an example of a Vuex action that waits two


seconds and then commits the changeName
mutation.

actions: {
changeName (context, payload) {
setTimeout(() => {
context.commit("changeName", payload);
}, 2000);
}
}

Inside our components, we use the store.dispatch


method in order to run our function. We pass
arguments just like we did with mutations. We
declare the type and we pass any custom arguments
in the second argument.

this.$store.dispatch("changeName", {
newName: "New Name from Action"
});

Wrapping Up
Now, you should know three different ways to share
data across components in VueJS: props, custom
events, and a Vuex store.

I hope this tutorial helped give you some more


insight into some different Vue methods and best
practices. Let me know how you’ve implemented
them into your projects!

FURTHER READING

If you’re interested in going even deeper into the


technical side/capabilities of each technique, here
are some great places to start.

Vuex
Vuex
Vuex
VuexOfficial
Official
Official
OfficialGuide
Guide
Guide
Guide website
VueJS Docs for Props
Props
Props
Propsand Custom
Custom
Custom
CustomEvents
Events
Events
Events

“WTF
WTF
WTF
WTFIsIs
Is
IsVuex?
Vuex?
Vuex?
Vuex?AAAABeginner’s
Beginner’s
Beginner’s
Beginner’sGuide
Guide
Guide
GuideTo
To
To
ToVue’s
Vue’s
Vue’s
Vue’s
Application
Application
Application
ApplicationData
Data
Data
DataStore
Store
Store,”
Store
Store Anthony Gore, Vue.js
Developers

(dm, yk, il)

Interface Design Click!


Checklists (PDF) A guide to increasing
100 practical cards for common conversion and driving sales.
interface design challenges.

Front-End & UX
Workshops, Online

With practical takeaways,


interactive exercises,
recordings and a friendly Q&A.

— Comments 12

Eric Taylor wrote J ANU AR Y 24, 2020 5:32

Great article! There is another way, though: We


use PostalJS and install it on the Vue instance.
Calling it is a matter of
this.$postal.publish(...) and
this.$postal.subscribe(...) . Postal gives us a
proper client-side event bus with channels and
AMPQ-style, hierarchical topics (although the style
can be customized). I had the pleasure of
contributing to the design specs of the
postal.request-response plugin and the
postal.preserve plugin. Couldn’t live without
Postal!

Reply ↓

Andrejs
Andrejs
Andrejs
Andrejs wrote J ANU AR Y 24, 2020 21:20

There’s an another option of setting up a global


Vue instance which is used as an EventBus
through which events can be emitted and listened
upon. Here’s an article to read more about the
EventBus pattern.
https://medium.com/me/stats/post/cdc11cd59860
https://medium.com/me/stats/post/cdc11cd59860
https://medium.com/me/stats/post/cdc11cd59860
https://medium.com/me/stats/post/cdc11cd59860

Reply ↓

Load all 12 comments ↓

BRO WSE ALL SMASHING MAG AZ INE TO PICS

• Accessibility • Android

• Animation • Apps

• CSS • Design

• Design Patterns • Design Systems

• E-Commerce • Freebies

• Graphics • HTML

• Illustrator • Inspiration

• iOS • JavaScript

• Mobile • Pattern Libraries

• Performance • Photoshop

• Plugins • React

• Responsive Web Design • Service Workers

• Sketch • Typography

• UI • Usability

• User Experience • Wallpapers

• Web Design • WordPress

• Workflow

With a commitment to quality content for the design community.


Founded by Vitaly Friedman and Sven Lennartz. 2006–2021.
Smashing is proudly running on Netlify.
Fonts by Latinotype.

✎ Write for us Contact us About us (Impressum)

Privacy policy Membership login Delivery times Advertise

You might also like