Posted  by  admin

Nested Slots Vue Js

In the previous article Getting-Started-With-Vue it was discussed how to install the vue-cli. So in this article let’s start by creating an app with the vue-cli. vue create my-portfolio. This above command will direct the vue-cli to create an app template by the name my-portfolio. Once the app is created to run the second command: vue. I’m going to start with the basic setup that Vue.js gives us when using the command line, but I’ll delete some things we don’t really need in the templates.

  1. Nested Slots Vue Js 2.2
  2. Nested Slots Vue Js Tool
  3. Nested Slots Vue Js Tutorial
  4. Nested Slots Vue Js Login

This page assumes you’ve already read the Components Basics. Read that first if you are new to components.

Slot Content

Vue implements a content distribution API that’s modeled after the current Web Components spec draft, using the <slot> element to serve as distribution outlets for content.

This allows you to compose components like this:

Then in the template for <navigation-link>, you might have:

When the component renders, the <slot> element will be replaced by “Your Profile”. Slots can contain any template code, including HTML:

Or even other components:

If <navigation-link> did not contain a <slot> element, any content passed to it would simply be discarded.

Named Slots

There are times when it’s useful to have multiple slots. For example, in a hypothetical base-layout component with the following template:

For these cases, the <slot> element has a special attribute, name, which can be used to define additional slots:

To provide content to named slots, we can use the slot attribute on a <template> element in the parent:

Or, the slot attribute can also be used directly on a normal element:

There can still be one unnamed slot, which is the default slot that serves as a catch-all outlet for any unmatched content. In both examples above, the rendered HTML would be:

Default Slot Content

There are cases when it’s useful to provide a slot with default content. For example, a <submit-button> component might want the content of the button to be “Submit” by default, but also allow users to override with “Save”, “Upload”, or anything else.

To achieve this, specify the default content in between the <slot> tags.

If the slot is provided content by the parent, it will replace the default content.

Compilation Scope

When you want to use data inside a slot, such as in:

That slot has access to the same instance properties (i.e. the same “scope”) as the rest of the template. The slot does not have access to <navigation-link>‘s scope. For example, trying to access url would not work. As a rule, remember that:

Everything in the parent template is compiled in parent scope; everything in the child template is compiled in the child scope.

Scoped Slots

New in 2.1.0+

Sometimes you’ll want to provide a component with a reusable slot that can access data from the child component. For example, a simple <todo-list> component may contain the following in its template:

But in some parts of our app, we want the individual todo items to render something different than just the todo.text. This is where scoped slots come in.

To make the feature possible, all we have to do is wrap the todo item content in a <slot> element, then pass the slot any data relevant to its context: in this case, the todo object:

Now when we use the <todo-list> component, we can optionally define an alternative <template> for todo items, but with access to data from the child via the slot-scope attribute:

Nested Slots Vue Js 2.2

In 2.5.0+, slot-scope is no longer limited to the <template> element, but can instead be used on any element or component in the slot.

Destructuring slot-scope

The value of slot-scope can actually accept any valid JavaScript expression that can appear in the argument position of a function definition. This means in supported environments (single-file components or modern browsers) you can also use ES2015 destructuring in the expression, like so:

This is a great way to make scoped slots a little cleaner.

← Custom EventsDynamic & Async Components →
Phát hiện lỗi hoặc muốn đóng góp vào nội dung? Chỉnh sửa trang này trên GitHub!

You have an array or an object as a prop, and you want your app to do something whenever that data changes.

So you create a watcher for that property, but Vue doesn't seem to fire the watcher when the nested data changes.

Here's how you solve this.

You need to set deep to true when watching an array or object so that Vue knows that it should watch the nested data for changes.

I'll go into more detail on what this looks like in this article, plus some other useful things to know when using watch in Vue.

You can also check out the Vue docs on using watchers.

What we'll cover in this article

First we'll do a quick refresher on what a watcher actually is.

Second, we have to take a slight detour and clarify the distinction between computed props and watchers.

Thirdly, we'll dive into how you can watch nested data in arrays and objects. Feel free to skip straight here if you need — you can always come back to the first sections later on.

We'll also go through what you can do with immediate and handler fields on your watchers. This will take your watcher skills to the next level!

What is a watch method?

In Vue we can watch for when a property changes, and then do something in response to that change.

For example, if the prop colour changes, we can decide to log something to the console:

These watchers let us do all sorts of useful things.

But many times we use a watcher when all we needed was a computed prop.

Should you use watch or computed?

Watched props can often be confused with computed properties, because they operate in a similar way. It's even trickier to know when to use which one.

But I've come up with a good rule of thumb.

Watch is for side effects. If you need to change state you want to use a computed prop instead.

A side effect is anything that happens outside of your component, or anything asynchronous.

Common examples are:

  • Fetching data
  • Manipulating the DOM
  • Using a browser API, such as local storage or audio playback

None of these things affect your component directly, so they are considered to be side effects.

If you aren't doing something like this, you'll probably want to use a computed prop. Computed props are really good for when you need to update a calculation in response to something else changing.

However, there are cases where you might want to use a watcher to update something in your data.

Sometimes it just doesn't make sense to make something a computed prop. If you have to update it from your <template> or from a method, it needs to go inside of your data. But then if you need to update it in response to a property changing, you need to use the watcher.

NOTE: Be careful with using a watch to update state. This means that both your component and the parent component are updating — directly or indirectly — the same state. This can get very ugly very fast.

Watching nested data — Arrays and Objects

So you've decided that you actually need a watcher.

But you're watching an array or an object, and it isn't working as you had expected.

What's going on here?

Nested Slots Vue Js Tool

Let's say you set up an array with some values in it:

Now you update the array by pushing some more values into it:

Nested slots vue js login

Here's the question: has array changed?

Well, it's not that simple.

The contents of array have changed, but the variable array still points to the same Array object. The array container hasn't changed, but what is inside of the array has changed.

So when you watch an array or an object, Vue has no idea that you've changed what's inside that prop. You have to tell Vue that you want it to inspect inside of the prop when watching for changes.

You can do this by setting deep to true on your watcher and rearranging the handler function:

Now Vue knows that it should also keep track of what's inside the prop when it's trying to detect changes.

What's up with the handler function though?

Just you wait, we'll get to that in a bit. But first let's cover something else that's important to know about Vue's watchers.

Immediate

A watcher will only fire when the prop's value changes, but we often need it to fire once on startup as well.

Nested slots vue js 2.2

Let's say we have a MovieData component, and it fetches data from the server based on what the movie prop is set to:

Now, this component will work wonderfully. Whenever we change the movie prop, our watcher will fire, and it will fetch the new data.

Except we have one small problem.

Nested Slots Vue Js Tutorial

Our problem here is that when the page loads, movie will be set to some default value. But since the prop hasn't changed yet, the watcher isn't fired. This means that the data isn't loaded until we select a different movie.

So how do we get our watcher to fire immediately upon page load?

We set immediate to true, and move our handler function:

Okay, so now you've seen this handler function twice now. I think it's time to cover what that is.

Handler

Nested Slots Vue Js Login

Watchers in Vue let you specify three different properties:

  • immediate
  • deep
  • handler

We just looked at the first two, and the third isn't too difficult either. You've probably already been using it without realizing it.

The property handler specifies the function that will be called when the watched prop changes.

What you've probably seen before is the shorthand that Vue lets us use if we don't need to specify immediate or deep. Instead of writing:

We can use the shorthand and just specify the function directly:

What's cool is that Vue also let's us use a String to name the method that handles the function. This is useful if we want to do something when two or more props change.

Using our movie component example, let's say we fetch data based on the movie prop as well as the actor, then this is what our methods and watchers would look like:

This makes things a little cleaner if we are watching multiple props to do the same side-effect.

If you enjoyed this article or have any comments, let me know by replying to this tweet!