diff --git a/README.md b/README.md index bb389fef..56b8bc69 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,6 @@ Vue 2 plugin for **Composition API** English | [中文](./README.zh-CN.md) ・ [**Composition API Docs**](https://composition-api.vuejs.org/) - -**Note: the primary goal of this package is to allow the community to experiment with the API and provide feedback before it's finalized. The implementation may contain minor inconsistencies with the RFC as the latter gets updated. We do not recommend using this package for production yet at this stage.** - ---- - ## Installation ### NPM @@ -45,14 +40,14 @@ Include `@vue/composition-api` after Vue and it will install itself automaticall ```html - + ``` -`@vue/composition-api` will be exposed to global variable `window.vueCompositionApi`. +`@vue/composition-api` will be exposed to global variable `window.VueCompositionAPI`. ```ts -const { ref, reactive } = vueCompositionApi +const { ref, reactive } = VueCompositionAPI ``` ## TypeScript Support @@ -99,8 +94,7 @@ export default { ## Limitations -> :white_check_mark: -> Support     :x: Not Supported +> :white_check_mark: Support     :x: Not Supported ### `Ref` Unwrap @@ -375,6 +369,27 @@ watch(() => { +### createApp + +
+ +⚠️ createApp() is global + + +In Vue 3, `createApp()` is introduced to provide context(plugin, components, etc.) isolation between app instances. Due the the design of Vue 2, in this plugin, we provide `createApp()` as a forward compatible API which is just an alias of the global. + +```ts +const app1 = createApp(RootComponent1) +app1.component('Foo', Foo) // equivalent to Vue.component('Foo', Foo) +app1.use(VueRouter) // equivalent to Vue.use(VueRouter) + +const app2 = createApp(RootComponent2) +app2.component('Bar', Bar) // equivalent to Vue.use('Bar', Bar) +``` + +
+ + ### Missing APIs The following APIs introduced in Vue 3 are not available in this plugin. diff --git a/README.zh-CN.md b/README.zh-CN.md index 157ab140..3eab32a2 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,135 +1,140 @@ -# Vue Composition API +# @vue/composition-api Vue 2 插件用于提供 Vue 3 中的 **组合式 API**. [![npm](https://img.shields.io/npm/v/@vue/composition-api)](https://www.npmjs.com/package/@vue/composition-api) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/vuejs/composition-api/Build%20&%20Test)](https://github.com/vuejs/composition-api/actions?query=workflow%3A%22Build+%26+Test%22) -[**English**](./README.md) | 中文文档 / [**组合式 API RFC**](https://composition-api.vuejs.org/zh) +[English](./README.md) | 中文 ・ [**组合式 API 文档**](https://composition-api.vuejs.org/zh) -**请注意:此插件的主要目的是让社区尝试新的API并在其最终确定之前提供反馈。随着RFC的更新,该实现可能包含与RFC有细微的不一致。现阶段,我们暂不建议将此插件用于生产环境。** ---- +## 安装 -# 导航 - -- [安装](#安装) -- [使用](#使用) -- [TypeScript](#TypeScript) - - [TSX](#tsx) -- [限制](#限制) -- [更新日志](https://github.com/vuejs/composition-api/blob/master/CHANGELOG.md) - -# 安装 - -**npm** +### NPM ```bash -npm install @vue/composition-api --save +npm install @vue/composition-api +# or +yarn add @vue/composition-api ``` -**yarn** +在使用 `@vue/composition-api` 前,必须先先通过 `Vue.use()` 进行安装后方可使用使用新的 [**组合式 API**](https://composition-api.vuejs.org/zh) 进行组件开发。 -```bash -yarn add @vue/composition-api -``` +```js +import Vue from 'vue' +import VueCompositionAPI from '@vue/composition-api' -**CDN** +Vue.use(VueCompositionAPI) +``` -```html - +```js +// 使用 API +import { ref, reactive } from '@vue/composition-api' ``` -通过全局变量 `window.vueCompositionApi` 来使用。 +> :bulb: 当迁移到 Vue 3 时,只需简单的将 `@vue/composition-api` 替换成 `vue` 即可。你现有的代码几乎无需进行额外的改动。 -# 使用 -在使用任何 `@vue/composition-api` 提供的能力前,必须先通过 `Vue.use()` 进行安装: +### CDN -```js -import Vue from 'vue'; -import VueCompositionApi from '@vue/composition-api'; +在 Vue 之后引入 `@vue/composition-api` ,插件将会自动完成安装。 -Vue.use(VueCompositionApi); + +```html + + ``` + -安装插件后,您就可以使用新的 [Composition API](https://vue-composition-api-rfc.netlify.com/) 来开发组件了。 +`@vue/composition-api` 将会暴露在全局变量 `window.VueCompositionAPI` 中。 -# TypeScript +```ts +const { ref, reactive } = VueCompositionAPI +``` + +## TypeScript 支持 -**本插件要求使用 TypeScript 3.5.1 以上版本,如果你正在使用 `vetur`,请将 `vetur.useWorkspaceDependencies` 设为 `true`。** +> 本插件要求使用 TypeScript **3.5.1** 或以上版本 为了让 TypeScript 在 Vue 组件选项中正确地推导类型,我们必须使用 `defineComponent` 来定义组件: ```ts -import { defineComponent } from '@vue/composition-api'; +import { defineComponent } from '@vue/composition-api' -const Component = defineComponent({ - // 启用类型推断 -}); - -const Component = { - // 无法进行选项的类型推断 - // TypeScript 无法知道这是一个 Vue 组件的选项对象 -}; +export default defineComponent({ + // 类型推断启用 +}) ``` -## TSX +### JSX/TSX -:rocket: 这里有一个配置好 TS/TSX 支持的[示例仓库](https://github.com/liximomo/vue-composition-api-tsx-example)来帮助你快速开始. +要使得 `@vue/composition-api` 支持 JSX/TSX,请前往查看由 [@luwanquan](https://github.com/luwanquan) 开发的 Babel 插件[babel-preset-vca-jsx](https://github.com/luwanquan/babel-preset-vca-jsx)。 -要支持 TSX,请创建一个类型定义文件并提供正确的 JSX 定义。内容如下: +## SSR -```ts -// 文件: `shim-tsx.d.ts` -import Vue, { VNode } from 'vue'; -import { ComponentRenderProxy } from '@vue/composition-api'; - -declare global { - namespace JSX { - // tslint:disable no-empty-interface - interface Element extends VNode {} - // tslint:disable no-empty-interface - interface ElementClass extends ComponentRenderProxy {} - interface ElementAttributesProperty { - $props: any; // 定义要使用的属性名称 - } - interface IntrinsicElements { - [elem: string]: any; +尽管 Vue 3 暂时没有给出确定的 SSR 的 API,这个插件实现了 `onServerPrefetch` 生命周期钩子函数。这个钩子允许你使用在传统 API 中的 `serverPrefetch` 函数。 + +```js +import { onServerPrefetch } from '@vue/composition-api' + +export default { + setup (props, { ssrContext }) { + const result = ref() + + onServerPrefetch(async () => { + result.value = await callApi(ssrContext.someId) + }) + + return { + result, } - } + }, } ``` -# 限制 +## 限制 -## `Ref` 自动展开 (unwrap) +> :white_check_mark: 支持     :x: 不支持 + + +### `Ref` 自动展开 (unwrap) 数组索引属性无法进行自动展开: -### **不要**使用 `Array` 直接存取 `ref` 对象: + +
+ +❌ 不要 使用数组直接存取 ref 对象 + ```js const state = reactive({ list: [ref(0)], -}); +}) // 不会自动展开, 须使用 `.value` -state.list[0].value === 0; // true +state.list[0].value === 0 // true -state.list.push(ref(1)); +state.list.push(ref(1)) // 不会自动展开, 须使用 `.value` -state.list[1].value === 1; // true +state.list[1].value === 1 // true ``` -### **不要**在数组中使用含有 `ref` 的普通对象: +
+ + +
+ +❌ 不要 在数组中使用含有 ref 的普通对象 + + ```js const a = { count: ref(0), -}; +} const b = reactive({ list: [a], // `a.count` 不会自动展开!! -}); +}) // `count` 不会自动展开, 须使用 `.value` b.list[0].count.value === 0; // true @@ -142,51 +147,47 @@ const b = reactive({ count: ref(0), // 不会自动展开!! }, ], -}); +}) // `count` 不会自动展开, 须使用 `.value` b.list[0].count.value === 0; // true ``` -### **应该**总是将 `ref` 存放到 `reactive` 对象中: +
+ + +
+ +✅ 在数组中,应该 总是将 ref 存放到 reactive 对象中 + ```js const a = reactive({ count: ref(0), -}); +}) const b = reactive({ list: [a], -}); +}) // 自动展开 -b.list[0].count === 0; // true +b.list[0].count === 0 // true b.list.push( reactive({ count: ref(1), }) -); +) // 自动展开 b.list[1].count === 1; // true ``` -### `reactive` 会返回一个修改过的原始的对象 +
-此行为与 Vue 2 中的 `Vue.observable` 一致 -> Vue 3 中会返回一个新的的代理对象. - ---- - -## `watch()` API - -不支持 `onTrack` 和 `onTrigger` 选项。 - ---- - -## 模板 Refs +### 模板 Refs -> :white_check_mark: 支持     :x: 不支持 - -:white_check_mark: 字符串 ref && 从 `setup()` 返回 ref: +
+ +✅ 字符串 ref && 从 setup() 返回 ref + ```html