Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/composition-api-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The `setup()` hook serves as the entry point for Composition API usage in compon
1. Using Composition API without a build step;
2. Integrating with Composition-API-based code in an Options API component.

:::info Note
:::info
If you are using Composition API with Single-File Components, [`<script setup>`](/api/sfc-script-setup) is strongly recommended for a more succinct and ergonomic syntax.
:::

Expand Down
3 changes: 2 additions & 1 deletion src/api/options-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ Declare computed properties to be exposed on the component instance.

type ComputedGetter<T> = (
this: ComponentPublicInstance,
vm: ComponentPublicInstance
vm: ComponentPublicInstance,
previous: T
) => T

type ComputedSetter<T> = (
Expand Down
2 changes: 1 addition & 1 deletion src/api/sfc-script-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ const post = await fetch(`/api/post/1`).then((r) => r.json())

In addition, the awaited expression will be automatically compiled in a format that preserves the current component instance context after the `await`.

:::warning Note
:::warning
`async setup()` must be used in combination with [`Suspense`](/guide/built-ins/suspense.html), which is currently still an experimental feature. We plan to finalize and document it in a future release - but if you are curious now, you can refer to its [tests](https://github.com/vuejs/core/blob/main/packages/runtime-core/__tests__/components/Suspense.spec.ts) to see how it works.
:::

Expand Down
4 changes: 2 additions & 2 deletions src/guide/components/provide-inject.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

Usually, when we need to pass data from the parent to a child component, we use [props](/guide/components/props). However, imagine the case where we have a large component tree, and a deeply nested component needs something from a distant ancestor component. With only props, we would have to pass the same prop across the entire parent chain:

![prop drilling diagram](./images/prop-drilling.png)
![Diagram showing props being passed through multiple levels of components just to reach a deeply nested child](./images/prop-drilling.png)

<!-- https://www.figma.com/file/yNDTtReM2xVgjcGVRzChss/prop-drilling -->

Notice although the `<Footer>` component may not care about these props at all, it still needs to declare and pass them along just so `<DeepChild>` can access them. If there is a longer parent chain, more components would be affected along the way. This is called "props drilling" and definitely isn't fun to deal with.

We can solve props drilling with `provide` and `inject`. A parent component can serve as a **dependency provider** for all its descendants. Any component in the descendant tree, regardless of how deep it is, can **inject** dependencies provided by components up in its parent chain.

![Provide/inject scheme](./images/provide-inject.png)
![Diagram showing the provide/inject mechanism where a parent component provides a dependency that can be directly injected by a deeply nested child, bypassing intermediate components](./images/provide-inject.png)

<!-- https://www.figma.com/file/PbTJ9oXis5KUawEOWdy2cE/provide-inject -->

Expand Down
6 changes: 3 additions & 3 deletions src/guide/components/slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The template of `<FancyButton>` looks like this:

The `<slot>` element is a **slot outlet** that indicates where the parent-provided **slot content** should be rendered.

![slot diagram](./images/slots.png)
![Diagram showing slot content from the parent being injected into the slot outlet in the child component](./images/slots.png)

<!-- https://www.figma.com/file/LjKTYVL97Ck6TEmBbstavX/slot -->

Expand Down Expand Up @@ -207,7 +207,7 @@ To pass a named slot, we need to use a `<template>` element with the `v-slot` di

`v-slot` has a dedicated shorthand `#`, so `<template v-slot:header>` can be shortened to just `<template #header>`. Think of it as "render this template fragment in the child component's 'header' slot".

![named slots diagram](./images/named-slots.png)
![Diagram showing multiple named slots in a layout component, with content from the parent being directed to the corresponding header, main, and footer slots](./images/named-slots.png)

<!-- https://www.figma.com/file/2BhP8gVZevttBu9oUmUUyz/named-slot -->

Expand Down Expand Up @@ -367,7 +367,7 @@ Receiving the slot props is a bit different when using a single default slot vs.
</MyComponent>
```

![scoped slots diagram](./images/scoped-slots.svg)
![Diagram showing a scoped slot where the child component passes data back to the parent-provided slot content](./images/scoped-slots.svg)

<!-- https://www.figma.com/file/QRneoj8eIdL1kw3WQaaEyc/scoped-slot -->

Expand Down
2 changes: 1 addition & 1 deletion src/guide/components/v-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Then, `v-model="foo"` in the parent component will be compiled to:
/>
```

As you can see, it is quite a bit more verbose. However, it is helpful to understand what is happening under the hood.
As you can see, it is quite a bit more verbose. However, it is helpful to understand what is happening internally.

Because `defineModel` declares a prop, you can therefore declare the underlying prop's options by passing it to `defineModel`:

Expand Down
2 changes: 1 addition & 1 deletion src/guide/essentials/component-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Components allow us to split the UI into independent and reusable pieces, and think about each piece in isolation. It's common for an app to be organized into a tree of nested components:

![Component Tree](./images/components.png)
![Diagram showing a component tree structure with a root component branching into multiple child and nested sub-child components](./images/components.png)

<!-- https://www.figma.com/file/qa7WHDQRWuEZNRs7iZRZSI/components -->

Expand Down
4 changes: 2 additions & 2 deletions src/guide/essentials/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ In addition, `v-model` can be used on inputs of different types, `<textarea>`, a
- `<input type="checkbox">` and `<input type="radio">` use `checked` property and `change` event;
- `<select>` uses `value` as a prop and `change` as an event.

::: tip Note
:::tip
`v-model` will ignore the initial `value`, `checked` or `selected` attributes found on any form elements. It will always treat the current bound JavaScript state as the source of truth. You should declare the initial value on the JavaScript side, using <span class="options-api">the [`data`](/api/options-state.html#data) option</span><span class="composition-api">[reactivity APIs](/api/reactivity-core.html#reactivity-api-core)</span>.
:::

Expand Down Expand Up @@ -274,7 +274,7 @@ Single select:

</div>

:::tip Note
:::tip
If the initial value of your `v-model` expression does not match any of the options, the `<select>` element will render in an "unselected" state. On iOS this will cause the user not being able to select the first item because iOS does not fire a change event in this case. It is therefore recommended to provide a disabled option with an empty value, as demonstrated in the example above.
:::

Expand Down
2 changes: 1 addition & 1 deletion src/guide/essentials/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Do note this doesn't mean that the call must be placed lexically inside `setup()

Below is a diagram for the instance lifecycle. You don't need to fully understand everything going on right now, but as you learn and build more, it will be a useful reference.

![Component lifecycle diagram](./images/lifecycle.png)
![Diagram showing the full lifecycle of a Vue component, from creation to destruction, including all major lifecycle hooks and the internal processes like template compilation and mounting](./images/lifecycle.png)

<!-- https://www.figma.com/file/Xw3UeNMOralY6NV7gSjWdS/Vue-Lifecycle -->

Expand Down
4 changes: 2 additions & 2 deletions src/guide/essentials/list.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ This can be fixed by moving `v-for` to a wrapping `<template>` tag (which is als
</template>
```

:::warning Note
:::warning
It's **not** recommended to use `v-if` and `v-for` on the same element due to implicit precedence.

There are two common cases where this can be tempting:
Expand Down Expand Up @@ -277,7 +277,7 @@ When using `<template v-for>`, the `key` should be placed on the `<template>` co
</template>
```

:::tip Note
:::tip
`key` here is a special attribute being bound with `v-bind`. It should not be confused with the property key variable when [using `v-for` with an object](#v-for-with-an-object).
:::

Expand Down
5 changes: 3 additions & 2 deletions src/guide/essentials/template-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ data() {
return {
objectOfAttrs: {
id: 'container',
class: 'wrapper'
class: 'wrapper',
style: 'background-color:green'
}
}
}
Expand Down Expand Up @@ -286,6 +287,6 @@ You'll see other examples of modifiers later, [for `v-on`](./event-handling#even

And finally, here's the full directive syntax visualized:

![directive syntax graph](./images/directive.png)
![Diagram visualizing the full directive syntax, including directive name, argument, modifiers, and value](./images/directive.png)

<!-- https://www.figma.com/file/BGWUknIrtY9HOmbmad0vFr/Directive -->
32 changes: 27 additions & 5 deletions src/guide/extras/reactivity-in-depth.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SpreadSheet from './demos/SpreadSheet.vue'

# Reactivity in Depth {#reactivity-in-depth}

One of Vue’s most distinctive features is the unobtrusive reactivity system. Component state consists of reactive JavaScript objects. When you modify them, the view updates. It makes state management simple and intuitive, but it’s also important to understand how it works to avoid some common gotchas. In this section, we are going to dig into some of the lower-level details of Vue’s reactivity system.
One of Vue’s most distinctive features is the unobtrusive reactivity system. Component state consists of reactive JavaScript objects. When you modify them, the view updates. It makes state management simple and intuitive, but it’s also important to understand how it works to avoid some common pitfalls. In this section, we are going to dig into some of the lower-level details of Vue’s reactivity system.

## What is Reactivity? {#what-is-reactivity}

Expand Down Expand Up @@ -202,7 +202,7 @@ In fact, this is pretty close to how a Vue component keeps the state and the DOM

<div class="options-api">

The `ref()`, `computed()` and `watchEffect()` APIs are all part of the Composition API. If you have only been using Options API with Vue so far, you'll notice that Composition API is closer to how Vue's reactivity system works under the hood. In fact, in Vue 3 the Options API is implemented on top of the Composition API. All property access on the component instance (`this`) triggers getter / setters for reactivity tracking, and options like `watch` and `computed` invoke their Composition API equivalents internally.
The `ref()`, `computed()` and `watchEffect()` APIs are all part of the Composition API. If you have only been using Options API with Vue so far, you'll notice that Composition API is closer to how Vue's reactivity system works internally. In fact, in Vue 3 the Options API is implemented on top of the Composition API. All property access on the component instance (`this`) triggers getter / setters for reactivity tracking, and options like `watch` and `computed` invoke their Composition API equivalents internally.

</div>

Expand Down Expand Up @@ -278,7 +278,9 @@ type DebuggerEvent = {

### Computed Debugging {#computed-debugging}

<!-- TODO options API equivalent -->
<div class="options-api">
Computed debugging options are only available when using the Composition API.
</div>

We can debug computed properties by passing `computed()` a second options object with `onTrack` and `onTrigger` callbacks:

Expand Down Expand Up @@ -312,10 +314,30 @@ count.value++

### Watcher Debugging {#watcher-debugging}

<!-- TODO options API equivalent -->

Similar to `computed()`, watchers also support the `onTrack` and `onTrigger` options:

<div class="options-api">

```js
export default {
watch: {
source: {
handler(val) {
// ...
},
onTrack(e) {
debugger
},
onTrigger(e) {
debugger
}
}
}
}
```

</div>

```js
watch(source, callback, {
onTrack(e) {
Expand Down
2 changes: 1 addition & 1 deletion src/guide/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { VTCodeGroup, VTCodeGroupTab } from '@vue/theme'

## Try Vue Online {#try-vue-online}

- To quickly get a taste of Vue, you can try it directly in our [Playground](https://play.vuejs.org/#eNo9jcEKwjAMhl/lt5fpQYfXUQfefAMvvRQbddC1pUuHUPrudg4HIcmXjyRZXEM4zYlEJ+T0iEPgXjn6BB8Zhp46WUZWDjCa9f6w9kAkTtH9CRinV4fmRtZ63H20Ztesqiylphqy3R5UYBqD1UyVAPk+9zkvV1CKbCv9poMLiTEfR2/IXpSoXomqZLtti/IFwVtA9A==).
- To quickly explore Vue, you can try it directly in our [Playground](https://play.vuejs.org/#eNo9jcEKwjAMhl/lt5fpQYfXUQfefAMvvRQbddC1pUuHUPrudg4HIcmXjyRZXEM4zYlEJ+T0iEPgXjn6BB8Zhp46WUZWDjCa9f6w9kAkTtH9CRinV4fmRtZ63H20Ztesqiylphqy3R5UYBqD1UyVAPk+9zkvV1CKbCv9poMLiTEfR2/IXpSoXomqZLtti/IFwVtA9A==).

- If you prefer a plain HTML setup without any build steps, you can use this [JSFiddle](https://jsfiddle.net/yyx990803/2ke1ab0z/) as your starting point.

Expand Down
2 changes: 1 addition & 1 deletion src/guide/reusability/custom-directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ Similar to built-in directives, custom directive arguments can be dynamic. For e

Here the directive argument will be reactively updated based on `arg` property in our component state.

:::tip Note
:::tip
Apart from `el`, you should treat these arguments as read-only and never modify them. If you need to share information across hooks, it is recommended to do so through element's [dataset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset).
:::

Expand Down
1 change: 0 additions & 1 deletion src/guide/scaling-up/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ In such SPAs, the "routing" is done on the client side, in the browser. A client

## Official Router {#official-router}

<!-- TODO update links -->
<div>
<VueSchoolLink href="https://vueschool.io/courses/vue-router-4-for-everyone" title="Free Vue Router Course">
Watch a Free Video Course on Vue School
Expand Down
11 changes: 10 additions & 1 deletion src/guide/scaling-up/tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,13 @@ The official loader that provides Vue SFC support in webpack. If you are using V
- [Vue on Codepen](https://codepen.io/pen/editor/vue)
- [Vue on WebComponents.dev](https://webcomponents.dev/create/cevue)

<!-- TODO ## Backend Framework Integrations -->
## Backend Framework Integrations {#backend-framework-integrations}

If you are using Vue with a backend framework (e.g. Laravel, Rails, Django, or Go), Vite provides several integrations for popular backend frameworks to help you manage your assets efficiently.

- **Laravel**: Official [Laravel Vite integration](https://laravel.com/docs/vite).
- **Rails**: [Vite Ruby](https://vite-ruby.netlify.app/).
- **Django**: [django-vite](https://github.com/MrBin99/django-vite).
- **Go**: [vite-go](https://github.com/hvuhsg/vite-go).

Alternatively, you can manually configure Vite to work with your backend by following the [Vite Backend Integration Guide](https://vite.dev/guide/backend-integration.html).