Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
47691ed
Update Introduction example to use `components` instead of `.componen…
LSViana Oct 26, 2021
210b792
SSR Guide: Remove app.js (#1297)
CyberAP Oct 26, 2021
965d330
Add an example on why singletones are bad (#1298)
CyberAP Oct 27, 2021
ae71533
Adding Components.studio and WebComponents.dev... (#1299)
georges-gomes Oct 29, 2021
7607848
Update debugging-in-vscode.md (#1270)
deepansh96 Oct 29, 2021
7a9ad06
Fixed possessive pronouns (#1303)
Oct 29, 2021
eef29e0
fixed missing commas (#1302)
Oct 29, 2021
d026fc2
Update introduction.md (#1306)
wxsms Oct 30, 2021
f4311ed
Update deprecated app.config.isCustomElement (#1307)
Miguel-Bento-Github Oct 31, 2021
5ddaf35
fix: use createSSRApp instead of createApp (#1311)
skirtles-code Nov 3, 2021
563ed27
docs: expand the explanation about using VNodes with <component> (#1310)
skirtles-code Nov 3, 2021
3d84cff
Fix typo (#1315)
dews Nov 5, 2021
0097065
chore: Update partners on myself (#1318)
rstoenescu Nov 7, 2021
4fae0d0
add vue school links to supplement component documentation with video…
danielkellyio Nov 10, 2021
3c97d52
Update description about .number modifier (#1285)
zxuqian Nov 10, 2021
45b9049
fix: Explain usage of custom directives with script-setup (#1319)
LinusBorg Nov 10, 2021
813c887
enclosed a word intended to clarify meaning of diff (#1304)
Nov 10, 2021
fc31792
A better example for v-html (#1314)
mehanalavimajd Nov 10, 2021
729d996
fix: bug in the rendering of the v-html example (#1326)
skirtles-code Nov 12, 2021
c90a0a2
Update application-api.md (#1327)
mehanalavimajd Nov 13, 2021
c9a4813
docs(en): merging all conflicts
docschina-bot Nov 14, 2021
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
11 changes: 5 additions & 6 deletions src/.vuepress/components/community/team/partners.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,14 @@ export default shuffle([
github: 'rstoenescu',
twitter: 'quasarframework',
work: {
role: 'Developer',
role: 'Author',
org: 'Quasar Framework',
orgUrl: 'http://quasar-framework.org/'
orgUrl: 'http://quasar.dev/'
},
reposPersonal: [
'quasarframework/quasar',
'quasarframework/quasar-cli',
'quasarframework/quasar-play'
]
'quasarframework/quasar'
],
links: ['https://quasar.dev']
},
{
name: 'Jilson Thomas',
Expand Down
3 changes: 2 additions & 1 deletion src/api/application-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ app.directive('my-directive', {
mounted() {},
// called before the containing component's VNode is updated
beforeUpdate() {},
// called after the containing component's VNode and the VNodes of its children // have updated
// called after the containing component's VNode and the VNodes of its
// children have updated
updated() {},
// called before the bound element's parent component is unmounted
beforeUnmount() {},
Expand Down
18 changes: 10 additions & 8 deletions src/api/built-in-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { KeepAlive, Teleport, Transition, TransitionGroup } from 'vue'

- **Props:**

- `is` - `string | Component`
- `is` - `string | Component | VNode`

- **Usage:**

Expand All @@ -41,6 +41,8 @@ import { KeepAlive, Teleport, Transition, TransitionGroup } from 'vue'
<component :is="href ? 'a' : 'span'"></component>
```

- **Usage with built-in components:**

The built-in components `KeepAlive`, `Transition`, `TransitionGroup`, and `Teleport` can all be passed to `is`, but you must register them if you want to pass them by name. For example:

```js
Expand All @@ -62,15 +64,15 @@ import { KeepAlive, Teleport, Transition, TransitionGroup } from 'vue'

Registration is not required if you pass the component itself to `is` rather than its name.

- **key:**
- **Usage with VNodes:**

When using <component :is="vnode"> and passing vnode of the same type, you need to provide keys:
```html
<component :is="current" :key="selected" />
```
In advanced use cases, it can sometimes be useful to render an existing VNode via a template. Using a `<component>` makes this possible, but it should be seen as an escape hatch, used to avoid rewriting the entire template as a `render` function.

```html
<component :is="vnode" :key="aSuitableKey" />
```

Otherwise, you are passing two compiled vnodes of the same type to the renderer. Because they are compiled as completely static, they will not be updated at all.
A caveat of mixing VNodes and templates in this way is that you need to provide a suitable `key` attribute. The VNode will be considered static, so any updates will be ignored unless the `key` changes. The `key` can be on the VNode or the `<component>` tag, but either way it must change every time you want the VNode to re-render. This caveat doesn't apply if the nodes have different types, e.g. changing a `span` to a `div`.

- **See also:** [Dynamic Components](../guide/component-dynamic-async.html)

Expand Down
2 changes: 1 addition & 1 deletion src/api/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
- **Example:**

```html
<div v-html="html"></div>
<div v-html="'<h1>Hello World</h1>'"></div>
```

- **See also:** [Data Binding Syntax - Interpolations](../guide/template-syntax.html#raw-html)
Expand Down
25 changes: 25 additions & 0 deletions src/api/sfc-script-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ import * as Form from './form-components'
</template>
```

## Using Custom Directives

Globally registered custom directives just work as expected, and local ones can be used directly in the template, much like we explained above for components.

But there's one restriction to be aware of: You must name local custom directives according to the following schema: `vNameOfDirective` in order for them to be directly usable in the template.

```html
<script setup>
const vMyDirective = {
beforeMount: (el) => {
// do something with the element
}
}
</script>
<template>
<h1 v-my-directive>This is a Heading</h1>
</template>
```
```html
<script setup>
// imports also work, and can be renamed to fit the required naming schema
import { myDirective as vMyDirective } from './MyDirective.js'
</script>
```

## `defineProps` and `defineEmits`

To declare `props` and `emits` in `<script setup>`, you must use the `defineProps` and `defineEmits` APIs, which provide full type inference support and are automatically available inside `<script setup>`:
Expand Down
2 changes: 2 additions & 0 deletions src/api/sfc-tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ You don't need to install anything on your machine to try out Vue SFCs - there a
- [Vue on Repl.it](https://replit.com/@templates/VueJS-with-Vite)
- [Vue on Codepen](https://codepen.io/pen/editor/vue)
- [Vue on StackBlitz](https://stackblitz.com/fork/vue)
- [Vue on Components.studio](https://components.studio/create/vue3)
- [Vue on WebComponents.dev](https://webcomponents.dev/create/cevue)

It is also recommended to use these online playgrounds to provide reproductions when reporting bugs.

Expand Down
2 changes: 1 addition & 1 deletion src/api/special-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

- **Expects:** `number | string | symbol`

The `key` special attribute is primarily used as a hint for Vue's virtual DOM algorithm to identify VNodes when diffing the new list of nodes against the old list. Without keys, Vue uses an algorithm that minimizes element movement and tries to patch/reuse elements of the same type in-place as much as possible. With keys, it will reorder elements based on the order change of keys, and elements with keys that are no longer present will always be removed/destroyed.
The `key` special attribute is primarily used as a hint for Vue's virtual DOM algorithm to identify VNodes when comparing the new list of nodes against the old list. Without keys, Vue uses an algorithm that minimizes element movement and tries to patch/reuse elements of the same type in-place as much as possible. With keys, it will reorder elements based on the order change of keys, and elements with keys that are no longer present will always be removed/destroyed.

Children of the same common parent must have **unique keys**. Duplicate keys will cause render errors.

Expand Down
5 changes: 1 addition & 4 deletions src/cookbook/debugging-in-vscode.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ This recipe shows how to debug [Vue CLI](https://github.com/vuejs/vue-cli) appli

## Prerequisites

Make sure you have VS Code and the browser of your choice installed, and the latest version of the corresponding Debugger extension installed and enabled:

- [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome)
- [Debugger for Firefox](https://marketplace.visualstudio.com/items?itemName=hbenl.vscode-firefox-debug)
Make sure you have VS Code and the browser of your choice installed.

Install and create a project with the [vue-cli](https://github.com/vuejs/vue-cli), following the instructions in the [Vue CLI Guide](https://cli.vuejs.org/). Change into the newly created application directory and open VS Code.

Expand Down
2 changes: 2 additions & 0 deletions src/guide/component-basics.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Components Basics

<VideoLesson href="https://vueschool.io/courses/vue-js-3-components-fundamentals?friend=vuejs" title="Free Vue.js Components Fundamentals Course">Learn component basics with a free video course on Vue School</VideoLesson>

## Base Example

Here's an example of a Vue component:
Expand Down
2 changes: 2 additions & 0 deletions src/guide/component-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

> This page assumes you've already read the [Components Basics](component-basics.md). Read that first if you are new to components.

<VideoLesson href="https://vueschool.io/lessons/vue-3-reusable-components-with-props?friend=vuejs" title="Free Vue.js Component Props Lesson">Learn how component props work with a free lesson on Vue School</VideoLesson>

## Prop Types

So far, we've only seen props listed as an array of strings:
Expand Down
2 changes: 2 additions & 0 deletions src/guide/component-registration.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Component Registration

<VideoLesson href="https://vueschool.io/lessons/vue-3-global-vs-local-vue-components?friend=vuejs" title="Free Vue.js Component Registration lesson">Learn how component registration works with a free lesson on Vue School</VideoLesson>

> This page assumes you've already read the [Components Basics](component-basics.md). Read that first if you are new to components.

## Component Names
Expand Down
2 changes: 2 additions & 0 deletions src/guide/component-slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

> This page assumes you've already read the [Components Basics](component-basics.md). Read that first if you are new to components.

<VideoLesson href="https://vueschool.io/lessons/vue-3-component-slots?friend=vuejs" title="Free Vue.js Slots lesson">Learn slot basics with a free lesson on Vue School</VideoLesson>

## Slot Content

Vue implements a content distribution API inspired by the [Web Components spec draft](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md), using the `<slot>` element to serve as distribution outlets for content.
Expand Down
4 changes: 2 additions & 2 deletions src/guide/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,10 @@ By default, `v-model` syncs the input with the data after each `input` event (wi
If you want user input to be automatically typecast as a number, you can add the `number` modifier to your `v-model` managed inputs:

```html
<input v-model.number="age" type="number" />
<input v-model.number="age" type="text" />
```

This is often useful, because even with `type="number"`, the value of HTML input elements always returns a string. If the value cannot be parsed with `parseFloat()`, then the original value is returned.
This is often useful when the input type is `text`. If the input type is `number`, Vue can automatically convert the raw string value to a number, and you don't need to add the `.number` modifier to `v-model`. If the value cannot be parsed with `parseFloat()`, then the original value is returned.

### `.trim`

Expand Down
20 changes: 20 additions & 0 deletions src/guide/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,19 @@ Vue.createApp(AttributeBinding).mount('#bind-attribute')

<common-codepen-snippet title="Attribute dynamic binding" slug="KKpRVvJ" />

<<<<<<< HEAD
这里我们遇到了一点新东西。你看到的 `v-bind` attribute 被称为**指令**。指令带有前缀 `v-`,以表示它们是 Vue 提供的特殊 attribute。可能你已经猜到了,它们会在渲染的 DOM 上应用特殊的响应式行为。在这里,该指令的意思是:“_将这个元素节点的 `title` attribute 和当前活跃实例的 `message` property 保持一致_”。
=======
Here we're encountering something new. The `v-bind` attribute you're seeing is called a **directive**. Directives are prefixed with `v-` to indicate that they are special attributes provided by Vue, and as you may have guessed, they apply special reactive behavior to the rendered DOM. Here, we're basically saying "_keep this element's `title` attribute up-to-date with the `message` property on the current active instance._"
>>>>>>> c90a0a2c20c08b726043764198dc246fcaea854b

## 处理用户输入 {#handling-user-input}

<<<<<<< HEAD
为了让用户和应用进行交互,我们可以用 `v-on` 指令添加一个事件监听器,通过它调用在实例中定义的方法:
=======
To let users interact with our app, we can use the `v-on` directive to attach event listeners that invoke methods on our instances:
>>>>>>> c90a0a2c20c08b726043764198dc246fcaea854b

```html
<div id="event-handling">
Expand Down Expand Up @@ -222,12 +230,24 @@ Vue.createApp(ListRendering).mount('#list-rendering')
在 Vue 中,组件本质上是一个具有预定义选项的实例。在 Vue 中注册组件很简单:如对 `App` 对象所做的那样创建一个组件对象,并将其定义在父级组件的 `components` 选项中:

```js
<<<<<<< HEAD
// 创建 Vue 应用
const app = Vue.createApp(...)

// 定义名为 todo-item 的新组件
app.component('todo-item', {
=======
const TodoItem = {
>>>>>>> c90a0a2c20c08b726043764198dc246fcaea854b
template: `<li>This is a todo</li>`
}

// Create Vue application
const app = Vue.createApp({
components: {
TodoItem // Register a new component
},
... // Other properties for the component
})

// 挂载 Vue 应用
Expand Down
6 changes: 3 additions & 3 deletions src/guide/migration/custom-elements-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ Vue.config.ignoredElements = ['plastic-button']
]
```

- If using on-the-fly template compilation, pass it via `app.config.isCustomElement`:
- If using on-the-fly template compilation, pass it via `app.config.compilerOptions.isCustomElement`:

```js
const app = Vue.createApp({})
app.config.isCustomElement = tag => tag === 'plastic-button'
app.config.compilerOptions.isCustomElement = tag => tag === 'plastic-button'
```

It's important to note the runtime config only affects runtime template compilation - it won't affect pre-compiled templates.
Expand Down Expand Up @@ -125,6 +125,6 @@ With the behavior change of `is`, a `vue:` prefix is now required to resolve the

## Migration Strategy

- Replace `config.ignoredElements` with either `vue-loader`'s `compilerOptions` (with the build step) or `app.config.isCustomElement` (with on-the-fly template compilation)
- Replace `config.ignoredElements` with either `vue-loader`'s `compilerOptions` (with the build step) or `app.config.compilerOptions.isCustomElement` (with on-the-fly template compilation)

- Change all non-`<component>` tags with `is` usage to `<component is="...">` (for SFC templates) or prefix it with `vue:` (for in-DOM templates).
2 changes: 2 additions & 0 deletions src/guide/single-file-component.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Single File Components

<VideoLesson href="https://vueschool.io/lessons/vue-3-introduction-to-single-file-components?friend=vuejs" title="Free Vue.js Single File Components Lesson">Learn about single file components with a free video lesson on Vue School</VideoLesson>

## Introduction

Vue Single File Components (aka `*.vue` files, abbreviated as **SFC**) is a special file format that allows us to encapsulate the template, logic, **and** styling of a Vue component in a single file. Here's an example SFC:
Expand Down
2 changes: 1 addition & 1 deletion src/guide/ssr/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you're using [webpack](https://webpack.js.org/), you can add prerendering wit

This guide will be very in-depth and assumes you are already familiar with Vue.js itself, and have a decent working knowledge of Node.js and webpack.

[//]: # 'If you prefer a higher-level solution that provides a smooth out-of-the-box experience, you should probably give [Nuxt.js](https://nuxtjs.org/) a try. It's built upon the same Vue stack but abstracts away a lot of the boilerplate, and provides some extra features such as static site generation. However, it may not suit your use case if you need more direct control of your app's structure. Regardless, it would still be beneficial to read through this guide to understand better how things work together.'
If you prefer a higher-level solution that provides a smooth out-of-the-box experience, you should probably give [Nuxt.js](https://nuxtjs.org/) a try. It's built upon the same Vue stack but abstracts away a lot of the boilerplate, and provides some extra features such as static site generation. However, it may not suit your use case if you need more direct control of your app's structure. Regardless, it would still be beneficial to read through this guide to understand better how things work together.

[//]: # 'TODO: As you read along, it would be helpful to refer to the official [HackerNews Demo](https://github.com/vuejs/vue-hackernews-2.0/), which makes use of most of the techniques covered in this guide'

Expand Down
69 changes: 38 additions & 31 deletions src/guide/ssr/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,50 @@ It is recommended to use the official [vue-router](https://github.com/vuejs/vue-

```js
// router.js
import { createRouter, createMemoryHistory, createWebHistory } from 'vue-router'
import { createRouter } from 'vue-router'
import MyUser from './components/MyUser.vue'

const isServer = typeof window === 'undefined'

const createHistory = isServer ? createMemoryHistory : createWebHistory

const routes = [{ path: '/user', component: MyUser }]

export default function() {
export default function (history) {
return createRouter({
history: createHistory(),
history,
routes
})
}
```

And update our `app.js`, client and server entries:
And update our client and server entries:

```js
// app.js
// entry-client.js
import { createSSRApp } from 'vue'
import { createWebHistory } from 'vue-router'
import createRouter from './router.js'
import App from './App.vue'
import createRouter from './router'

export default function(args) {
// ...

const app = createSSRApp(App)

const router = createRouter(createWebHistory())

app.use(router)

// ...
```

```js
// entry-server.js
import { createSSRApp } from 'vue'
// server router uses a different history from the client one
import { createMemoryHistory } from 'vue-router'
import createRouter from './router.js'
import App from './App.vue'

export default function () {
const app = createSSRApp(App)
const router = createRouter()
const router = createRouter(createMemoryHistory())

app.use(router)

Expand All @@ -46,20 +62,6 @@ export default function(args) {
}
```

```js
// entry-client.js
const { app, router } = createApp({
/*...*/
})
```

```js
// entry-server.js
const { app, router } = createApp({
/*...*/
})
```

## Code-Splitting

Code-splitting, or lazy-loading part of your app, helps reduce the size of assets that need to be downloaded by the browser for the initial render, and can greatly improve TTI (time-to-interactive) for apps with large bundles. The key is "loading just what is needed" for the initial screen.
Expand All @@ -77,15 +79,20 @@ const routes = [
]
```

On both client and server we need to wait for router to resolve async route components ahead of time in order to properly invoke in-component hooks. For this we will be using [router.isReady](https://next.router.vuejs.org/api/#isready) method Let's update our client entry:
On both client and server we need to wait for the router to resolve async route components ahead of time in order to properly invoke in-component hooks. For this we will be using the [router.isReady](https://next.router.vuejs.org/api/#isready) method. Let's update our client entry:

```js
// entry-client.js
import createApp from './app'
import { createSSRApp } from 'vue'
import { createWebHistory } from 'vue-router'
import createRouter from './router.js'
import App from './App.vue'

const { app, router } = createApp({
/* ... */
})
const app = createSSRApp(App)

const router = createRouter(createWebHistory())

app.use(router)

router.isReady().then(() => {
app.mount('#app')
Expand Down
Loading