Vue Slot Props Example

Posted on by admin
  1. Vue Slot Examples
  2. Vue Template Slot

# Slots # default. This slot is the element that triggers the dropdown. It can be any HTML element, the components surrounds it with a div which handles the events like hover/click etc. This slot is the content of the dropdown menu. The child component contains a prop called 'signal'. I would like to be able to change data called 'parentVal' in the parent component so that the children's signal prop is updated with the parent's value. This seems like it should be something simple, but I cannot figure out how to do this using slots: Here is a running example below.

Vue introduces Composition API (Function-based API) as an addition to current Options-based API. The API will be released with Vue 3, but now you can try it with Vue 3 Composition API added to your Vue 2 app. In this tutorial, we’re gonna show you:

  • New Vue Composition API overview and comparison with classic Vue Options-based API
  • Examples to implement a Vue Component with new API: props, data, watchers, lifecycle hooks
  • Example to take advantage of new Vue 3 Composition API (function-based API): split Topics into Functions

Related Post: Vue v-slot tutorial with examples


Contents

  • Vue Composition API examples

What’s changed when Vue Composition API is added?

Everything will still work as it works before. Almost things don’t change:

  • CLI
  • Template syntax
  • Object format
  • Reactivity system
  • Concepts of computed properties, watchers & component lifecycle
  • SFC format
  • Progressive nature of Vue framework

Options-based API vs Composition API

The difference of current Options-based API concept vs new Composition API (Function-based API) concept is the way we think of what a component contains:

Slot
  • Options-based API: A component contains types of properties/methods/options.
  • Composition API: A component encapsulates logical topics into functions.

Component options could become complicated to be organized and hard to maintain (monster component). A logical topic could involve properties in props and data(), some methods, a certain hook (beforeMount/ mounted), and a watcher in watch. Hence one single topic will be fragmented across multiple options.

With Composition API, every function, which is a part of the big component, encapsulates all the code related to the logical topic (properties, methods, hooks, watchers). Now that smaller code (function) can be reused, and well-organized.

Use Vue 3 Composition API in current Vue 2 project

We can use new Vue 3 Composition API in our current Vue 2.x project by installing @vue/composition-api module.

It is so easy, just run the command:

Or

Then import it in main.js.

Vue setup() function

setup() is the new component option that we will use new Vue Composition API to setup the logic (logical topics) of the component. If setup() function becomes complex, we can easily split it into multiple functions with corresponding to logical topics.

When setup() is called?
It is called after props resolution, when an instance of the component is created.

Now look at the Vue component with setup() function:

The function has 2 arguments:
props
context

context has properties (attrs, slots, emit, parent, root) that are corresponding to this.$attrs, this.$slots, this.$emit, this.$parent, this.$root.

We can also destructure them with the latest values even after updates:

*Note:this keyword is not available inside setup() function.

So this.$emit cannot be used like this:

this.$refs with new Composition API

To get a reference to an element or component instance in the template, we use ref API so that setup() can return reactive and mutable object for render context.

ref automatically unwraps to the inner value, so we don’t need to append .value in the template: {{ name }} is enough, not {{ name.value }}.

Vue Composition API examples

In this section, we’re gonna show you examples that use new API along with old Vue2 options-based API syntax.

Vue Composition API Computed Values

Vue2 options-based API syntax:

Vue 3 Composition API syntax:

With new computed API, we can create a writable ref object with get and set functions.

Vue Composition API Watchers

This is how we use Vue2 options-based API syntax:

Like watch option, we can use new Vue watch API to perform side effect everytime a state is changed.

The syntax is: watch(source, callback, options)

  • source: could be a getter function, a value wrapper, or an array containing the two above types (in case of watching multiple sources)
  • callback: is the function like Vue2 watcher handler function, with 2 arguments: newVal, oldVal. Each argument could be an array (for watching multiple sources): [newVal1, newVal2, ... newValN], [oldVal1, oldVal2, ... oldValN]
  • options (optional): is used for configuring watcher type containing: lazy, deep, flush.

For more details about WatchOption, please visit: api#watch.

In case we want to watch multiple sources:

We can also split the multiple sources watcher into smaller watchers. This helps us organize our code and create watchers with distinct options:

Vue Composition API Lifecycle Hooks

With Vue2, we implement Lifecycle Hooks functions by this way:

New Vue 3 Composition API has equivalent functions, we can use those with on prefix inside setup() function:

You can see the mapping between Lifecycle Vue2 Options and Composition API in the following table:

Vue2 Options-based APIVue Composition API
beforeCreatesetup()
createdsetup()
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
errorCapturedonErrorCaptured

Encapsulate logical Topics into Functions

Now we combine all code above into one Vue Component, you can see a complex component with multiple topics. We need to implement logic for title, for todo, for items:

It comes time to take advantage of Vue Composition API: split complex component into multiple functions with corresponding to logical topics:

The results:

It works like a charm.
We can easily view each topic by its own function. Each topic has its own props, data, watchers, methods. Our component now only need to inject these functions and return them inside its setup() function.

Fantastic!

Conclusion

Maybe you feel comfortable when using the old Vue options-based API, or maybe you don’t like to think of everything as functions but properties/methods with OOP mindset. The creators are developing Vue, make it better year after year and give us more options. Just try it and feel the good.

Happy learning! See you again!

Source Code

You can find the complete source code for this ‘Vue Composition Api example’ on Github.

Further Reading

You keep reading about 'props'.

Props

You've probably been using them too (even if you didn't realize it).

But maybe you aren't completely sure about what they are.

Or how to use them properly and get the most out of them.

I was once in your position, not entirely sure of what I was doing and feeling like I was drowning. But I've learned a lot over the years, and now I want to pass that on to you.

By the time you're finished reading this guide, you'll know everything you need to know about props in order to be a super productive Vue developer.

And when your co-workers ask you how you know so much, just smile and tell them you're awesome 😉

In this guide we'll cover the most important things about props:

  • What are props?
  • Two main characteristics of props
  • How to pass props to other components
  • Adding prop types
  • Making props required
  • Setting default values

Plus many more things throughout!

So, let's get started, shall we?

What are props?

Vue Slot Examples

Props are how we pass variables and other information around between different components. This is similar to how in Javascript we can pass variables into functions as arguments:

Here we pass the variable myMessage into the function as the argument message. Inside the function we can access that value as message.

Props work in a very similar way to this. We pass props to another component, and that component can then use that value.

But there are a couple rules you need to know about first.

Two main characteristics of Vue props

There are two specific things to keep in mind when dealing with props:

  1. Props are passed down the component tree to descendents (not up)
  2. Props are read-only and cannot be modified (as you may have discovered)

Vue uses one way data flow, meaning that data can only flow from a parent into a child component. You cannot pass data from a child to a parent.

And because that parent component 'owns' that value it passed down, the child can't modify it. If only one component is allowed to change it, then it's easier to track down bugs since we know exactly where to look.

If the reasoning here isn't super clear that's okay. You'll understand how this works as you use Vue more and more.

Just make sure you don't violate those two rules and you'll be golden.

Let's take a look at how we can pass props from one component to another.

Passing props to other components

If you want to pass a value from your component into a child component, it's exactly like adding an HTML attribute:

Looks like regular HTML, right? Not too scary.

The Camera component will then use the name and img props to render itself to the page. It might render something like this:

Here we render the name prop into the h2 tag, and use the img prop to set the src attribute on the img tag.

But what if we have this information stored in a variable somewhere?

To do that we need to use a slightly different syntax, since instead of passing a string we want to use a Javascript expression:

The line v-bind:name='cameraName' tells Vue to bind the Javascript expression cameraName to the prop name. A Javascript expression is any snippet of Javascript. It could be a variable name like we have here, or something more complicated.

For example, we could use a logical OR to use a default if we don't have an image for the camera:

More commonly, we use the shorthand for v-bind which is just : and reduces clutter in the code:

Because you can put in any arbitrary piece of Javascript, you can do a lot of nifty little things, such as dynamically adding a class name, or implementing a hover.

Adding in our Props

We're not quite there yet though.

Before this code will actually work, we need to get the Camera component to actually listen to the props. By default it will just ignore them.

To do this we have to add a props section to our component definition:

This is the bare minimum to get things working, but it's not recommended you do this. Instead, you should specify the type of the prop as well, using an object:

By switching from an array to an object, we can specify more details of our props, like the type. We can specify other things too, but we'll get to that in a bit.

Why do we want to add types to our props?

In Vue, props can be many different things. They can be:

  • Strings
  • Numbers
  • Boolean (true or false)
  • Arrays
  • Objects

By adding in prop types like this we can set expectations for what we'll receive. If we set our camera's name prop to true it won't work properly, so Vue will warn us that we're using it wrong.

We'll add a rating to our Camera component so we can see what using a number looks like. First we add it to the prop types:

Then we'll also update our template so we display the rating on the page:

All we need to do is specify the prop name, no this is required. In a Vue template everything that can be accessed off of this is automatically included.

Now we can pass in a number as a prop:

Notice how we used the v-bind shorthand for this one. If we didn't do this it would get passed in as a String, which is the incorrect type.

Passing in an array or object or any other type works in the same way, using v-bind or it's shorthand.

Required props

Not all props are created equal.

Some of them are necessary for the component to work correctly.

Others are just extras, giving additional functionality if you need it.

For our Camera component, we definitely need a name, otherwise it doesn't make any sense. But we don't need an image, and we don't really need a rating either.

Vue slot class

We can specify which props are required and which ones aren't in our prop definition:

Here we set our name prop to be required by adding required: true to its prop definition.

By default props are not required, so we don't need to touch the other ones. We could add required: false if we wanted to.

Default Values

Many times we'll want to set a default value on our optional props, since they may not be provided each time.

Earlier we saw how to add a default image if we didn't have one for our camera, but this is a better way:

Perfect!

Instead of cluttering up our template, we put the default value right alongside all of the other information about the img prop.

While we're at it, we should specify a default for our rating prop as well. Right now if it isn't set we'll just get undefined, which could cause some issues for us:

Vue Slot Props Example

Vue Template Slot

Now if the camera hasn't been rated, we'll get a 0 displayed instead of undefined.

Specifying types, adding defaults, and marking props as required are only a couple of the things you can do with prop types. I wrote an article with some killer tips on getting the most out of them.

Using props outside of the template

While being able to use props inside of your template is great, the real power comes from using them in your methods, computed props, and other Javascript used in your component.

In our templates we saw that we just needed the prop name, like this: {{ rating }}. However, everywhere else in our Vue component we'll need to access our props using this.rating.

Let's refactor the app so that we use a standard URL structure for our images. This way we don't have to pass it to the Camera component each time, and we can just figure it out from the name.

We'll use this structure: ./images/cameras/${cameraName}.jpg

Vue

So if the camera is the Sony A6400, the URL will become ./images/cameras/Sony%20A6400.jpg. The %20 is from encoding the space character so we can use it in a URL.

First we'll remove the img prop that we no longer need:

Then we'll add a computed property that will generate the image URL for us:

Not all characters can be used in URLs, so encodeURIComponent will convert those for us.

Because we can access this computed prop in the same way as regular props, we don't need to change our template at all, and it can stay as we had it before:

In this way you can use the component's props in:

  • Watchers
  • Lifecycle hooks
  • Methods
  • Computed props

And anywhere else in the component definition!

Conclusion

By now you should know everything you need to know about props in order to be a highly productive Vue developer.

However, there are always more things to learn. Vue (and software development in general) is a never ending learning process.

In order to keep learning more about Vue, and to learn things as I figure them out myself, join my email list below for weekly updates!