Vue Slots Jsx
2021年4月11日Register here: http://gg.gg/p038a
*Vue Jsx Slot Name
*Jsx Vue Slots
*Vue Jsx Slot Props
*Vue Scoped Slots Jsx
*Vue V-slot Jsx
*Vue Slot Jsx
If you use Vue version above 2.6.0, Vue introduces new unified slot api, which is v-slot. It replaces the slot and slot-scope attributes, which are deprecated, but have not been removed and are still documented here. You can refer to deprecated API here. # Slots (Default). Render props is a design pattern from React that allows a closer-to-the-compiler alternative to templates with fine-grain control over rendering. In this article, Darren Jennings shows you how to implement render props with Vue.js. Vue中使用 render写一些展示组件 通过实现一个简单的单元 cell 组件, 来了解render jsx 在vue的使用 将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的。. Vue.js - The Progressive JavaScript Framework. Each Vue instance goes through a series of initialization steps when it’s created - for example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes.Basics
Vue recommends using templates to build your HTML in the vast majority of cases. There are situations however, where you really need the full programmatic power of JavaScript. That’s where you can use the render function, a closer-to-the-compiler alternative to templates.
Let’s dive into a simple example where a render function would be practical. Say you want to generate anchored headings:
For the HTML above, you decide you want this component interface:
When you get started with a component that only generates a heading based on the level prop, you quickly arrive at this:
That template doesn’t feel great. It’s not only verbose, but we’re duplicating <slot></slot> for every heading level and will have to do the same when we add the anchor element.
While templates work great for most components, it’s clear that this isn’t one of them. So let’s try rewriting it with a render function:
Much simpler! Sort of. The code is shorter, but also requires greater familiarity with Vue instance properties. In this case, you have to know that when you pass children without a slot attribute into a component, like the Hello world! inside of anchored-heading, those children are stored on the component instance at $slots.default. If you haven’t already, it’s recommended to read through the instance properties API before diving into render functions.Nodes, Trees, and the Virtual DOM
Before we dive into render functions, it’s important to know a little about how browsers work. Take this HTML for example:
When a browser reads this code, it builds a tree of “DOM nodes” to help it keep track of everything, just as you might build a family tree to keep track of your extended family.
The tree of DOM nodes for the HTML above looks like this:
Every element is a node. Every piece of text is a node. Even comments are nodes! A node is just a piece of the page. And as in a family tree, each node can have children (i.e. each piece can contain other pieces).
Updating all these nodes efficiently can be difficult, but thankfully, you never have to do it manually. Instead, you tell Vue what HTML you want on the page, in a template:
Or a render function:
And in both cases, Vue automatically keeps the page updated, even when blogTitle changes.The Virtual DOM
Vue accomplishes this by building a virtual DOM to keep track of the changes it needs to make to the real DOM. Taking a closer look at this line:
What is createElement actually returning? It’s not exactly a real DOM element. It could perhaps more accurately be named createNodeDescription, as it contains information describing to Vue what kind of node it should render on the page, including descriptions of any child nodes. We call this node description a “virtual node”, usually abbreviated to VNode. “Virtual DOM” is what we call the entire tree of VNodes, built by a tree of Vue components.createElement Arguments
The next thing you’ll have to become familiar with is how to use template features in the createElement function. Here are the arguments that createElement accepts:The Data Object In-DepthVue Jsx Slot Name
One thing to note: similar to how v-bind:class and v-bind:style have special treatment in templates, they have their own top-level fields in VNode data objects. This object also allows you to bind normal HTML attributes as well as DOM properties such as innerHTML (this would replace the v-html directive):Complete Example
With this knowledge, we can now finish the component we started:ConstraintsVNodes Must Be Unique
All VNodes in the component tree must be unique. That means the following render function is invalid:
If you really want to duplicate the same element/component many times, you can do so with a factory function. For example, the following render function is a perfectly valid way of rendering 20 identical paragraphs:Replacing Template Features with Plain JavaScriptv-if and v-for
Wherever something can be easily accomplished in plain JavaScript, Vue render functions do not provide a proprietary alternative. For example, in a template using v-if and v-for:
This could be rewritten with JavaScript’s if/else and map in a render function:v-model
There is no direct v-model counterpart in render functions - you will have to implement the logic yourself:
This is the cost of going lower-level, but it also gives you much more control over the interaction details compared to v-model.Event & Key Modifiers
For the .passive, .capture and .once event modifiers, Vue offers prefixes that can be used with on:Modifier(s)Prefix.passive&.capture!.once~.capture.once or.once.capture~!
For example:
For all other event and key modifiers, no proprietary prefix is necessary, because you can use event methods in the handler:Modifier(s)Equivalent in Handler.stopevent.stopPropagation().preventevent.preventDefault().selfif (event.target ! event.currentTarget) returnKeys:.enter, .13if (event.keyCode ! 13) return (change 13 to another key code for other key modifiers)Modifiers Keys:.ctrl, .alt, .shift, .metaif (!event.ctrlKey) return (change ctrlKey to altKey, shiftKey, or metaKey, respectively)
Here’s an example with all of these modifiers used together:Slots
You can access static slot contents as Arrays of VNodes from this.$slots:
And access scoped slots as functions that return VNodes from this.$scopedSlots:
To pass scoped slots to a child component using render functions, use the scopedSlots field in VNode data:JSX
If you’re writing a lot of render functions, it might feel painful to write something like this:
Especially when the template version is so simple in comparison:
That’s why there’s a Babel plugin to use JSX with Vue, getting us back to a syntax that’s closer to templates:
Aliasing createElement to h is a common convention you’ll see in the Vue ecosystem and is actually required for JSX. If h is not available in the scope, your app will throw an error.
For more on how JSX maps to JavaScript, see the usage docs.Functional Components
The anchored heading component we created earlier is relatively simple. It doesn’t manage any state, watch any state passed to it, and it has no lifecycle methods. Really, it’s only a function with some props.
In cases like this, we can mark components as functional, which means that they’re stateless (no data) and instanceless (no this context). A functional component looks like this:
Note: in versions before 2.3.0, the props option is required if you wish to accept props in a functional component. In 2.3.0+ you can omit the props option and all attributes found on the component node will be implicitly extracted as props.
In 2.5.0+, if you are using single-file components, template-based functional components can be declared with:
Everything the component needs is passed through context, which is an object containing:
*props: An object of the provided props
*children: An array of the VNode children
*slots: A function returning a slots object
*data: The entire data object passed to the component
*parent: A reference to the parent component
*listeners: (2.3.0+) An object containing parent-registered event listeners. This is an alias to data.on
*injections: (2.3.0+) if using the inject option, this will contain resolved injections.
After adding functional: true, updating the render function of our anchored heading component would require adding the context argument, updating this.$slots.default to context.children, then updating this.level to context.props.level.
Since functional components are just functions, they’re much cheaper to render. However, the lack of a persistent instance means they won’t show up in the Vue devtools component tree.
They’re also very useful as wrapper components. For example, when you need to:
*Programmatically choose one of several other components to delegate to
*Manipulate children, props, or data before passing them on to a child component
Here’s an example of a smart-list component that delegates to more specific components, depending on the props passed to it:slots() vs children
You may wonder why we need both slots() and children. Wouldn’t slots().default be the same as children? In some cases, yes - but what if you have a functional component with the following children?
For this component, children will give you both paragraphs, slots().default will give you only the second, and slots().foo will give you only the first. Having both children and slots() therefore allows you to choose whether this component knows about a slot system or perhaps delegates that responsibility to another component by passing along children.Template Compilation
You may be interested to know that Vue’s templates actually compile to render functions. This is an implementation detail you usually don’t need to know about, but if you’d like to see how specific template features are compiled, you may find it interesting. Below is a little demo using Vue.compile to live-compile a template string:Compilation Error: Hai visto degli errori o vorresti contriuire alla repository? Modifica questa pagina in Github!
You’re browsing the documentation for v2.x and earlier. For v3.x, click here.
This page assumes you’ve already read the Components Basics. Read that first if you are new to components.
In 2.6.0, we introduced a new unified syntax (the v-slot directive) for named and scoped slots. It replaces the slot and slot-scope attributes, which are now deprecated, but have not been removed and are still documented here. The rationale for introducing the new syntax is described in this RFC.Slot Content
Vue implements a content distribution API inspired by the 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, <slot></slot> will be replaced by “Your Profile”. Slots can contain any template code, including HTML:
Or even other components:
If <navigation-link>‘s template did not contain a <slot> element, any content provided between its opening and closing tag would be discarded.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.Fallback Content
There are cases when it’s useful to specify fallback (i.e. default) content for a slot, to be rendered only when no content is provided. For example, in a <submit-button> component:
We might want the text “Submit” to be rendered inside the <button> most of the time. To make “Submit” the fallback content, we can place it in between the <slot> tags:
Now when we use <submit-button> in a parent component, providing no content for the slot:
will render the fallback content, “Submit”:
But if we provide content:
Then the provided content will be rendered instead:Named Slots
Updated in 2.6.0+. See here for the deprecated syntax using the slot attribute.
There are times when it’s useful to have multiple slots. For example, in a <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:
A <slot> outlet without name implicitly has the name “default”.
To provide content to named slots, we can use the v-slot directive on a <template>, providing the name of the slot as v-slot‘s argument:
Now everything inside the <template> elements will be passed to the corresponding slots. Any content not wrapped in a <template> using v-slot is assumed to be for the default slot.
However, you can still wrap default slot content in a <template> if you wish to be explicit:
Either way, the rendered HTML will be:
Note that v-slot can only be added to a <template> (with one exception), unlike the deprecated slot attribute.Scoped Slots
Updated in 2.6.0+. See here for the deprecated syntax using the slot-scope attribute.
Sometimes, it’s useful for slot content to have access to data only available in the child component. For example, imagine a <current-user> component with the following template:
We might want to replace this fallback content to display the user’s first name, instead of last, like this:
That won’t work, however, because only the <current-user> component has access to the user and the content we’re providing is rendered in the parent.
To make user available to the slot content in the parent, we can bind user as an attribute to the <slot> element:
Attributes bound to a <slot> element are called slot props. Now, in the parent scope, we can use v-slot with a value to define a name for the slot props we’ve been provided:
In this example, we’ve chosen to name the object containing all our slot props slotProps, but you can use any name you like.Abbreviated Syntax for Lone Default Slots
In cases like above, when only the default slot is provided content, the component’s tags can be used as the slot’s template. This allows us to use v-slot directly on the component:
This can be shortened even further. Just as non-specified content is assumed to be for the default slot, v-slot without an argument is assumed to refer to the default slot:
Note that the abbreviated syntax for default slot cannot be mixed with named slots, as it would lead to scope ambiguity:
Whenever there are multiple slots, use the full <template> based syntax for all slots:Destructuring Slot Props
Internally, scoped slots work by wrapping your slot content in a function passed a single argument:
That means the value of v-slot can actually accept any valid JavaScript expression that can appear in the argument position of a function definition. So in supported environments (single-file components or modern browsers), you can also use ES2015 destructuring to pull out specific slot props, like so:
This can make the template much cleaner, especially when the slot provides many props. It also opens other possibilities, such as renaming props, e.g. user to person:
You can even define fallbacks, to be used in case a slot prop is undefined:Dynamic Slot Names
New in 2.6.0+
Dynamic directive arguments also work on v-slot, allowing the definition of dynamic slot names:Named Slots Shorthand
New in 2.6.0+
Similar to v-on and v-bind, v-slot also has a shorthand, replacing everything before the argument (v-slot:) with the special symbol #. For example, v-slot:header can be rewritten as #header:
However, just as with other directives, the shorthand is only available when an argument is provided. That means the following syntax is invalid:
Instead, you must always specify the name of the slot if you wish to use the shorthand:Other Examples
Slot props allow us to turn slots into reusable templates that can render different content based on input props. This is most useful when you are designing a reusable component that encapsulates data logic while allowing the consuming parent component to customize part of its layout.
For example, we are implementing a <todo-list> component that contains the layout and filtering logic for a list:
Instead of hard-coding the content for each todo, we can let the parent component take control by making every todo a slot, then binding todo as a slot prop:
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:
However, even this barely scratches the surface of what scoped slots are capable of. For real-life, powerful examples of scoped slot usage, we recommend browsing libraries such as Vue Virtual Scroller, Vue Promised, and Portal Vue.Deprecated SyntaxJsx Vue Slots
The v-slot directive was introduced in Vue 2.6.0, offering an improved, alternative API to the still-supported slot and slot-scope attributes. The full rationale for introducing v-slot is described in this RFC. The slot and slot-scope attributes will continue to be supported in all future 2.x releases, but are officially deprecated and will eventually be removed in Vue 3.Named Slots with the slot Attribute
Deprecated in 2.6.0+. See here for the new, recommended syntax.
To pass content to named slots from the parent, use the special slot attribute on <template> (using the <base-layout> component described here as example):
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 for any unmatched content. In both examples above, the rendered HTML would be:Scoped Slots with the slot-scope Attribute
Deprecated in 2.6.0+. See here for the new, recommended syntax.Vue Jsx Slot Props
To receive props passed to a slot, the parent component can use <template> with the slot-scope attribute (using the <slot-example> described here as example):
Here, slot-scope declares the received props object as the slotProps variable, and makes it available inside the <template> scope. You can name slotProps anything you like similar to naming function arguments in JavaScript.Vue Scoped Slots Jsx
Here slot=’default’ can be omitted as it is implied:
The slot-scope attribute can also be used directly on a non-<template> element (including components):
The value of slot-scope can 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:
Using t
https://diarynote-jp.indered.space
*Vue Jsx Slot Name
*Jsx Vue Slots
*Vue Jsx Slot Props
*Vue Scoped Slots Jsx
*Vue V-slot Jsx
*Vue Slot Jsx
If you use Vue version above 2.6.0, Vue introduces new unified slot api, which is v-slot. It replaces the slot and slot-scope attributes, which are deprecated, but have not been removed and are still documented here. You can refer to deprecated API here. # Slots (Default). Render props is a design pattern from React that allows a closer-to-the-compiler alternative to templates with fine-grain control over rendering. In this article, Darren Jennings shows you how to implement render props with Vue.js. Vue中使用 render写一些展示组件 通过实现一个简单的单元 cell 组件, 来了解render jsx 在vue的使用 将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的。. Vue.js - The Progressive JavaScript Framework. Each Vue instance goes through a series of initialization steps when it’s created - for example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes.Basics
Vue recommends using templates to build your HTML in the vast majority of cases. There are situations however, where you really need the full programmatic power of JavaScript. That’s where you can use the render function, a closer-to-the-compiler alternative to templates.
Let’s dive into a simple example where a render function would be practical. Say you want to generate anchored headings:
For the HTML above, you decide you want this component interface:
When you get started with a component that only generates a heading based on the level prop, you quickly arrive at this:
That template doesn’t feel great. It’s not only verbose, but we’re duplicating <slot></slot> for every heading level and will have to do the same when we add the anchor element.
While templates work great for most components, it’s clear that this isn’t one of them. So let’s try rewriting it with a render function:
Much simpler! Sort of. The code is shorter, but also requires greater familiarity with Vue instance properties. In this case, you have to know that when you pass children without a slot attribute into a component, like the Hello world! inside of anchored-heading, those children are stored on the component instance at $slots.default. If you haven’t already, it’s recommended to read through the instance properties API before diving into render functions.Nodes, Trees, and the Virtual DOM
Before we dive into render functions, it’s important to know a little about how browsers work. Take this HTML for example:
When a browser reads this code, it builds a tree of “DOM nodes” to help it keep track of everything, just as you might build a family tree to keep track of your extended family.
The tree of DOM nodes for the HTML above looks like this:
Every element is a node. Every piece of text is a node. Even comments are nodes! A node is just a piece of the page. And as in a family tree, each node can have children (i.e. each piece can contain other pieces).
Updating all these nodes efficiently can be difficult, but thankfully, you never have to do it manually. Instead, you tell Vue what HTML you want on the page, in a template:
Or a render function:
And in both cases, Vue automatically keeps the page updated, even when blogTitle changes.The Virtual DOM
Vue accomplishes this by building a virtual DOM to keep track of the changes it needs to make to the real DOM. Taking a closer look at this line:
What is createElement actually returning? It’s not exactly a real DOM element. It could perhaps more accurately be named createNodeDescription, as it contains information describing to Vue what kind of node it should render on the page, including descriptions of any child nodes. We call this node description a “virtual node”, usually abbreviated to VNode. “Virtual DOM” is what we call the entire tree of VNodes, built by a tree of Vue components.createElement Arguments
The next thing you’ll have to become familiar with is how to use template features in the createElement function. Here are the arguments that createElement accepts:The Data Object In-DepthVue Jsx Slot Name
One thing to note: similar to how v-bind:class and v-bind:style have special treatment in templates, they have their own top-level fields in VNode data objects. This object also allows you to bind normal HTML attributes as well as DOM properties such as innerHTML (this would replace the v-html directive):Complete Example
With this knowledge, we can now finish the component we started:ConstraintsVNodes Must Be Unique
All VNodes in the component tree must be unique. That means the following render function is invalid:
If you really want to duplicate the same element/component many times, you can do so with a factory function. For example, the following render function is a perfectly valid way of rendering 20 identical paragraphs:Replacing Template Features with Plain JavaScriptv-if and v-for
Wherever something can be easily accomplished in plain JavaScript, Vue render functions do not provide a proprietary alternative. For example, in a template using v-if and v-for:
This could be rewritten with JavaScript’s if/else and map in a render function:v-model
There is no direct v-model counterpart in render functions - you will have to implement the logic yourself:
This is the cost of going lower-level, but it also gives you much more control over the interaction details compared to v-model.Event & Key Modifiers
For the .passive, .capture and .once event modifiers, Vue offers prefixes that can be used with on:Modifier(s)Prefix.passive&.capture!.once~.capture.once or.once.capture~!
For example:
For all other event and key modifiers, no proprietary prefix is necessary, because you can use event methods in the handler:Modifier(s)Equivalent in Handler.stopevent.stopPropagation().preventevent.preventDefault().selfif (event.target ! event.currentTarget) returnKeys:.enter, .13if (event.keyCode ! 13) return (change 13 to another key code for other key modifiers)Modifiers Keys:.ctrl, .alt, .shift, .metaif (!event.ctrlKey) return (change ctrlKey to altKey, shiftKey, or metaKey, respectively)
Here’s an example with all of these modifiers used together:Slots
You can access static slot contents as Arrays of VNodes from this.$slots:
And access scoped slots as functions that return VNodes from this.$scopedSlots:
To pass scoped slots to a child component using render functions, use the scopedSlots field in VNode data:JSX
If you’re writing a lot of render functions, it might feel painful to write something like this:
Especially when the template version is so simple in comparison:
That’s why there’s a Babel plugin to use JSX with Vue, getting us back to a syntax that’s closer to templates:
Aliasing createElement to h is a common convention you’ll see in the Vue ecosystem and is actually required for JSX. If h is not available in the scope, your app will throw an error.
For more on how JSX maps to JavaScript, see the usage docs.Functional Components
The anchored heading component we created earlier is relatively simple. It doesn’t manage any state, watch any state passed to it, and it has no lifecycle methods. Really, it’s only a function with some props.
In cases like this, we can mark components as functional, which means that they’re stateless (no data) and instanceless (no this context). A functional component looks like this:
Note: in versions before 2.3.0, the props option is required if you wish to accept props in a functional component. In 2.3.0+ you can omit the props option and all attributes found on the component node will be implicitly extracted as props.
In 2.5.0+, if you are using single-file components, template-based functional components can be declared with:
Everything the component needs is passed through context, which is an object containing:
*props: An object of the provided props
*children: An array of the VNode children
*slots: A function returning a slots object
*data: The entire data object passed to the component
*parent: A reference to the parent component
*listeners: (2.3.0+) An object containing parent-registered event listeners. This is an alias to data.on
*injections: (2.3.0+) if using the inject option, this will contain resolved injections.
After adding functional: true, updating the render function of our anchored heading component would require adding the context argument, updating this.$slots.default to context.children, then updating this.level to context.props.level.
Since functional components are just functions, they’re much cheaper to render. However, the lack of a persistent instance means they won’t show up in the Vue devtools component tree.
They’re also very useful as wrapper components. For example, when you need to:
*Programmatically choose one of several other components to delegate to
*Manipulate children, props, or data before passing them on to a child component
Here’s an example of a smart-list component that delegates to more specific components, depending on the props passed to it:slots() vs children
You may wonder why we need both slots() and children. Wouldn’t slots().default be the same as children? In some cases, yes - but what if you have a functional component with the following children?
For this component, children will give you both paragraphs, slots().default will give you only the second, and slots().foo will give you only the first. Having both children and slots() therefore allows you to choose whether this component knows about a slot system or perhaps delegates that responsibility to another component by passing along children.Template Compilation
You may be interested to know that Vue’s templates actually compile to render functions. This is an implementation detail you usually don’t need to know about, but if you’d like to see how specific template features are compiled, you may find it interesting. Below is a little demo using Vue.compile to live-compile a template string:Compilation Error: Hai visto degli errori o vorresti contriuire alla repository? Modifica questa pagina in Github!
You’re browsing the documentation for v2.x and earlier. For v3.x, click here.
This page assumes you’ve already read the Components Basics. Read that first if you are new to components.
In 2.6.0, we introduced a new unified syntax (the v-slot directive) for named and scoped slots. It replaces the slot and slot-scope attributes, which are now deprecated, but have not been removed and are still documented here. The rationale for introducing the new syntax is described in this RFC.Slot Content
Vue implements a content distribution API inspired by the 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, <slot></slot> will be replaced by “Your Profile”. Slots can contain any template code, including HTML:
Or even other components:
If <navigation-link>‘s template did not contain a <slot> element, any content provided between its opening and closing tag would be discarded.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.Fallback Content
There are cases when it’s useful to specify fallback (i.e. default) content for a slot, to be rendered only when no content is provided. For example, in a <submit-button> component:
We might want the text “Submit” to be rendered inside the <button> most of the time. To make “Submit” the fallback content, we can place it in between the <slot> tags:
Now when we use <submit-button> in a parent component, providing no content for the slot:
will render the fallback content, “Submit”:
But if we provide content:
Then the provided content will be rendered instead:Named Slots
Updated in 2.6.0+. See here for the deprecated syntax using the slot attribute.
There are times when it’s useful to have multiple slots. For example, in a <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:
A <slot> outlet without name implicitly has the name “default”.
To provide content to named slots, we can use the v-slot directive on a <template>, providing the name of the slot as v-slot‘s argument:
Now everything inside the <template> elements will be passed to the corresponding slots. Any content not wrapped in a <template> using v-slot is assumed to be for the default slot.
However, you can still wrap default slot content in a <template> if you wish to be explicit:
Either way, the rendered HTML will be:
Note that v-slot can only be added to a <template> (with one exception), unlike the deprecated slot attribute.Scoped Slots
Updated in 2.6.0+. See here for the deprecated syntax using the slot-scope attribute.
Sometimes, it’s useful for slot content to have access to data only available in the child component. For example, imagine a <current-user> component with the following template:
We might want to replace this fallback content to display the user’s first name, instead of last, like this:
That won’t work, however, because only the <current-user> component has access to the user and the content we’re providing is rendered in the parent.
To make user available to the slot content in the parent, we can bind user as an attribute to the <slot> element:
Attributes bound to a <slot> element are called slot props. Now, in the parent scope, we can use v-slot with a value to define a name for the slot props we’ve been provided:
In this example, we’ve chosen to name the object containing all our slot props slotProps, but you can use any name you like.Abbreviated Syntax for Lone Default Slots
In cases like above, when only the default slot is provided content, the component’s tags can be used as the slot’s template. This allows us to use v-slot directly on the component:
This can be shortened even further. Just as non-specified content is assumed to be for the default slot, v-slot without an argument is assumed to refer to the default slot:
Note that the abbreviated syntax for default slot cannot be mixed with named slots, as it would lead to scope ambiguity:
Whenever there are multiple slots, use the full <template> based syntax for all slots:Destructuring Slot Props
Internally, scoped slots work by wrapping your slot content in a function passed a single argument:
That means the value of v-slot can actually accept any valid JavaScript expression that can appear in the argument position of a function definition. So in supported environments (single-file components or modern browsers), you can also use ES2015 destructuring to pull out specific slot props, like so:
This can make the template much cleaner, especially when the slot provides many props. It also opens other possibilities, such as renaming props, e.g. user to person:
You can even define fallbacks, to be used in case a slot prop is undefined:Dynamic Slot Names
New in 2.6.0+
Dynamic directive arguments also work on v-slot, allowing the definition of dynamic slot names:Named Slots Shorthand
New in 2.6.0+
Similar to v-on and v-bind, v-slot also has a shorthand, replacing everything before the argument (v-slot:) with the special symbol #. For example, v-slot:header can be rewritten as #header:
However, just as with other directives, the shorthand is only available when an argument is provided. That means the following syntax is invalid:
Instead, you must always specify the name of the slot if you wish to use the shorthand:Other Examples
Slot props allow us to turn slots into reusable templates that can render different content based on input props. This is most useful when you are designing a reusable component that encapsulates data logic while allowing the consuming parent component to customize part of its layout.
For example, we are implementing a <todo-list> component that contains the layout and filtering logic for a list:
Instead of hard-coding the content for each todo, we can let the parent component take control by making every todo a slot, then binding todo as a slot prop:
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:
However, even this barely scratches the surface of what scoped slots are capable of. For real-life, powerful examples of scoped slot usage, we recommend browsing libraries such as Vue Virtual Scroller, Vue Promised, and Portal Vue.Deprecated SyntaxJsx Vue Slots
The v-slot directive was introduced in Vue 2.6.0, offering an improved, alternative API to the still-supported slot and slot-scope attributes. The full rationale for introducing v-slot is described in this RFC. The slot and slot-scope attributes will continue to be supported in all future 2.x releases, but are officially deprecated and will eventually be removed in Vue 3.Named Slots with the slot Attribute
Deprecated in 2.6.0+. See here for the new, recommended syntax.
To pass content to named slots from the parent, use the special slot attribute on <template> (using the <base-layout> component described here as example):
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 for any unmatched content. In both examples above, the rendered HTML would be:Scoped Slots with the slot-scope Attribute
Deprecated in 2.6.0+. See here for the new, recommended syntax.Vue Jsx Slot Props
To receive props passed to a slot, the parent component can use <template> with the slot-scope attribute (using the <slot-example> described here as example):
Here, slot-scope declares the received props object as the slotProps variable, and makes it available inside the <template> scope. You can name slotProps anything you like similar to naming function arguments in JavaScript.Vue Scoped Slots Jsx
Here slot=’default’ can be omitted as it is implied:
The slot-scope attribute can also be used directly on a non-<template> element (including components):
The value of slot-scope can 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:
Using t
https://diarynote-jp.indered.space
コメント