From 0481a1dfef290e1ddb7e510f1bbb838e3277e771 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 29 Aug 2024 16:25:04 +0800 Subject: [PATCH 01/17] 3.5: failSilently for onScopeDispose --- src/api/reactivity-advanced.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/api/reactivity-advanced.md b/src/api/reactivity-advanced.md index 2e63a5aeba..825b2373f5 100644 --- a/src/api/reactivity-advanced.md +++ b/src/api/reactivity-advanced.md @@ -336,8 +336,10 @@ Registers a dispose callback on the current active [effect scope](#effectscope). This method can be used as a non-component-coupled replacement of `onUnmounted` in reusable composition functions, since each Vue component's `setup()` function is also invoked in an effect scope. +A warning will be thrown if this function is called without an active effect scope. In 3.5+, this warning can be suppressed by passing `true` as the second argument. + - **Type** ```ts - function onScopeDispose(fn: () => void): void + function onScopeDispose(fn: () => void, failSilently?: boolean): void ``` From db3ba8dc88b44cccd86fd7d238ac9799c9f6e0ae Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 29 Aug 2024 17:02:54 +0800 Subject: [PATCH 02/17] 3.5: reactive props destructure --- src/api/sfc-script-setup.md | 45 ++++++++++++++++++++++--- src/guide/components/props.md | 39 +++++++++++++++++++++ src/guide/typescript/composition-api.md | 17 ++++++++-- 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/api/sfc-script-setup.md b/src/api/sfc-script-setup.md index d7ee22d963..fe955a6eaa 100644 --- a/src/api/sfc-script-setup.md +++ b/src/api/sfc-script-setup.md @@ -209,12 +209,48 @@ const emit = defineEmits<{ This limitation has been resolved in 3.3. The latest version of Vue supports referencing imported and a limited set of complex types in the type parameter position. However, because the type to runtime conversion is still AST-based, some complex types that require actual type analysis, e.g. conditional types, are not supported. You can use conditional types for the type of a single prop, but not the entire props object. -### Default props values when using type declaration {#default-props-values-when-using-type-declaration} +### Reactive Props Destructure {#reactive-props-destructure} -One drawback of the type-only `defineProps` declaration is that it doesn't have a way to provide default values for the props. To resolve this problem, a `withDefaults` compiler macro is also provided: +In Vue 3.5 and above, variables destructured from the return value of `defineProps` are reactive. Vue's compiler automatically prepends `props.` when code in the same ` + + + ``` + +- **Details** + + IDs generated by `useId()` are unique-per-application. It can be used to generate IDs for form elements and accessibility attributes. Multiple calls in the same component will generate different IDs; multiple instances of the same component calling `useId()` will also have different IDs. + + IDs generated by `useId()` are also guaranteed to be stable across the server and client renders, so they can be used in SSR applications without leading to hydration mismatches. + + If you have more than one Vue application instance of the same page, you can avoid ID conflicts by giving each app an ID prefix via [`app.config.idPrefix`](/api/application#app-config-idprefix). From c44739a52fcd9dece01eac1ef25837c47b9d6e6a Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 30 Aug 2024 15:11:32 +0800 Subject: [PATCH 06/17] 3.5: lazy hydration --- src/guide/components/async.md | 99 +++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/src/guide/components/async.md b/src/guide/components/async.md index 4927549f6a..fe786b969d 100644 --- a/src/guide/components/async.md +++ b/src/guide/components/async.md @@ -108,6 +108,105 @@ If a loading component is provided, it will be displayed first while the inner c If an error component is provided, it will be displayed when the Promise returned by the loader function is rejected. You can also specify a timeout to show the error component when the request is taking too long. +## Lazy Hydration {#lazy-hydration} + +> This section only applies if you are using [Server-Side Rendering](/guide/scaling-up/ssr). + +In Vue 3.5+, async components can control when they are hydrated by providing a hydration strategy. + +- Vue provides a number of built-in hydration strategies. These built-in strategies need to be individually imported so they can be tree-shaken if not used. + +- The design is intentionally low-level for flexibility. Compiler syntax sugar can potentially be built on top of this in the future either in core or in higher level solutions (e.g. Nuxt). + +### Hydrate on Idle + +Hydrates via `requestIdleCallback`: + +```js +import { defineAsyncComponent, hydrateOnIdle } from 'vue' + +const AsyncComp = defineAsyncComponent({ + loader: () => import('./Comp.vue'), + hydrate: hydrateOnIdle(/* optionally pass a max timeout */) +}) +``` + +### Hydrate on Visible + +Hydrate when element(s) become visible via `IntersectionObserver`. + +```js +import { defineAsyncComponent, hydrateOnVisible } from 'vue' + +const AsyncComp = defineAsyncComponent({ + loader: () => import('./Comp.vue'), + hydrate: hydrateOnVisible() +}) +``` + +Can optionally pass in an options object value for the observer: + +```js +hydrateOnVisible({ rootMargin: '100px' }) +``` + +### Hydrate on Media Query + +Hydrates when the specified media query matches. + +```js +import { defineAsyncComponent, hydrateOnMediaQuery } from 'vue' + +const AsyncComp = defineAsyncComponent({ + loader: () => import('./Comp.vue'), + hydrate: hydrateOnMediaQuery('(max-width:500px)') +}) +``` + +### Hydrate on Interaction + +Hydrates 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. + +```js +import { defineAsyncComponent, hydrateOnInteraction } from 'vue' + +const AsyncComp = defineAsyncComponent({ + loader: () => import('./Comp.vue'), + hydrate: hydrateOnInteraction('click') +}) +``` + +Can also be a list of multiple event types: + +```js +hydrateOnInteraction(['wheel', 'mouseover']) +``` + +### Custom Strategy + +```ts +import { defineAsyncComponent, type HydrationStrategy } from 'vue' + +const myStrategy: HydrationStrategy = (hydrate, forEachElement) => { + // forEachElement is a helper to iterate through all the root elememts + // 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 +}) +``` + ## Using with Suspense {#using-with-suspense} Async components can be used with the `` built-in component. The interaction between `` and async components is documented in the [dedicated chapter for ``](/guide/built-ins/suspense). From caa99ca611ef18e863848d07d2249e4b8801ec36 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 30 Aug 2024 15:20:44 +0800 Subject: [PATCH 07/17] 3.5: data-allow-mismatch --- src/api/ssr.md | 20 ++++++++++++++++++++ src/guide/scaling-up/ssr.md | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/src/api/ssr.md b/src/api/ssr.md index a85101323a..a39ea41876 100644 --- a/src/api/ssr.md +++ b/src/api/ssr.md @@ -220,3 +220,23 @@ A runtime API used to retrieve the context object passed to `renderToString()` o } ``` + +## data-allow-mismatch {#data-allow-mismatch} + +A special attribute that can be used to suppress [hydration mismatch](/guide/scaling-up/ssr#hydration-mismatch) warnings. + +- **Example** + + ```html +
{{ data.toLocaleString() }}
+ ``` + + The value can limit the allowed mismatch to a specific type. Allowed values are: + + - `text` + - `children` (only allows mismatch for direct children) + - `class` + - `style` + - `attribute` + + If no value is provided, all types of mismatches will be allowed. diff --git a/src/guide/scaling-up/ssr.md b/src/guide/scaling-up/ssr.md index 780c6c1ba0..c78ce0b7be 100644 --- a/src/guide/scaling-up/ssr.md +++ b/src/guide/scaling-up/ssr.md @@ -314,6 +314,10 @@ If the DOM structure of the pre-rendered HTML does not match the expected output When Vue encounters a hydration mismatch, it will attempt to automatically recover and adjust the pre-rendered DOM to match the client-side state. This will lead to some rendering performance loss due to incorrect nodes being discarded and new nodes being mounted, but in most cases, the app should continue to work as expected. That said, it is still best to eliminate hydration mismatches during development. +#### Suppressing Hydration Mismatches {#suppressing-hydration-mismatches} + +In Vue 3.5+, it is possible to selectively suppress inevitable hydration mismatches by using the [`data-allow-mismatch`](/api/ssr#data-allow-mismatch) attribute. + ### Custom Directives {#custom-directives} Since most custom directives involve direct DOM manipulation, they are ignored during SSR. However, if you want to specify how a custom directive should be rendered (i.e. what attributes it should add to the rendered element), you can use the `getSSRProps` directive hook: From 43b0da63361121fa9721e26c79998f02a7c7c7d4 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 30 Aug 2024 15:53:50 +0800 Subject: [PATCH 08/17] 3.5: add composition api helpers page --- .vitepress/config.ts | 4 +++ src/api/composition-api-helpers.md | 40 ++++++++++++++++++++++++++++++ src/api/general.md | 31 ----------------------- 3 files changed, 44 insertions(+), 31 deletions(-) create mode 100644 src/api/composition-api-helpers.md diff --git a/.vitepress/config.ts b/.vitepress/config.ts index dd0f10a780..41f0df0c9c 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -368,6 +368,10 @@ export const sidebar: ThemeConfig['sidebar'] = { { text: 'Dependency Injection', link: '/api/composition-api-dependency-injection' + }, + { + text: 'Helpers', + link: '/api/composition-api-helpers' } ] }, diff --git a/src/api/composition-api-helpers.md b/src/api/composition-api-helpers.md new file mode 100644 index 0000000000..6cbe39314d --- /dev/null +++ b/src/api/composition-api-helpers.md @@ -0,0 +1,40 @@ +# Composition API: Helpers {#composition-api-helpers} + +## useAttrs() {#useattrs} + +## useSlots() {#useslots} + +## useModel() {#usemodel} + +## useTemplateRef() {#usetemplateref} + +## useId() {#useid} + +`useId()` is an API that can be used to generate unique-per-application IDs. + +- **Composition API only.** + +- **Example** + + ```vue + + + + ``` + +- **Details** + + IDs generated by `useId()` are unique-per-application. It can be used to generate IDs for form elements and accessibility attributes. Multiple calls in the same component will generate different IDs; multiple instances of the same component calling `useId()` will also have different IDs. + + IDs generated by `useId()` are also guaranteed to be stable across the server and client renders, so they can be used in SSR applications without leading to hydration mismatches. + + If you have more than one Vue application instance of the same page, you can avoid ID conflicts by giving each app an ID prefix via [`app.config.idPrefix`](/api/application#app-config-idprefix). diff --git a/src/api/general.md b/src/api/general.md index 569412c552..80eec455f9 100644 --- a/src/api/general.md +++ b/src/api/general.md @@ -266,34 +266,3 @@ This method accepts the same argument as [`defineComponent`](#definecomponent), - [Guide - Building Custom Elements with Vue](/guide/extras/web-components#building-custom-elements-with-vue) - Also note that `defineCustomElement()` requires [special config](/guide/extras/web-components#sfc-as-custom-element) when used with Single-File Components. - -## useId() {#useid} - -`useId()` is an API that can be used to generate unique-per-application IDs. - -- **Composition API only.** - -- **Example** - - ```vue - - - - ``` - -- **Details** - - IDs generated by `useId()` are unique-per-application. It can be used to generate IDs for form elements and accessibility attributes. Multiple calls in the same component will generate different IDs; multiple instances of the same component calling `useId()` will also have different IDs. - - IDs generated by `useId()` are also guaranteed to be stable across the server and client renders, so they can be used in SSR applications without leading to hydration mismatches. - - If you have more than one Vue application instance of the same page, you can avoid ID conflicts by giving each app an ID prefix via [`app.config.idPrefix`](/api/application#app-config-idprefix). From 256b92a119116824ef6f214aa464e7612981380e Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 30 Aug 2024 16:06:15 +0800 Subject: [PATCH 09/17] useAttrs, useSlots, useModel --- src/api/composition-api-helpers.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/api/composition-api-helpers.md b/src/api/composition-api-helpers.md index 6cbe39314d..c5757327ff 100644 --- a/src/api/composition-api-helpers.md +++ b/src/api/composition-api-helpers.md @@ -2,18 +2,39 @@ ## useAttrs() {#useattrs} +Returns the `attrs` object from the [Setup Context](/api/composition-api-setup#setup-context), which includes the [fallthrough attributes](/guide/components/attrs#fallthrough-attributes) of the current component. This is intended to be used in ` + + + ``` + +- **See also** + - [Guide - Template Refs](/guide/essentials/template-refs) + - [Guide - Typing Template Refs](/guide/typescript/composition-api#typing-template-refs) + - [Guide - Typing Component Template Refs](/guide/typescript/composition-api#typing-component-template-refs) + ## useId() {#useid} -`useId()` is an API that can be used to generate unique-per-application IDs. +Used to generate unique-per-application IDs for accessibility attributes or form elements. + +- **Type** + + ```ts + function useId(): string + ``` - **Example** @@ -55,7 +119,7 @@ This is the underlying helper that powers [`defineModel()`](/api/sfc-script-setu - **Details** IDs generated by `useId()` are unique-per-application. It can be used to generate IDs for form elements and accessibility attributes. Multiple calls in the same component will generate different IDs; multiple instances of the same component calling `useId()` will also have different IDs. - + IDs generated by `useId()` are also guaranteed to be stable across the server and client renders, so they can be used in SSR applications without leading to hydration mismatches. If you have more than one Vue application instance of the same page, you can avoid ID conflicts by giving each app an ID prefix via [`app.config.idPrefix`](/api/application#app-config-idprefix). diff --git a/src/guide/essentials/template-refs.md b/src/guide/essentials/template-refs.md index 499963255c..04624e13c8 100644 --- a/src/guide/essentials/template-refs.md +++ b/src/guide/essentials/template-refs.md @@ -12,7 +12,32 @@ While Vue's declarative rendering model abstracts away most of the direct DOM op
-To obtain the reference with Composition API, we need to declare a ref with a name that matches the template ref attribute's value: +To obtain the reference with Composition API, we can use the [`useTemplateRef()`](/api/composition-api-helpers#usetemplateref) helper: + +```vue + + + +``` + +When using TypeScript, Vue's IDE support and `vue-tsc` will automatically infer the type of `inputRef.value` based on what element or component the matching `ref` attribute is used on. + +
+Usage before 3.5 + +In versions before 3.5 where `useTemplateRef()` was not introduced, we need to declare a ref with a name that matches the template ref attribute's value: ```vue + + +``` + +[Try it in the Playground](https://play.vuejs.org/#eNp9UsluwjAQ/ZWRLwQpDepyQoDUIg6t1EWUW91DFAZq6tiWF4oU5d87dtgqVRyyzLw3b+aN3bB7Y4ptQDZkI1dZYTw49MFMuBK10dZDAxZXOQSHC6yNLD3OY6zVsw7K4xJaWFldQ49UelxxVWnlPEhBr3GszT6uc7jJ4fazf4KFx5p0HFH+Kme9CLle4h6bZFkfxhNouAIoJVqfHQSKbSkDFnVpMhEpovC481NNVcr3SaWlZzTovJErCqgydaMIYBRk+tKfFLC9Wmk75iyqg1DJBWfRxT7pONvTAZom2YC23QsMpOg0B0l0NDh2YjnzjpyvxLrYOK1o3ckLZ5WujSBHr8YL2gxnw85lxEop9c9TynkbMD/kqy+svv/Jb9wu5jh7s+jQbpGzI+ZLu0byEuHZ+wvt6Ays9TJIYl8A5+i0DHHGjvYQ1JLGPuOlaR/TpRFqvXCzHR2BO5iKg0Zmm/ic0W2ZXrB+Gve2uEt1dJKs/QXbwePE) + +
+Usage before 3.5 + ```vue + + +``` + +
+Usage before 3.5 + ```vue -``` +In cases where auto-inference is not possible (e.g. non-SFC usage or dynamic components), you can still cast the template ref to an explicit type via the generic argument. -In order to get the instance type of `MyModal`, we need to first get its type via `typeof`, then use TypeScript's built-in `InstanceType` utility to extract its instance type: +In order to get the instance type of an imported component, we need to first get its type via `typeof`, then use TypeScript's built-in `InstanceType` utility to extract its instance type: ```vue{5} + + ``` In cases where the exact type of the component isn't available or isn't important, `ComponentPublicInstance` can be used instead. This will only include properties that are shared by all components, such as `$el`: ```ts -import { ref } from 'vue' +import { useTemplateRef } from 'vue' import type { ComponentPublicInstance } from 'vue' -const child = ref(null) +const child = useTemplateRef(null) ``` In cases where the component referenced is a [generic component](/guide/typescript/overview.html#generic-components), for instance `MyGenericModal`: @@ -457,11 +463,11 @@ It needs to be referenced using `ComponentExposed` from the [`vue-component-type ```vue ``` +Note that with `@vue/language-tools` 2.1+, static template refs' types can be automatically inferred and the above is only needed in edge cases. From 5c0ee2ba002bd8442568d874b5ffea7ad0b893b2 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 30 Aug 2024 18:03:59 +0800 Subject: [PATCH 11/17] app.config.throwUnhandledErrorInProduction --- src/api/application.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/api/application.md b/src/api/application.md index 132c34d29a..328f000e45 100644 --- a/src/api/application.md +++ b/src/api/application.md @@ -90,6 +90,18 @@ Unmounts a mounted application instance, triggering the unmount lifecycle hooks } ``` +## app.onUnmount() {#app-onunmount} + +Registers a callback to be called when the app is unmounted. + +- **Type** + + ```ts + interface App { + onUnmount(callback: () => any): void + } + ``` + ## app.component() {#app-component} Registers a global component if passing both a name string and a component definition, or retrieves an already registered one if only the name is passed. @@ -619,7 +631,7 @@ Configure a prefix for all IDs generated via [useId()](/api/general#useid) insid - **Default:** `undefined` -- **Example:** +- **Example** ```js app.config.idPrefix = 'my-app' @@ -630,3 +642,21 @@ Configure a prefix for all IDs generated via [useId()](/api/general#useid) insid const id1 = useId() // 'my-app:0' const id2 = useId() // 'my-app:1' ``` + +## app.config.throwUnhandledErrorInProduction {#app-config-throwunhandlederrorinproduction} + +Force unhandled errors to be thrown in production mode. + +- **Type:** `boolean` + +- **Default:** `false` + +- **Details** + + By default, errors thrown inside a Vue application but not explicit handled have different behavior between development and production modes: + + - In development, the error is thrown and can possibly crash the application. This is to make the error more prominent so that it can be noticed and fixed during development. + + - In production, the error will only be logged to the console to minimize the impact to end users. However, this may prevent errors that only happen in production from being caught by error monitoring services. + + By setting `app.config.throwUnhandledErrorInProduction` to `true`, unhandled errors will be thrown even in production mode. From 6860d600a0dd6c2bcfefb699f97631ac78b2fb53 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 30 Aug 2024 18:09:59 +0800 Subject: [PATCH 12/17] remove version badages for previous minors --- src/api/application.md | 4 +++- src/api/built-in-directives.md | 10 ++++++---- src/api/compile-time-flags.md | 4 +++- src/api/composition-api-dependency-injection.md | 4 +++- src/api/composition-api-helpers.md | 8 ++++++-- src/api/general.md | 4 +++- src/api/reactivity-core.md | 4 ++-- src/api/reactivity-utilities.md | 4 +++- src/api/sfc-script-setup.md | 4 +++- src/guide/best-practices/performance.md | 4 ++-- src/guide/essentials/template-syntax.md | 4 +++- src/guide/essentials/watchers.md | 4 +++- 12 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/api/application.md b/src/api/application.md index 328f000e45..189422bcb7 100644 --- a/src/api/application.md +++ b/src/api/application.md @@ -283,10 +283,12 @@ Provide a value that can be injected in all descendant components within the app - [App-level Provide](/guide/components/provide-inject#app-level-provide) - [app.runWithContext()](#app-runwithcontext) -## app.runWithContext() {#app-runwithcontext} +## app.runWithContext() {#app-runwithcontext} Execute a callback with the current app as injection context. +- Only supported in 3.3+ + - **Type** ```ts diff --git a/src/api/built-in-directives.md b/src/api/built-in-directives.md index c0a3b6e814..8afb0bfc48 100644 --- a/src/api/built-in-directives.md +++ b/src/api/built-in-directives.md @@ -259,7 +259,7 @@ Dynamically bind one or more attributes, or a component prop to an expression. - **Shorthand:** - `:` or `.` (when using `.prop` modifier) - - Omitting value (when attribute and bound value has the same name) 3.4+ + - Omitting value (when attribute and bound value has the same name, requires 3.4+) - **Expects:** `any (with argument) | Object (without argument)` @@ -268,8 +268,8 @@ Dynamically bind one or more attributes, or a component prop to an expression. - **Modifiers** - `.camel` - transform the kebab-case attribute name into camelCase. - - `.prop` - force a binding to be set as a DOM property. 3.2+ - - `.attr` - force a binding to be set as a DOM attribute. 3.2+ + - `.prop` - force a binding to be set as a DOM property (3.2+). + - `.attr` - force a binding to be set as a DOM attribute (3.2+). - **Usage** @@ -468,7 +468,9 @@ Render the element and component once only, and skip future updates. - [Data Binding Syntax - interpolations](/guide/essentials/template-syntax#text-interpolation) - [v-memo](#v-memo) -## v-memo {#v-memo} +## v-memo {#v-memo} + +- Only supported in 3.2+ - **Expects:** `any[]` diff --git a/src/api/compile-time-flags.md b/src/api/compile-time-flags.md index cdd59fca68..b590cad810 100644 --- a/src/api/compile-time-flags.md +++ b/src/api/compile-time-flags.md @@ -26,12 +26,14 @@ See [Configuration Guides](#configuration-guides) on how to configure them depen Enable / disable devtools support in production builds. This will result in more code included in the bundle, so it is recommended to only enable this for debugging purposes. -## `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__` {#VUE_PROD_HYDRATION_MISMATCH_DETAILS} +## `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__` {#VUE_PROD_HYDRATION_MISMATCH_DETAILS} - **Default:** `false` Enable/disable detailed warnings for hydration mismatches in production builds. This will result in more code included in the bundle, so it is recommended to only enable this for debugging purposes. +- Only available in 3.4+ + ## Configuration Guides {#configuration-guides} ### Vite {#vite} diff --git a/src/api/composition-api-dependency-injection.md b/src/api/composition-api-dependency-injection.md index 32ecb19fbc..89df326578 100644 --- a/src/api/composition-api-dependency-injection.md +++ b/src/api/composition-api-dependency-injection.md @@ -107,10 +107,12 @@ Injects a value provided by an ancestor component or the application (via `app.p - [Guide - Provide / Inject](/guide/components/provide-inject) - [Guide - Typing Provide / Inject](/guide/typescript/composition-api#typing-provide-inject) -## hasInjectionContext() {#has-injection-context} +## hasInjectionContext() {#has-injection-context} Returns true if [inject()](#inject) can be used without warning about being called in the wrong place (e.g. outside of `setup()`). This method is designed to be used by libraries that want to use `inject()` internally without triggering a warning to the end user. +- Only supported in 3.3+ + - **Type** ```ts diff --git a/src/api/composition-api-helpers.md b/src/api/composition-api-helpers.md index acb9bb6cfc..d09391857d 100644 --- a/src/api/composition-api-helpers.md +++ b/src/api/composition-api-helpers.md @@ -22,11 +22,11 @@ If using TypeScript, [`defineSlots()`](/api/sfc-script-setup#defineslots) should function useSlots(): Record VNode[]> ``` -## useModel() {#usemodel} +## useModel() {#usemodel} This is the underlying helper that powers [`defineModel()`](/api/sfc-script-setup#definemodel). If using `