From bbec8ca568402fc9aa238875b7a2ea5abbea4f0f Mon Sep 17 00:00:00 2001 From: Naoki Endoh Date: Sat, 10 Jul 2021 11:08:30 +0900 Subject: [PATCH 01/12] docs: link directly to equivalent pages in translations https://github.com/vuejs/docs/commit/883b753327563bef5636d8e821563dc03f24b009 --- src/.vuepress/config.js | 17 ++++++++---- src/.vuepress/theme/components/NavLink.vue | 32 ++++++++++++++++++++-- src/.vuepress/theme/layouts/404.vue | 31 ++++++++++++++------- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index 8103482b..5cec4ab7 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -423,23 +423,28 @@ module.exports = { // Translation maintainers: Please include the link below to the English documentation { text: 'English', - link: 'https://v3.vuejs.org/' + link: 'https://v3.vuejs.org/', + isTranslation: true }, { text: '中文', - link: 'https://v3.cn.vuejs.org/' + link: 'https://v3.cn.vuejs.org/', + isTranslation: true }, { text: '한국어', - link: 'https://v3.ko.vuejs.org/' + link: 'https://v3.ko.vuejs.org/', + isTranslation: true }, // { - // text: '日本語', - // link: 'https://v3.ja.vuejs.org/' + // text: '日本語', + // link: 'https://v3.ja.vuejs.org/', + // isTranslation: true // }, { text: 'Русский', - link: 'https://v3.ru.vuejs.org/' + link: 'https://v3.ru.vuejs.org/ru/', + isTranslation: true }, { text: 'その他の翻訳', diff --git a/src/.vuepress/theme/components/NavLink.vue b/src/.vuepress/theme/components/NavLink.vue index 4ccd13d8..3f4754f4 100644 --- a/src/.vuepress/theme/components/NavLink.vue +++ b/src/.vuepress/theme/components/NavLink.vue @@ -22,8 +22,26 @@ diff --git a/src/.vuepress/theme/layouts/404.vue b/src/.vuepress/theme/layouts/404.vue index 2cbfa0f1..915deb1d 100644 --- a/src/.vuepress/theme/layouts/404.vue +++ b/src/.vuepress/theme/layouts/404.vue @@ -3,7 +3,13 @@

404

-
{{ getMsg() }}
+
+

Whoops! This page doesn't exist.

+
+ +

+ New pages are added to the documentation all the time. This page might not be included in all of the translations yet. +

Take me home. @@ -13,17 +19,22 @@ +``` + +As you can see, without annotating the `evt` argument correctly, TypeScript will throw an error when we try to access the value of the `` element. The solution is to cast the event target with a correct type: + +```ts +const handleChange = (evt: Event) => { + console.log((evt.target as HTMLInputElement).value) +} +``` From 61dae215fec4502f70eed8f30b9d8b702537b784 Mon Sep 17 00:00:00 2001 From: Naoki Endoh Date: Sat, 10 Jul 2021 11:30:23 +0900 Subject: [PATCH 03/12] docs: elaborate on what can be included in the createApp root props https://github.com/vuejs/docs/commit/9554a8309800558fd1da1e5d95bbbf3af59e9a0f --- src/api/global-api.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/api/global-api.md b/src/api/global-api.md index c804ba4b..115ebaa7 100644 --- a/src/api/global-api.md +++ b/src/api/global-api.md @@ -63,6 +63,8 @@ const app = createApp(
``` +The root props are raw props, much like those passed to [`h`](#h) to create a VNode. In addition to component props, they can also include attributes and event listeners to be applied to the root component. + ### 型定義 ```ts From 646c332320f619057e90824d8f49b1c3f160634e Mon Sep 17 00:00:00 2001 From: Naoki Endoh Date: Sat, 10 Jul 2021 11:31:12 +0900 Subject: [PATCH 04/12] add an any and a union type example for typescript prop annotation https://github.com/vuejs/docs/commit/4dc940e688f370c6346b9c982a660172d92a11ed --- src/guide/typescript-support.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/guide/typescript-support.md b/src/guide/typescript-support.md index 6178dd53..0b6bfe17 100644 --- a/src/guide/typescript-support.md +++ b/src/guide/typescript-support.md @@ -247,6 +247,7 @@ interface Book { const Component = defineComponent({ props: { name: String, + id: [Number, String], success: { type: String }, callback: { type: Function as PropType<() => void> @@ -254,6 +255,9 @@ const Component = defineComponent({ book: { type: Object as PropType, required: true + }, + metadata: { + type: null // metadata is typed as any } } }) From 31417bd7aed73cbdcace374046413c56162c6725 Mon Sep 17 00:00:00 2001 From: Naoki Endoh Date: Sat, 10 Jul 2021 11:35:41 +0900 Subject: [PATCH 05/12] fix: code style in reactivity-computed-watchers.md https://github.com/vuejs/docs/commit/fd21397c07d3c8bcca1b7d7d3ed21f6c444ec6bb --- src/guide/reactivity-computed-watchers.md | 52 +++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/guide/reactivity-computed-watchers.md b/src/guide/reactivity-computed-watchers.md index fe5894a4..fb68e6c6 100644 --- a/src/guide/reactivity-computed-watchers.md +++ b/src/guide/reactivity-computed-watchers.md @@ -95,8 +95,7 @@ watchEffect(async (onInvalidate) => { Vue のリアクティブシステムは、無効になった変更をバッファリングし、非同期に処理することによって、おなじ "tick" の中での複数の状態の変化に対して、不要な重複の呼び出しを避けることができています。内部的には、コンポーネントの `update` 関数も、監視されている作用の 1 つです。ユーザーによる作用がキューに入っている場合、デフォルトではすべてのコンポーネントの更新の **前に** 呼び出されます: -```html - +```vue @@ -201,15 +200,15 @@ watch(count, (count, prevCount) => { ウォッチャは、配列を利用することで、複数のデータソースを同時に監視できます: ```js -const firstName = ref(''); -const lastName = ref(''); +const firstName = ref('') +const lastName = ref('') watch([firstName, lastName], (newValues, prevValues) => { - console.log(newValues, prevValues); + console.log(newValues, prevValues) }) -firstName.value = "John"; // logs: ["John",""] ["", ""] -lastName.value = "Smith"; // logs: ["John", "Smith"] ["John", ""] +firstName.value = 'John' // logs: ["John", ""] ["", ""] +lastName.value = 'Smith' // logs: ["John", "Smith"] ["John", ""] ``` ### リアクティブなオブジェクトの監視 @@ -222,8 +221,9 @@ const numbers = reactive([1, 2, 3, 4]) watch( () => [...numbers], (numbers, prevNumbers) => { - console.log(numbers, prevNumbers); - }) + console.log(numbers, prevNumbers) + } +) numbers.push(5) // logs: [1,2,3,4,5] [1,2,3,4] ``` @@ -234,47 +234,47 @@ numbers.push(5) // logs: [1,2,3,4,5] [1,2,3,4] const state = reactive({ id: 1, attributes: { - name: "", - }, -}); + name: '' + } +}) watch( () => state, (state, prevState) => { console.log( - "not deep ", + 'not deep', state.attributes.name, prevState.attributes.name - ); + ) } -); +) watch( () => state, (state, prevState) => { console.log( - "deep ", + 'deep', state.attributes.name, prevState.attributes.name - ); + ) }, { deep: true } -); +) -state.attributes.name = "Alex"; // Logs: "deep " "Alex" "Alex" +state.attributes.name = 'Alex' // Logs: "deep" "Alex" "Alex" ``` しかし、リアクティブなオブジェクトや配列を監視すると、そのオブジェクトの状態の現在値と前回値の両方について参照が常に返されます。深くネストされたオブジェクトや配列を完全に監視するためには、値のディープコピーが必要な場合があります。これは [lodash.cloneDeep](https://lodash.com/docs/4.17.15#cloneDeep) のようなユーティリティで実現できます。 ```js -import _ from 'lodash'; +import _ from 'lodash' const state = reactive({ id: 1, attributes: { - name: "", - }, -}); + name: '' + } +}) watch( () => _.cloneDeep(state), @@ -282,11 +282,11 @@ watch( console.log( state.attributes.name, prevState.attributes.name - ); + ) } -); +) -state.attributes.name = "Alex"; // Logs: "Alex" "" +state.attributes.name = 'Alex'; // Logs: "Alex" "" ``` ### `watchEffect` との振る舞いの共有 From b808e8ad43d94da337840309b6c9e8a9cc0fc028 Mon Sep 17 00:00:00 2001 From: Naoki Endoh Date: Sat, 10 Jul 2021 11:36:42 +0900 Subject: [PATCH 06/12] docs: extra examples of migrating keyCode modifiers https://github.com/vuejs/docs/commit/afc2a953cb175173f13ed85f4040e65c87e29dc5 --- src/guide/migration/keycode-modifiers.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/guide/migration/keycode-modifiers.md b/src/guide/migration/keycode-modifiers.md index 2cf895c9..be9a4fd8 100644 --- a/src/guide/migration/keycode-modifiers.md +++ b/src/guide/migration/keycode-modifiers.md @@ -46,7 +46,10 @@ Vue.config.keyCodes = { ```html - + + + + ``` `config.keyCodes` の利用も同様の理由で非推奨となり、サポートされなくなりました。 @@ -55,6 +58,14 @@ Vue.config.keyCodes = { キーコードを利用している場合は、ケバブケースでの命名に変更することを推奨します。 +The keys for some punctuation marks can just be included literally. e.g. For the `,` key: + +```html + +``` + +Limitations of the syntax prevent certain characters from being matched, such as `"`, `'`, `/`, `=`, `>`, and `.`. For those characters you should check `event.key` inside the listener instead. + [移行ビルドのフラグ:](migration-build.html#compat-の設定) - `CONFIG_KEY_CODES` From 9c4deea34a37a5827420aa9c07aacfa9b962b30e Mon Sep 17 00:00:00 2001 From: Naoki Endoh Date: Sat, 10 Jul 2021 11:42:29 +0900 Subject: [PATCH 07/12] docs: add various improvements to the Events API migration guide https://github.com/vuejs/docs/commit/d9430c250bc7da8f0da94b65f0c33e8501c502df --- src/guide/migration/events-api.md | 55 +++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/src/guide/migration/events-api.md b/src/guide/migration/events-api.md index e6d82ef7..2e42e41c 100644 --- a/src/guide/migration/events-api.md +++ b/src/guide/migration/events-api.md @@ -7,46 +7,46 @@ badges: ## 概要 -インスタンスメソッド `$on`、`$off`、`$once` は削除されました。アプリケーションインスタンスはイベントエミッタインタフェースを実装しなくなりました。 +インスタンスメソッド `$on`、`$off`、`$once` は削除されました。コンポーネントインスタンスはイベントエミッタインタフェースを実装しなくなりました。 ## 2.x での構文 -2.x では、Vue インスタンスを使用して、イベントエミッタ API (`$on`、`$off`、`$once`) を介して強制的に接続されたハンドラをトリガすることができました。これは、アプリケーション全体で使用されるグローバルイベントリスナーを作成するための _イベントハブ_ を作るために使用されました。 +2.x では、Vue インスタンスを使用して、イベントエミッタ API (`$on`、`$off`、`$once`) を介して強制的に接続されたハンドラをトリガすることができました。これは、アプリケーション全体で使用されるグローバルイベントリスナーを作成するための _イベントバス_ を作るために使用できました。 ```js -// eventHub.js +// eventBus.js -const eventHub = new Vue() +const eventBus = new Vue() -export default eventHub +export default eventBus ``` ```js // ChildComponent.vue -import eventHub from './eventHub' +import eventBus from './eventBus' export default { mounted() { - // eventHub リスナーの追加 - eventHub.$on('custom-event', () => { + // eventBus リスナーの追加 + eventBus.$on('custom-event', () => { console.log('Custom event triggered!') }) }, beforeDestroy() { - // eventHub リスナーの削除 - eventHub.$off('custom-event') + // eventBus リスナーの削除 + eventBus.$off('custom-event') }, } ``` ```js // ParentComponent.vue -import eventHub from './eventHub' +import eventBus from './eventBus' export default { methods: { callGlobalCustomEvent() { - eventHub.$emit('custom-event') // ChildComponent がマウントされている場合、コンソールにメッセージが表示されます。 + eventBus.$emit('custom-event') // ChildComponent がマウントされている場合、コンソールにメッセージが表示されます。 }, }, } @@ -58,26 +58,47 @@ export default { ## 移行の戦略 +[Migration build flag: `INSTANCE_EVENT_EMITTER`](migration-build.html#compat-configuration) + Vue 3 では、これらの API を使用して、コンポーネント内からコンポーネント自身が発行したイベントを購読することはできなくなりました。そのユースケースのための移行パスはありません。 -ただし、EventHub (イベントハブ) パターンは、Event Emitter (イベントエミッタ) インタフェースを実装した外部ライブラリを使用することで置き換えることができます。例えば、[mitt](https://github.com/developit/mitt) や [tiny-emitter](https://github.com/scottcorgan/tiny-emitter) などです。 +### Root Component Events + +Static event listeners can be added to the root component by passing them as props to `createApp`: + +```js +createApp(App, { + // Listen for the 'expand' event + onExpand() { + console.log('expand') + } +}) +``` + +### Event Bus + +EventBus (イベントバス) パターンは、Event Emitter (イベントエミッタ) インタフェースを実装した外部ライブラリを使用することで置き換えることができます。例えば、[mitt](https://github.com/developit/mitt) や [tiny-emitter](https://github.com/scottcorgan/tiny-emitter) などです。 例: ```js -// eventHub.js +// eventBus.js import emitter from 'tiny-emitter/instance' export default { $on: (...args) => emitter.on(...args), $once: (...args) => emitter.once(...args), $off: (...args) => emitter.off(...args), - $emit: (...args) => emitter.emit(...args), + $emit: (...args) => emitter.emit(...args) } ``` これは Vue 2 と同じような Event Emitter API を提供します。 -これらのメソッドは、Vue 3 の将来の互換ビルドでもサポートされる可能性があります。 +In most circumstances, using a global event bus for communicating between components is discouraged. While it is often the simplest solution in the short term, it almost invariably proves to be a maintenance headache in the long term. Depending on the circumstances, there are various alternatives to using an event bus: -[移行ビルドのフラグ: `INSTANCE_EVENT_EMITTER`](migration-build.html#compat-の設定) +* [Props](/guide/component-basics.html#passing-data-to-child-components-with-props) and [events](/guide/component-basics.html#listening-to-child-components-events) should be your first choice for parent-child communication. Siblings can communicate via their parent. +* [Provide and inject](/guide/component-provide-inject.html) allow a component to communicate with its slot contents. This is useful for tightly-coupled components that are always used together. +* `provide`/`inject` can also be used for long-distance communication between components. It can help to avoid 'prop drilling', where props need to be passed down through many levels of components that don't need those props themselves. +* Prop drilling can also be avoided by refactoring to use slots. If an interim component doesn't need the props then it might indicate a problem with separation of concerns. Introducing a slot in that component allows the parent to create the content directly, so that props can be passed without the interim component needing to get involved. +* [Global state management](/guide/state-management.html), such as [Vuex](https://next.vuex.vuejs.org/). From 1fe0a6b24111e5acb7dd7c1c615898cac7d7391f Mon Sep 17 00:00:00 2001 From: Naoki Endoh Date: Sat, 10 Jul 2021 11:53:05 +0900 Subject: [PATCH 08/12] docs: translate new typescript example --- src/guide/typescript-support.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/guide/typescript-support.md b/src/guide/typescript-support.md index 0b6bfe17..5b1107f8 100644 --- a/src/guide/typescript-support.md +++ b/src/guide/typescript-support.md @@ -491,9 +491,9 @@ export default defineComponent({ }) ``` -### Typing Event Handlers +### イベントハンドラを型定義する -When dealing with native DOM events, it might be useful to type the argument we pass to the handler correctly. Let's take a look at this example: +ネイティブの DOM イベントを扱うとき、ハンドラに渡す引数を正しく型定義することが有効な場合があります。この例を見てみましょう: ```vue