diff --git a/src/recommendations.md b/src/recommendations.md index 0cdb788..44653f4 100644 --- a/src/recommendations.md +++ b/src/recommendations.md @@ -31,7 +31,7 @@ Also see [Tooling chapter in new docs](https://vuejs.org/guide/scaling-up/toolin ### Vue Router -Vue Router 4.0 provides Vue 3 support and has a number of breaking changes of its own. Check out its [migration guide](https://router.vuejs.org/) for full details. +Vue Router 4.0 provides Vue 3 support and has a number of breaking changes of its own. Check out its [migration guide](https://router.vuejs.org/guide/migration/index.html) for full details. - [Documentation](https://router.vuejs.org/) - [GitHub](https://github.com/vuejs/router) diff --git a/src/zh/breaking-changes/array-refs.md b/src/zh/breaking-changes/array-refs.md deleted file mode 100644 index 34706b3..0000000 --- a/src/zh/breaking-changes/array-refs.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: v-for 中的 Ref 数组 -badges: - - breaking ---- - -# {{ $frontmatter.title }} - -在 Vue 2 中,在 `v-for` 中使用的 `ref` attribute 会用 ref 数组填充相应的 `$refs` property。当存在嵌套的 `v-for` 时,这种行为会变得不明确且效率低下。 - -在 Vue 3 中,此类用法将不再自动创建 `$ref` 数组。要从单个绑定获取多个 ref,请将 `ref` 绑定到一个更灵活的函数上 (这是一个新特性): - -```html -
-``` - -结合选项式 API: - -```js -export default { - data() { - return { - itemRefs: [] - } - }, - methods: { - setItemRef(el) { - if (el) { - this.itemRefs.push(el) - } - } - }, - beforeUpdate() { - this.itemRefs = [] - }, - updated() { - console.log(this.itemRefs) - } -} -``` - -结合组合式 API: - -```js -import { onBeforeUpdate, onUpdated } from 'vue' - -export default { - setup() { - let itemRefs = [] - const setItemRef = el => { - if (el) { - itemRefs.push(el) - } - } - onBeforeUpdate(() => { - itemRefs = [] - }) - onUpdated(() => { - console.log(itemRefs) - }) - return { - setItemRef - } - } -} -``` - -注意: - -- `itemRefs` 不必是数组:它也可以是一个对象,其 ref 可以通过迭代的 key 被设置。 - -- 如有需要,`itemRefs` 也可以是响应式的,且可以被侦听。 - -## 迁移策略 - -[迁移构建开关:](../migration-build.html#兼容性配置) - -- `V_FOR_REF` -- `COMPILER_V_FOR_REF` diff --git a/src/zh/breaking-changes/children.md b/src/zh/breaking-changes/children.md index 34aa46a..7ef9c4b 100644 --- a/src/zh/breaking-changes/children.md +++ b/src/zh/breaking-changes/children.md @@ -37,7 +37,7 @@ export default { ## 3.x 更新 -在 3.x 中,`$children` property 已被移除,且不再支持。如果你需要访问子组件实例,我们建议使用 [模板引用](https://cn.vuejs.org/guide/essentials/template-refs.html#template-refs)。 +在 3.x 中,`$children` property 已被移除,且不再支持。如果你需要访问子组件实例,我们建议使用[模板引用](https://cn.vuejs.org/guide/essentials/template-refs.html#template-refs)。 ## 迁移策略 diff --git a/src/zh/breaking-changes/events-api.md b/src/zh/breaking-changes/events-api.md index 5f1cf39..6540ab9 100644 --- a/src/zh/breaking-changes/events-api.md +++ b/src/zh/breaking-changes/events-api.md @@ -97,7 +97,7 @@ export default { 在绝大多数情况下,不鼓励使用全局的事件总线在组件之间进行通信。虽然在短期内往往是最简单的解决方案,但从长期来看,它维护起来总是令人头疼。根据具体情况来看,有多种事件总线的替代方案: -* Props 和 事件 应该是父子组件之间沟通的首选。兄弟节点可以通过它们的父节点通信。 +* Props 和事件应该是父子组件之间沟通的首选。兄弟节点可以通过它们的父节点通信。 * `provide` / `inject` 允许一个组件与它的插槽内容进行通信。这对于总是一起使用的紧密耦合的组件非常有用。 * `provide` / `inject` 也能够用于组件之间的远距离通信。它可以帮助避免“prop 逐级透传”,即 prop 需要通过许多层级的组件传递下去,但这些组件本身可能并不需要那些 prop。 * Prop 逐级透传也可以通过重构以使用插槽来避免。如果一个中间组件不需要某些 prop,那么表明它可能存在关注点分离的问题。在该类组件中使用 slot 可以允许父节点直接为它创建内容,因此 prop 可以被直接传递而不需要中间组件的参与。 diff --git a/src/zh/breaking-changes/global-api-treeshaking.md b/src/zh/breaking-changes/global-api-treeshaking.md index f57d4cc..84a38da 100644 --- a/src/zh/breaking-changes/global-api-treeshaking.md +++ b/src/zh/breaking-changes/global-api-treeshaking.md @@ -17,7 +17,7 @@ Vue.nextTick(() => { }) ``` -或者,如果你曾经对涉及[异步组件](https://v2.cn.vuejs.org/v2/guide/components-dynamic-async.html)的应用进行单元测试,那么你很可能编写过以下内容: +或者,如果你曾经对涉及异步组件的应用进行单元测试,那么你很可能编写过以下内容: ```js import { shallowMount } from '@vue/test-utils' @@ -38,7 +38,7 @@ test('an async feature', async () => { 但是,如果你从来都没有过手动操作 DOM 的必要,也没有在你的应用中使用或测试过异步组件,那该怎么办?或者,不管出于什么原因,你更喜欢使用老式的 `window.setTimeout()` 来代替它?在这种情况下,`nextTick()` 的代码就会变成死代码——也就是说,代码写了,但从未使用过。而死代码很难成为一个好的东西,尤其是在我们的客户端上下文中,每一个字节都很重要。 -如 [webpack](https://webpack.js.org/) 这样的模块打包工具支持 [tree-shaking](https://webpack.js.org/guides/tree-shaking/),这是表达“消除死代码”的一个花哨术语。遗憾的是,由于之前的 Vue 版本中的代码编写方式,如 `Vue.nextTick()` 这样的全局 API 是不支持 tree-shake 的,不管它们实际上是否被使用了,都会被包含在最终的打包产物中。 +如 webpack 和 Rollup (Vite 基于它) 这样的模块打包工具支持 [tree-shaking](https://webpack.js.org/guides/tree-shaking/),这是表达“消除死代码”的一个花哨术语。遗憾的是,由于之前的 Vue 版本中的代码编写方式,如 `Vue.nextTick()` 这样的全局 API 是不支持 tree-shake 的,不管它们实际上是否被使用了,都会被包含在最终的打包产物中。 ## 3.x 语法 diff --git a/src/zh/breaking-changes/global-api.md b/src/zh/breaking-changes/global-api.md index d904c8f..701ceb0 100644 --- a/src/zh/breaking-changes/global-api.md +++ b/src/zh/breaking-changes/global-api.md @@ -3,7 +3,7 @@ badges: - breaking --- -# 全局 API +# 全局 API 应用实例 Vue 2.x 有许多全局 API 和配置,它们可以全局改变 Vue 的行为。例如,要注册全局组件,可以使用 `Vue.component` API,就像这样: @@ -20,7 +20,7 @@ Vue.component('button-counter', { ```js Vue.directive('focus', { - inserted: el => el.focus() + inserted: (el) => el.focus() }) ``` @@ -65,7 +65,7 @@ import { createApp } from 'vue' const app = createApp({}) ``` -如果你使用的是 Vue 的 [CDN](./introduction.html#cdn) 构建版本,那么 `createApp` 将通过全局的 `Vue` 对象暴露。 +如果你使用的是 Vue 的 CDN 构建版本,那么 `createApp` 将通过全局的 `Vue` 对象暴露。 ```js const { createApp } = Vue @@ -107,7 +107,7 @@ Vue.config.ignoredElements = ['my-el', /^ion-/] // 之后 const app = createApp({}) -app.config.compilerOptions.isCustomElement = tag => tag.startsWith('ion-') +app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('ion-') ``` :::tip 重要 @@ -234,7 +234,7 @@ app.component('button-counter', { }) app.directive('focus', { - mounted: el => el.focus() + mounted: (el) => el.focus() }) // 现在,所有通过 app.mount() 挂载的应用实例及其组件树, @@ -275,7 +275,7 @@ import { createApp } from 'vue' import Foo from './Foo.vue' import Bar from './Bar.vue' -const createMyApp = options => { +const createMyApp = (options) => { const app = createApp(options) app.directive('focus' /* ... */) diff --git a/src/zh/breaking-changes/introduction.md b/src/zh/breaking-changes/introduction.md deleted file mode 100644 index 596a788..0000000 --- a/src/zh/breaking-changes/introduction.md +++ /dev/null @@ -1,225 +0,0 @@ -# 介绍 - -::: info 提示 -刚接触 Vue.js?先从[基础指南](http://cn.vuejs.org/guide/introduction.html)开始吧。 -::: - -本指南主要是为有 Vue 2 经验的、希望了解 Vue 3 的新功能和更改的用户而提供的。**在试用 Vue 3 之前,你不必完整阅读这些内容**。虽然看起来有很多变化,但很多你已经了解和喜欢 Vue 的部分仍是一样的。不过我们希望尽可能全面,并为每处变化提供详细的例子。 - -- [快速开始](#快速开始) -- [用于迁移的构建版本](#用于迁移的构建版本) -- [值得注意的新特性](#值得注意的新特性) -- [非兼容的变更](#非兼容的变更) -- [官方的支持库](#官方的支持库) - -## 概览 - -
- - -## 快速开始 - -如果你想要在一个新项目里快速尝试 Vue 3: - -- 通过 CDN:`` -- [Codepen](https://codepen.io/yyx990803/pen/OJNoaZL) 上的浏览器内试验田 -- [CodeSandbox](https://vue.new/) 上的浏览器内沙盒 -- 通过脚手架 [Vite](https://github.com/vitejs/vite): - - ```bash - npm init vite hello-vue3 -- --template vue # 或 yarn create vite hello-vue3 --template vue - ``` - -- 通过脚手架 [vue-cli](https://cli.vuejs.org/): - - ```bash - npm install -g @vue/cli # 或 yarn global add @vue/cli - vue create hello-vue3 - # 选择 vue 3 preset - ``` - -## 用于迁移的构建版本 - -如果你打算要将一个基于 Vue 2 的项目或者库升级到 Vue 3,我们提供了一个与 Vue 2 API 兼容的 Vue 3 构建版本,详情见[用于迁移的构建版本](../migration-build.html)。 - -## 值得注意的新特性 - -Vue 3 中一些需要关注的新功能包括: - -- [组合式 API](https://cn.vuejs.org/guide/composition-api-introduction.html) -- [Teleport](https://cn.vuejs.org/guide/teleport.html) -- [片段](../new/fragments.html) -- [Emits 组件选项](https://cn.vuejs.org/guide/component-custom-events.html) -- [来自 `@vue/runtime-core` 的 `createRenderer` API](https://github.com/vuejs/vue-next/tree/master/packages/runtime-core),用于创建自定义渲染器 -- [单文件组件组合式 API 语法糖 (` -``` - -`` 组件有两个插槽。它们都只接收一个直接子节点。`default` 插槽里的节点会尽可能展示出来。如果不能,则展示 `fallback` 插槽里的节点。 - -重要的是,异步组件不需要作为 `` 的直接子节点。它可以出现在组件树任意深度的位置,且不需要出现在和 `` 自身相同的模板中。只有所有的后代组件都准备就绪,该内容才会被认为解析完毕。 - -另一个触发 `fallback` 的方式是让后代组件从 `setup` 函数中返回一个 Promise。通常这是通过 `async` 实现的,而不是显式地返回一个 Promise: - -```js{2} -export default { - async setup() { - // 在 `setup` 内部使用 `await` 需要非常小心 - // 因为大多数组合式 API 函数只会在 - // 第一个 `await` 之前工作 - const data = await loadData() - - // 它隐性地包裹在一个 Promise 内 - // 因为函数是 `async` 的 - return { - // ... - } - } -} -``` - -## 子组件更新 - -一旦 `` 的 `default` 插槽里的内容被解析,则它只有在 `default` 根结点被替换的时候才能被再次触发。而树里的深层嵌套组件不足以让 `` 回到等待状态。 - -如果根结点发生了变化,它会触发 `pending` 事件。然而,默认情况下,它不会更新 DOM 以展示 `fallback` 内容。取而代之的是,它会继续展示旧的 DOM,直到新组件准备就绪。这个行为可以通过 `timeout` prop 进行控制。这个值是一个毫秒数,告诉 `` 组件多久之后展示 `fallback`。如果这个值是 `0` 则表示它在 `` 进入等待状态时会立即显示。 - -## 事件 - -除了 `pending` 事件以外,`` 组件还拥有 `resolve` 和 `fallback` 事件。`resolve` 事件会在 `default` 插槽完成新内容的解析之后被触发。`fallback` 事件会在 `fallback` 插槽的内容展示的时候被触发。 - -这些事件可以用在诸如当新组件加载时在旧 DOM 上展示一个加载标识等场景。 - -## 和其它组件结合 - -将 `` 跟 [``](https://cn.vuejs.org/api/built-in-components.html#transition) 和 [``](https://cn.vuejs.org/api/built-in-components.html#keep-alive) 组件相结合是常见的情形。这些组件的嵌套顺序对于它们的正确工作很重要。 - -额外的,这些组件经常用于衔接 [Vue Router](https://router.vuejs.org/zh/) 的 `` 组件。 - -以下示例展示了如何嵌套这些组件以让它们的表现符合预期。若要简化这个组合你可以移除不需要的组件: - -```html - - - -``` - -Vue Router 有内置的基于动态导入的[组件懒加载](https://router.vuejs.org/zh/guide/advanced/lazy-loading.html)支持。它和异步组件有所区别,并且当前不会触发 ``。不过它们仍然可以包含异步组件作为后代,这样它们还是可以正常触发 ``。 diff --git a/src/zh/breaking-changes/v-model.md b/src/zh/breaking-changes/v-model.md index 42c45a6..6ce282c 100644 --- a/src/zh/breaking-changes/v-model.md +++ b/src/zh/breaking-changes/v-model.md @@ -144,7 +144,7 @@ this.$emit('update:title', newValue) ``` -我们可以在 [Custom Events](http://cn.vuejs.org/guide/components/events.html#usage-with-v-model) 部分中了解有关自定义 `v-model` 修饰符的更多信息。 +我们可以在[组件事件](http://cn.vuejs.org/guide/components/events.html#usage-with-v-model)部分中了解有关自定义 `v-model` 修饰符的更多信息。 ## 迁移策略 diff --git a/src/zh/migration-build.md b/src/zh/migration-build.md index f813cd0..4109931 100644 --- a/src/zh/migration-build.md +++ b/src/zh/migration-build.md @@ -20,7 +20,7 @@ - 对 IE11 的支持:[Vue 3 已经官方放弃对 IE11 的支持](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0038-vue3-ie11-support.md)。如果仍然需要支持 IE11 或更低版本,那你仍需继续使用 Vue 2。 -- 服务端渲染:该迁移构建版本可以被用于服务端渲染,但是迁移一个自定义的服务端渲染配置还有很多工作要做。大致的思路是将 `vue-server-renderer` 替换为 [`@vue/server-renderer`](https://github.com/vuejs/vue-next/tree/master/packages/server-renderer)。Vue 3 不再提供一个包渲染器,且我们推荐使用 [Vite](https://cn.vitejs.dev/guide/ssr.html) 以支持 Vue 3 服务端渲染。如果你正在使用 [Nuxt.js](https://zh.nuxtjs.org/),可以尝试 [Nuxt Bridge,一个 Nuxt.js 2 到 3 的兼容层](https://v3.nuxtjs.org/getting-started/bridge/)。对于复杂、生产环境的项目来说,可能最好还是等待一下 [Nuxt 3 (目前处于 beta 阶段)](https://v3.nuxtjs.org/getting-started/introduction)。 +- 服务端渲染:该迁移构建版本可以被用于服务端渲染,但是迁移一个自定义的服务端渲染配置还有很多工作要做。大致的思路是将 `vue-server-renderer` 替换为 [`@vue/server-renderer`](https://github.com/vuejs/core/tree/master/packages/server-renderer)。Vue 3 不再提供一个包渲染器,且我们推荐使用 [Vite](https://cn.vitejs.dev/guide/ssr.html) 以支持 Vue 3 服务端渲染。如果你正在使用 [Nuxt.js](https://zh.nuxtjs.org/),可以尝试 [Nuxt Bridge,一个 Nuxt.js 2 到 3 的兼容层](https://v3.nuxtjs.org/getting-started/bridge/)。对于复杂、生产环境的项目来说,可能更好还是等待一下 Nuxt 3。 ### 预期 @@ -75,13 +75,13 @@ ```js // vue.config.js module.exports = { - chainWebpack: config => { + chainWebpack: (config) => { config.resolve.alias.set('vue', '@vue/compat') config.module .rule('vue') .use('vue-loader') - .tap(options => { + .tap((options) => { return { ...options, compilerOptions: { @@ -273,7 +273,7 @@ export default { | ID | 类型 | 描述 | 文档 | | ---- | ---- | ---- | ---- | | GLOBAL_MOUNT_CONTAINER | ⨂ | 被挂载的应用不会替换被挂载到的元素 | [链接](./breaking-changes/mount-changes.html) | -| CONFIG_DEVTOOLS | ⨂ | 生产环境开发者工具现在是一个构建时的开关 | [链接](https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags) | +| CONFIG_DEVTOOLS | ⨂ | 生产环境开发者工具现在是一个构建时的开关 | [链接](https://github.com/vuejs/core/tree/master/packages/vue#bundler-build-feature-flags) | | COMPILER_V_IF_V_FOR_PRECEDENCE | ⨂ | `v-if` 和 `v-for` 用在相同的元素上时的处理顺序发生了改变 | [链接](./breaking-changes/v-if-v-for.html) | | COMPILER_V_IF_SAME_KEY | ⨂ | `v-if` 分支不能再拥有相同的 key | [链接](./breaking-changes/key-attribute.html#on-conditional-branches) | | COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENT | ⨂ | `