new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Vue · Guide · all subjects

components/slots

20 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Slot content and outlet definition

A slot outlet is a <slot> element in a child component's template that indicates where parent-provided slot content should be rendered. Slot content is the template fragment passed from the parent component. When the component renders, the slot content replaces the <slot> outlet.

Slot content render scope

Slot content has access to the data scope of the parent component because it is defined in the parent. Slot content does not have access to the child component's data. Expressions in Vue templates follow JavaScript's lexical scoping: expressions in the parent template only have access to the parent scope; expressions in the child template only have access to the child scope.

Fallback content in slots

Fallback (default) content can be placed between <slot> tags. This content is rendered only when no content is provided by the parent component. If the parent provides slot content, the provided content overrides the fallback content.

Named slots with v-slot directive

Multiple slot outlets in a single component are defined using the name attribute on <slot> elements. A <slot> without name implicitly has the name "default". To pass content to named slots from the parent, use a <template> element with the v-slot directive, passing the slot name as an argument: <template v-slot:slotName>. The v-slot directive has a shorthand #: <template #slotName>.

Implicit default slot in named slots

When a component accepts both a default slot and named slots, all top-level non-<template> nodes in the parent are implicitly treated as content for the default slot. Only <template> elements are subject to slot targeting; other elements automatically go to the default slot.

Conditional slot rendering with $slots

Use the $slots property in combination with v-if to render content conditionally based on whether a slot has content. $slots is an object where keys are slot names (strings) and values indicate whether that slot has content. This allows wrapping slot content with additional styling only when content is provided.

Dynamic slot names

Dynamic directive arguments work on v-slot, allowing dynamic slot names: <template v-slot:[dynamicSlotName]> or with shorthand <template #[dynamicSlotName]>. The expression is subject to the syntax constraints of dynamic directive arguments.

Scoped slots - passing data from child to parent

Scoped slots allow the child component to pass data to a slot when rendering it. The child passes attributes to a slot outlet just like passing props to a component. The parent template receives slot props using v-slot directive. In the child: <slot text="hello" :count="1" />. In the parent: <ChildComponent v-slot="receivedProps"> {{ receivedProps.text }} {{ receivedProps.count }} </ChildComponent>. The props passed by the child become available as the value of the v-slot directive.

Scoped slots as function analogy

Scoped slots can be understood as functions being passed into a child component. The child component calls the function, passing props as arguments. The parent provides the function body via v-slot, and the child invokes it with data. This is similar to the compiled output and render functions.

Destructuring in v-slot

Like function arguments, v-slot supports destructuring: <ChildComponent v-slot="{ text, count }"> {{ text }} {{ count }} </ChildComponent>. This allows accessing specific props directly without the receiver object.

Named scoped slots

Named scoped slots work similarly to regular named slots, but slot props are accessible via the v-slot directive: <template #header="headerProps"> {{ headerProps }} </template>. The name attribute of a slot is reserved and not included in the props object, so only the passed attributes appear in the received props.

Explicit template required for default scoped slot with named slots

When mixing named slots with default scoped slots, an explicit <template> tag must be used for the default slot. Attempting to place v-slot directly on the component will result in a compilation error. This avoids ambiguity about which scope the default slot props belong to. Use <template #default="{ props }"> explicitly rather than placing v-slot on the parent component.

Scoped slots example - FancyList

A FancyList component can render a list multiple times with different item data while allowing flexible item styling via scoped slots. Parent usage: <FancyList :api-url="url" :per-page="10"> <template #item="{ body, username, likes }"> <div class="item"> <p>{{ body }}</p> <p>by {{ username }} | {{ likes }} likes</p> </div> </template> </FancyList>. Child renders with v-bind to pass object as slot props: <ul> <li v-for="item in items"> <slot name="item" v-bind="item" /> </li> </ul>.

Renderless components pattern

Renderless components encapsulate logic only and do not render anything themselves. Visual output is fully delegated to the consumer component via scoped slots. Example: <MouseTracker v-slot="{ x, y }"> Mouse is at: {{ x }}, {{ y }} </MouseTracker>. Renderless components separate concern of logic from presentation.

Renderless components vs Composition API

While renderless components are a useful pattern for encapsulating logic and composing visual output, most of what can be achieved with renderless components can be achieved more efficiently with Composition API without the overhead of extra component nesting.

Using slots to distribute content to components

The <slot> element acts as a placeholder in a component's template where parent content is inserted. Parent passes content between opening and closing tags: <AlertBox>Something bad happened.</AlertBox>. Child defines where this content appears using <slot /> in its template.

Rendering slots in Composition API

In Composition API render functions, slots are accessed from the setup() context as an object. Each slot is a function that returns an array of vnodes. Access default slot with slots.default() and named slots with slots.footer({ text: props.message }). The slot function receives an object of props to pass to the parent.

Rendering slots in Options API

In Options API render functions, slots are accessed from this.$slots. Each slot is a function that returns an array of vnodes. Access default slot with this.$slots.default() and named slots with this.$slots.footer({ text: this.message }).

Passing slots to child components in render functions

When passing slots to child components, pass either a slot function or an object of slot functions, not an array. Usage: h(MyComponent, () => 'hello') for default slot, or h(MyComponent, null, { default: () => 'default slot', foo: () => h('div', 'foo') }) for named slots. The null argument prevents the slots object from being treated as props. In JSX: <MyComponent>{() => 'hello'}</MyComponent> or <MyComponent>{{ default: () => 'default slot', foo: () => <div>foo</div> }}</MyComponent>.

Scoped slots in render functions

Scoped slots are rendered by passing a slot function with parameters to the child component. The parent passes a slot that receives scoped data: h(MyComp, null, { default: ({ text }) => h('p', text) }). Remember to pass null so slots are not treated as props. The child component invokes the slot: h('div', null, slots.default({ text: text.value })).

Give your agent this brain