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

198 notes in this subject, read out of this brain and free to use. This is page 1 of 4.

hydrateOnInteraction example with single event

import { defineAsyncComponent, hydrateOnInteraction } from 'vue' const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: hydrateOnInteraction('click') })

defineAsyncComponent loading and error states options

defineAsyncComponent supports an options object with: loader (the loader function), loadingComponent (component to display while loading), delay (default 200ms before showing loading component), errorComponent (component to display on load failure), and timeout (default Infinity, shows error component if exceeded).

defineAsyncComponent basic usage with Promise

defineAsyncComponent accepts a loader function that returns a Promise. The Promise's resolve callback should be called when you have retrieved the component definition from the server. You can also call reject(reason) to indicate the load has failed.

hydrateOnMediaQuery example

import { defineAsyncComponent, hydrateOnMediaQuery } from 'vue' const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: hydrateOnMediaQuery('(max-width:500px)') })

hydrateOnVisible strategy

hydrateOnVisible hydrates an async component when element(s) become visible via IntersectionObserver. It can optionally accept an options object with properties like rootMargin for configuring the observer. Available in Vue 3.5+ for Server-Side Rendering.

Custom hydration strategy example

import { defineAsyncComponent, type HydrationStrategy } from 'vue' const myStrategy: HydrationStrategy = (hydrate, forEachElement) => { // forEachElement is a helper to iterate through all the root elements // in the component's non-hydrated DOM, since the root can be a fragment // instead of a single element forEachElement(el => { // ... }) // call `hydrate` when ready hydrate() return () => { // return a teardown function if needed } } const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: myStrategy })

hydrateOnVisible example

import { defineAsyncComponent, hydrateOnVisible } from 'vue' const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: hydrateOnVisible() })

defineAsyncComponent with loading and error states example

const AsyncComp = defineAsyncComponent({ // the loader function loader: () => import('./Foo.vue'), // A component to use while the async component is loading loadingComponent: LoadingComponent, // Delay before showing the loading component. Default: 200ms. delay: 200, // A component to use if the load fails errorComponent: ErrorComponent, // The error component will be displayed if a timeout is // provided and exceeded. Default: Infinity. timeout: 3000 })

Loading component delay default behavior

The default delay before showing a loading component is 200ms. This prevents the loading state from appearing as a flicker on fast networks when it would be replaced too quickly.

defineAsyncComponent basic example

import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { // ...load component from server resolve(/* loaded component */) }) })

hydrateOnVisible with options example

hydrateOnVisible({ rootMargin: '100px' })

hydrateOnInteraction example with multiple events

hydrateOnInteraction(['wheel', 'mouseover'])

Async components with global registration

Async components can be registered globally using app.component() with defineAsyncComponent.

hydrateOnMediaQuery strategy

hydrateOnMediaQuery hydrates an async component when the specified media query matches. It takes a media query string as a parameter. Available in Vue 3.5+ for Server-Side Rendering.

defineAsyncComponent with dynamic import

defineAsyncComponent can be used with ES module dynamic import to lazily load Vue SFCs. Bundlers like Vite and webpack support this syntax and will use it as bundle split points.

hydrateOnIdle strategy

hydrateOnIdle hydrates an async component via requestIdleCallback. It can optionally be passed a max timeout parameter. Available in Vue 3.5+ for Server-Side Rendering.

hydrateOnIdle example

import { defineAsyncComponent, hydrateOnIdle } from 'vue' const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: hydrateOnIdle(/* optionally pass a max timeout */) })

Error component timeout behavior

If a timeout is provided to defineAsyncComponent, the error component will be displayed if the timeout is exceeded. The default timeout is Infinity.

Async component wrapper behavior

The resulting AsyncComp from defineAsyncComponent is a wrapper component that only calls the loader function when it is actually rendered on the page. It passes along any props and slots to the inner component, allowing it to seamlessly replace the original component while achieving lazy loading.

defineAsyncComponent with dynamic import example

import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => import('./components/MyComponent.vue') )

Async components with Suspense

Async components can be used with the Suspense built-in component. The interaction between Suspense and async components is documented in the dedicated Suspense chapter.

Custom hydration strategy

A custom hydration strategy is a function implementing HydrationStrategy that receives hydrate and forEachElement parameters. forEachElement is a helper to iterate through all root elements in the component's non-hydrated DOM. The strategy should call hydrate() when ready and can optionally return a teardown function. Available in Vue 3.5+ for Server-Side Rendering.

hydrateOnInteraction strategy

hydrateOnInteraction hydrates an async component when specified event(s) are triggered on the component element(s). The event that triggered the hydration will also be replayed once hydration is complete. Can accept a single event type string or an array of multiple event types. Available in Vue 3.5+ for Server-Side Rendering.

Nested component attribute forwarding

If a component renders another component as its root node, the fallthrough attributes received by the parent component will be automatically forwarded to the child component.

Class and style attribute merging

If the child component's root element already has existing class or style attributes, they will be merged with the class and style values inherited from the parent. For example, a parent passing class="large" to a child with class="btn" results in class="btn large" on the rendered element.

Fallthrough attributes definition

A fallthrough attribute is an attribute or v-on event listener that is passed to a component but is not explicitly declared in the receiving component's props or emits. Common examples include class, style, and id attributes.

Single root element automatic attribute inheritance

When a component renders a single root element, fallthrough attributes are automatically added to the root element's attributes.

V-on listener inheritance behavior

V-on event listeners follow the same fallthrough rules as attributes. A listener like @click passed to a component will be added to the root element. If the root element already has a click listener bound with v-on, both listeners will trigger.

Accessing $attrs via instance property in Options API

In the Options API, fallthrough attributes can be accessed via the $attrs instance property on the component, such as in the created() lifecycle hook: this.$attrs.

Forwarded attributes exclude declared props and listeners

When a component forwards attributes to a nested component, forwarded attributes do not include any attributes declared as props or v-on listeners of declared events by the forwarding component, as these have been consumed by that component.

Accessing attrs in setup context

When not using <script setup>, fallthrough attributes are exposed as the attrs property of the setup() context: setup(props, ctx) receives ctx.attrs containing the fallthrough attributes.

useAttrs() API for accessing fallthrough attributes

In <script setup>, you can access a component's fallthrough attributes using the useAttrs() API imported from 'vue': const attrs = useAttrs().

Multiple root nodes lack automatic attribute fallthrough

Components with multiple root nodes do not have automatic attribute fallthrough behavior. If $attrs are not bound explicitly, a runtime warning will be issued because Vue cannot determine where to apply the fallthrough attributes.

Using v-bind with $attrs to control attribute placement

The v-bind="$attrs" syntax binds all properties of the $attrs object as attributes to a target element. This is useful when inheritAttrs: false is set and you need to apply fallthrough attributes to a specific element other than the root.

V-on listeners in $attrs exposed as functions

A v-on event listener like @click will be exposed on the $attrs object as a function under $attrs.onClick.

$attrs preserves original attribute casing

Fallthrough attributes in the $attrs object preserve their original casing in JavaScript, so an attribute like foo-bar must be accessed as $attrs['foo-bar'], not $attrs.fooBar.

$attrs object access in templates

Fallthrough attributes can be accessed in template expressions as $attrs, which includes all attributes not declared by the component's props or emits options, such as class, style, and v-on listeners.

Suppressing multi-root attribute warning with explicit binding

In a multi-root component, the warning about unbound fallthrough attributes is suppressed when $attrs is explicitly bound to one of the root elements using v-bind="$attrs".

defineOptions for inheritance control in script setup

Since Vue 3.3, you can use defineOptions() directly in <script setup> to set inheritAttrs: false without needing to export a default object.

Disable attribute inheritance with inheritAttrs

To prevent a component from automatically inheriting attributes, set inheritAttrs: false in the component's options. This allows taking full control over where fallthrough attributes should be applied.

Mutating nested properties in object/array props

While the child component cannot mutate the prop binding itself, it will be able to mutate the object or array's nested properties because objects and arrays are passed by reference. As a best practice, avoid such mutations unless the parent and child are tightly coupled by design. The child should emit an event to let the parent perform the mutation.

Using prop as initial value for local data

When a prop is used to pass an initial value but the child component wants to use it as a local data property afterwards, define a local data property or ref that uses the prop as its initial value. For example: const counter = ref(props.initialCounter). This disconnects the local property from future prop updates.

Props are read-only

Props must not be mutated inside a child component. Attempting to mutate a prop (e.g., props.foo = 'bar') will trigger a console warning in Vue.

One-way data flow principle

All props form a one-way-down binding between the child property and the parent one. When the parent property updates, it flows down to the child, but not the other way around. Every time the parent component is updated, all props in the child component are refreshed with the latest value.

Merging regular props when combining bindings

When v-bind is used alongside explicit prop bindings on the same component, for regular props the last value wins. For example, <BlogPost title='foo' v-bind='{ title: "bar" }' /> will result in title === 'bar'.

Spreading object properties as props with v-bind

To pass all properties of an object as props, use v-bind without an argument (v-bind instead of :prop-name). For example, <BlogPost v-bind='post' /> where post has properties id and title is equivalent to <BlogPost :id='post.id' :title='post.title' />.

Array and object props require v-bind

To pass array or object values as props, v-bind must be used even for static values. For example: :comment-ids='[234, 266, 273]' or :author='{ name: "Veronica", company: "Veridian Dynamics" }'. Without v-bind, these would be passed as strings.

Boolean prop without value implies true

Including a boolean prop with no value will imply true. For example, <BlogPost is-published /> is equivalent to <BlogPost :is-published='true' />. To pass false, v-bind must be used: <BlogPost :is-published='false' />.

Passing number props requires v-bind

To pass a number as a prop, v-bind must be used even for static values. For example, :likes='42' tells Vue this is a JavaScript expression rather than a string. Without v-bind, the value would be passed as a string.

Static vs dynamic props

Props can be passed as static values (e.g., title='My journey with Vue') or dynamically with v-bind or its ':' shortcut (e.g., :title='post.title' or :title='post.title + " by " + post.author.name').

Prop name casing convention

Declare long prop names using camelCase (e.g., greetingMessage) in the component definition because this allows them to be used as property keys without quotes and referenced directly in template expressions. However, the convention is to use kebab-case when passing props to child components (e.g., greeting-message='hello') to align with HTML attributes conventions.

Watching destructured props

When passing a destructured prop into a function like watch(), wrap it in a getter to maintain reactivity. For example, use watch(() => foo, ...) instead of watch(foo, ...). This applies when passing destructured props to external functions as well.

Default values for destructured props

JavaScript's native default value syntax can be used to declare default values for destructured props, which is particularly useful with type-based props declaration. For example: const { foo = 'hello' } = defineProps<{ foo?: string }>()

Merging event listeners when combining bindings

When passing event listeners in a v-bind object, use the onEventName key convention. All handlers for the same event will be called. For example, <BlogPost @click='console.log(1)' v-bind='{ onClick: () => console.log(2) }' /> will log both 1 and 2.

Props destructuring with reactivity in Vue 3.5+

In Vue 3.5+, when destructuring props from defineProps, Vue's compiler automatically prepends 'props.' when accessing destructured variables. For example, const { foo } = defineProps(['foo']) followed by console.log(foo) is automatically transformed to console.log(props.foo). In version 3.4 and below, destructured props are constants that never change.

Object syntax for props declaration

In addition to declaring props using an array of strings, you can use object syntax where the key is the prop name and the value is the constructor function of the expected type. For example: defineProps({ title: String, likes: Number }). This documents the component and warns developers if they pass the wrong type.

Props declaration in non-setup components

In non-<script setup> components, props are declared using the props option. The props are received as the first argument to setup() in the Composition API, or exposed on 'this' in the Options API.

Transforming props with computed properties

When a prop is passed as a raw value that needs to be transformed, define a computed property using the prop's value. This ensures the computed value auto-updates when the prop changes. For example: const normalizedSize = computed(() => props.size.trim().toLowerCase())

Props declaration with defineProps macro

In SFC with <script setup>, props are declared using the defineProps() macro. The macro returns a props object that can be accessed. For example: const props = defineProps(['foo']); console.log(props.foo). The argument passed to defineProps() is the same as the value provided to the props option in non-setup components.

Required but nullable prop

To require a prop but allow it to be nullable, use the array syntax that includes null. For example: propD: { type: [String, null], required: true }

Give your agent this brain