From ba0bffa65cbe7ff0cd548ab0a9e4437b330c95fb Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 29 May 2020 15:37:59 +0200 Subject: [PATCH 1/8] chore(changelog): 3.3.2 --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dffedc737..a149eb247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [3.3.2](https://github.com/vuejs/vue-router/compare/v3.3.1...v3.3.2) (2020-05-29) + + +### Bug Fixes + +* **errors:** NavigationCanceled with async components ([#3211](https://github.com/vuejs/vue-router/issues/3211)) ([be39ca3](https://github.com/vuejs/vue-router/commit/be39ca3)) +* remove error.stack modification ([#3212](https://github.com/vuejs/vue-router/issues/3212)) ([a0075ed](https://github.com/vuejs/vue-router/commit/a0075ed)) + + + ## [3.3.1](https://github.com/vuejs/vue-router/compare/v3.3.0...v3.3.1) (2020-05-27) From dab86c5263c077b486de6438927740a78c72c71c Mon Sep 17 00:00:00 2001 From: javiertury Date: Thu, 4 Jun 2020 12:31:01 +0200 Subject: [PATCH 2/8] feat(types): RouterConfig for multiple components (#3217) (#3218) * feat(types): RouterConfig for multiple components (#3217) * Apply suggestions from code review Co-authored-by: Eduardo San Martin Morote --- types/router.d.ts | 19 ++++++++++++++----- types/test/index.ts | 3 +++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/types/router.d.ts b/types/router.d.ts index 424a48430..09bca5032 100644 --- a/types/router.d.ts +++ b/types/router.d.ts @@ -89,21 +89,30 @@ export interface PathToRegexpOptions { end?: boolean } -export interface RouteConfig { +interface _RouteConfigBase { path: string name?: string - component?: Component - components?: Dictionary redirect?: RedirectOption alias?: string | string[] - children?: RouteConfig[] meta?: any beforeEnter?: NavigationGuard - props?: boolean | Object | RoutePropsFunction caseSensitive?: boolean pathToRegexpOptions?: PathToRegexpOptions } +interface RouteConfigSingleView extends _RouteConfigBase { + component?: Component + props?: boolean | Object | RoutePropsFunction +} + +interface RouteConfigMultipleViews extends _RouteConfigBase { + components?: Dictionary + children?: RouteConfig[] + props?: Dictionary +} + +export type RouteConfig = RouteConfigSingleView | RouteConfigMultipleViews + export interface RouteRecord { path: string regex: RegExp diff --git a/types/test/index.ts b/types/test/index.ts index 4afa858b0..328e8c980 100644 --- a/types/test/index.ts +++ b/types/test/index.ts @@ -8,6 +8,7 @@ Vue.use(VueRouter) const Home = { template: '
home
' } const Foo = { template: '
foo
' } const Bar = { template: '
bar
' } +const Abc = { template: '
abc
' } const Async = () => Promise.resolve({ template: '
async
' }) const Hook: ComponentOptions = { @@ -76,6 +77,7 @@ const router = new VueRouter({ components: { default: Foo, bar: Bar, + abc: Abc, asyncComponent: Async }, meta: { auth: true }, @@ -88,6 +90,7 @@ const router = new VueRouter({ props: { default: true, bar: { id: 123 }, + abc: route => route.params, asyncComponent: (route: Route) => route.params } }, From 1f3aea660804bd9dfba3020e2d112d9bd510e518 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 5 Jun 2020 20:43:30 +0200 Subject: [PATCH 3/8] feat: better wording for navigation redirected failure --- examples/router-errors/app.js | 2 + src/history/errors.js | 12 +++- test/unit/specs/error-handling.spec.js | 81 +++++++++++++++----------- 3 files changed, 59 insertions(+), 36 deletions(-) diff --git a/examples/router-errors/app.js b/examples/router-errors/app.js index 749d36463..b6979380d 100644 --- a/examples/router-errors/app.js +++ b/examples/router-errors/app.js @@ -17,6 +17,8 @@ const router = new VueRouter({ ] }) +window.router = router + router.beforeEach((to, from, next) => { console.log('from', from.fullPath) console.log('going to', to.fullPath) diff --git a/src/history/errors.js b/src/history/errors.js index 2d624e135..0eaa5a8df 100644 --- a/src/history/errors.js +++ b/src/history/errors.js @@ -10,7 +10,9 @@ export function createNavigationRedirectedError (from, to) { from, to, NavigationFailureType.redirected, - `Redirected from "${from.fullPath}" to "${stringifyRoute(to)}" via a navigation guard.` + `Redirected when going from "${from.fullPath}" to "${stringifyRoute( + to + )}" via a navigation guard.` ) } @@ -28,7 +30,9 @@ export function createNavigationCancelledError (from, to) { from, to, NavigationFailureType.cancelled, - `Navigation cancelled from "${from.fullPath}" to "${to.fullPath}" with a new navigation.` + `Navigation cancelled from "${from.fullPath}" to "${ + to.fullPath + }" with a new navigation.` ) } @@ -37,7 +41,9 @@ export function createNavigationAbortedError (from, to) { from, to, NavigationFailureType.aborted, - `Navigation aborted from "${from.fullPath}" to "${to.fullPath}" via a navigation guard.` + `Navigation aborted from "${from.fullPath}" to "${ + to.fullPath + }" via a navigation guard.` ) } diff --git a/test/unit/specs/error-handling.spec.js b/test/unit/specs/error-handling.spec.js index d73a89d95..24a31145c 100644 --- a/test/unit/specs/error-handling.spec.js +++ b/test/unit/specs/error-handling.spec.js @@ -8,20 +8,25 @@ describe('error handling', () => { it('onReady errors', done => { const router = new VueRouter() const err = new Error('foo') - router.beforeEach(() => { throw err }) - router.onError(() => { }) + router.beforeEach(() => { + throw err + }) + router.onError(() => {}) const onReady = jasmine.createSpy('ready') const onError = jasmine.createSpy('error') const onPromiseReject = jasmine.createSpy('promise reject') router.onReady(onReady, onError) - router.push('/').catch(onPromiseReject).finally(() => { - expect(onReady).not.toHaveBeenCalled() - expect(onError).toHaveBeenCalledWith(err) - expect(onPromiseReject).toHaveBeenCalled() - done() - }) + router + .push('/') + .catch(onPromiseReject) + .finally(() => { + expect(onReady).not.toHaveBeenCalled() + expect(onError).toHaveBeenCalledWith(err) + expect(onPromiseReject).toHaveBeenCalled() + done() + }) }) it('navigation errors', done => { @@ -32,13 +37,18 @@ describe('error handling', () => { router.onError(spy) router.push('/') - router.beforeEach(() => { throw err }) - - router.push('/foo').catch(spy1).finally(() => { - expect(spy).toHaveBeenCalledWith(err) - expect(spy1).toHaveBeenCalled() - done() + router.beforeEach(() => { + throw err }) + + router + .push('/foo') + .catch(spy1) + .finally(() => { + expect(spy).toHaveBeenCalledWith(err) + expect(spy1).toHaveBeenCalled() + done() + }) }) it('NavigationDuplicated error', done => { @@ -65,7 +75,7 @@ describe('error handling', () => { router.push('/') }) - it('NavigationCancelled error for nested async navigation', (done) => { + it('NavigationCancelled error for nested async navigation', done => { const component = { template: ``, beforeRouteEnter (to, from, next) { @@ -73,9 +83,7 @@ describe('error handling', () => { } } const router = new VueRouter({ - routes: [ - { path: '/a', component } - ] + routes: [{ path: '/a', component }] }) router.push('/a').catch(err => { @@ -96,6 +104,8 @@ describe('error handling', () => { router.push('/foo?redirect=/').catch(err => { expect(err.type).toBe(NavigationFailureType.redirected) + expect(err.from.path).toBe('/') + expect(err.to.path).toBe('/foo') done() }) }) @@ -103,7 +113,9 @@ describe('error handling', () => { it('NavigationAborted error', done => { const router = new VueRouter() - router.beforeEach((to, from, next) => { next(false) }) + router.beforeEach((to, from, next) => { + next(false) + }) router.push('/foo').catch(err => { expect(err.type).toBe(NavigationFailureType.aborted) @@ -115,24 +127,27 @@ describe('error handling', () => { spyOn(console, 'warn') const err = new Error('foo') const spy1 = jasmine.createSpy('error') - const spy2 = jasmine.createSpy('errpr') + const spy2 = jasmine.createSpy('error') const spy3 = jasmine.createSpy('promise reject') - const Comp = () => { throw err } + const Comp = () => { + throw err + } const router = new VueRouter({ - routes: [ - { path: '/', component: Comp } - ] + routes: [{ path: '/', component: Comp }] }) router.onError(spy1) - router.onReady(() => { }, spy2) - - router.push('/').catch(spy3).finally(() => { - expect(spy1).toHaveBeenCalledWith(err) - expect(spy2).toHaveBeenCalledWith(err) - expect(spy3).toHaveBeenCalled() - expect(console.warn).toHaveBeenCalledTimes(1) - done() - }) + router.onReady(() => {}, spy2) + + router + .push('/') + .catch(spy3) + .finally(() => { + expect(spy1).toHaveBeenCalledWith(err) + expect(spy2).toHaveBeenCalledWith(err) + expect(spy3).toHaveBeenCalled() + expect(console.warn).toHaveBeenCalledTimes(1) + done() + }) }) }) From c05f741cd6428744afa5bf62363af2529f15ac12 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Sun, 7 Jun 2020 20:07:57 +0900 Subject: [PATCH 4/8] fix: update ja docs (#3214) * docs(ja): update NOTE: https://github.com/vuejs/vue-router/commit/fdf5756f15fddf15c18e0269c31f1ca868f6a50d * docs(ja): pick NOTE: https://github.com/vuejs/vue-router/commit/a55ae44f72099395c42af18acf93e131ec1ee560 * docs(ja): pick NOTE: https://github.com/vuejs/vue-router/commit/a8fe4fcecf59b3a25d7dd8796643870f85069e2f * docs(ja): pick NOTE: https://github.com/vuejs/vue-router/commit/039bd8f128b5ad7e7543d4b708db9ddca40bb5f9 * docs(ja): translate * docs(ja): remove NOTE: https://github.com/vuejs/vue-router/commit/41b9ac802eaeb7f7c1bfa2d47b416e8c7202d3fa * docs(ja): update NOTE: https://github.com/vuejs/vue-router/commit/5c5b8abe61631f85ad8c56cb164ac9f3ece86f3e * docs(ja): update NOTE: https://github.com/vuejs/vue-router/commit/e014630002e2d1107b1167b6b56f54d157592aa4 * docs(ja): translate * docs(ja): update NOTE: https://github.com/vuejs/vue-router/commit/23d87d8a7e85d0b54345b812e6863e8d23359051 * docs(ja): update NOTE: https://github.com/vuejs/vue-router/commit/8fdd9c527a5e445de00e0fdd378e42c7a26bd7d7 * docs(ja): pick NOTE: https://github.com/vuejs/vue-router/commit/6ec0ee563898ed513556f589209e8456d54ccd3b * docs(ja): translate * docs(ja): pick NOTE: https://github.com/vuejs/vue-router/commit/f11e531521fdac396877767c68e30ae79ecb5d2c * docs(ja): translate * docs(ja): update NOTE: https://github.com/vuejs/vue-router/commit/231f4a5851372bd653ca6125bc00c025ef0ca77e * docs(ja): add sponsor links * Update docs/ja/api/README.md Co-authored-by: Katashin * Update docs/ja/installation.md Co-authored-by: Katashin * fix: fixed miss take translation Co-authored-by: Katashin --- docs/ja/README.md | 2 + docs/ja/api/README.md | 62 ++++++++++++++++--- docs/ja/guide/README.md | 2 + docs/ja/guide/advanced/data-fetching.md | 4 +- docs/ja/guide/advanced/lazy-loading.md | 2 + docs/ja/guide/advanced/meta.md | 2 + docs/ja/guide/advanced/navigation-guards.md | 23 ++++++- docs/ja/guide/advanced/scroll-behavior.md | 2 + docs/ja/guide/advanced/transitions.md | 2 + docs/ja/guide/essentials/dynamic-matching.md | 2 + docs/ja/guide/essentials/history-mode.md | 6 +- docs/ja/guide/essentials/named-routes.md | 2 + docs/ja/guide/essentials/named-views.md | 2 + docs/ja/guide/essentials/navigation.md | 2 + docs/ja/guide/essentials/nested-routes.md | 2 + docs/ja/guide/essentials/passing-props.md | 2 + .../ja/guide/essentials/redirect-and-alias.md | 4 +- docs/ja/installation.md | 8 +++ 18 files changed, 115 insertions(+), 16 deletions(-) diff --git a/docs/ja/README.md b/docs/ja/README.md index a43edf928..902912f5b 100644 --- a/docs/ja/README.md +++ b/docs/ja/README.md @@ -4,6 +4,8 @@ TypeScriptユーザの場合、 `vue-router@3.0+` は `vue@2.5+` を必須とし、逆もまた同様です。 ::: + + Vue Router は [Vue.js](http://vuejs.org) 公式ルータです。これは Vue.js のコアと深く深く統合されており、Vue.js でシングルページアプリケーションを構築します。機能は次の通りです: - ネストされたルート/ビューマッピング diff --git a/docs/ja/api/README.md b/docs/ja/api/README.md index 657d251fe..720231820 100644 --- a/docs/ja/api/README.md +++ b/docs/ja/api/README.md @@ -16,17 +16,49 @@ sidebar: auto - HTML5 history モードで `base` オプションを使っている時に、 `to` プロパティの URL にそれを含める必要がありません。 -### 外側の要素へのアクティブクラスの適用 +### `v-slot` API (3.1.0 以降) -アクティブクラスを `` タグ自身よりも、外側の要素に対して適用したいことがあるでしょう。その場合、 `` を使って外側の要素を描画して、その内側に生の `` タグをラップすることができます。 +`router-link` は[スコープ付きスロット](https://jp.vuejs.org/v2/guide/components-slots.html#%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E4%BB%98%E3%81%8D%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88)を通して低レベルなカスタマイズを提供しています。これは、主にライブラリ作者をターゲットにした高度な API ですが、ほとんどの場合 _NavLink_ などのようなカスタムコンポーネントでも同様に開発者にとっても大変便利です。 -``` html - - /foo +**`v-slot` API を使うとき、それは単一の子を `router-link` に通す必要がります。**そうしない場合は、 `router-linke` は `span` 要素で子をラップします。 + +```html + + {{ route.fullPath }} + +``` + +- `href`: 解決された url。これは、`a` 要素の `href` 属性になります +- `route`: 解決された正規化済みロケーション +- `navigate`: ナビゲーションをトリガーするための関数。`router-link` と同じように、**必要なときに自動的にイベントが起こらないようにします。** +- `isActive`: [アクティブクラス (active class)](#active-class) が適用されるとき、`true` になります。任意のクラスを適用できます。 +- `isExactActive`: `true` if the [正確なアクティブクラス (exact active class)](#exact-active-class) が適用されるとき、`true` になります。 任意のクラスを適用できます。 + +#### 例: アクティブクラスを外部要素へ適用 + +アクティブクラスを `` タグ自身よりも、外側の要素に対して適用したいことがあるでしょう。その場合、`` 内の要素を `v-slot` を使ってリンクを作成することでラップできます。 + +```html + +
  • + {{ route.fullPath }} +
  • ``` -この時、 `` は実際のリンクになります (そして正しい `href` が得られます)。しかし、アクティブクラスは外側の `
  • ` に適用されます。 +:::tip +`target="_blank"` を `a` 要素に追加する場合、`@click="navigate"` ハンドラを省略しなければなりません。 +::: ## `` Props @@ -112,7 +144,7 @@ sidebar: auto ``` html - + ``` アクティブリンククラスをより説明している例としてこちらの [動作](https://jsfiddle.net/8xrk1n9f/) を確認してください。 @@ -131,6 +163,13 @@ sidebar: auto 完全一致によってリンクがアクティブになっているときに適用されるアクティブな CSS クラスを設定します。デフォルト値は `linkExactActiveClass` ルーターコンストラクタのオプション経由でグローバルに設定することもできます。 +### aria-current-value + +- 型: `'page' | 'step' | 'location' | 'date' | 'time'` +- デフォルト: `"page"` + + 完全一致によってリンクがアクティブになっているときに `aria-current` の値を設定します。ARIA spec において[aria-current で許可されている値](https://www.w3.org/TR/wai-aria-1.2/#aria-current)の1つでなければなりません。ほとんどの場合、デフォルト`page` が最適です。 + ## `` `` コンポーネントは与えられたパスに対してマッチしたコンポーネントを描画する関数型コンポーネントです。`` の中で描画されるコンポーネント自身もまた、ネストされたパスに対してコンポーネントを描画するための `` を持つことができます。 @@ -164,8 +203,8 @@ name ではないプロパティも描画されるコンポーネントに渡さ `RouteConfig` の型宣言: - ``` js - declare type RouteConfig = { + ``` ts + interface RouteConfig = { path: string; component?: Component; name?: string; // 名前付きルート用 @@ -313,7 +352,9 @@ router.afterEach((to, from) => {}) ``` js router.push(location, onComplete?, onAbort?) +router.push(location).then(onComplete).catch(onAbort) router.replace(location, onComplete?, onAbort?) +router.replace(location).then(onComplete).catch(onAbort) router.go(n) router.back() router.forward() @@ -462,7 +503,8 @@ router.onError(callback) const router = new VueRouter({ routes: [ // 以下のオブジェクトがルートレコード - { path: '/foo', component: Foo, + { path: '/foo', + component: Foo, children: [ // こちらもルートレコード { path: 'bar', component: Bar } diff --git a/docs/ja/guide/README.md b/docs/ja/guide/README.md index 3baef4c13..0a1317503 100644 --- a/docs/ja/guide/README.md +++ b/docs/ja/guide/README.md @@ -6,6 +6,8 @@ すべての example では、vue の完全バージョンを使用してテンプレートを解析可能にしています。詳細は[こちら](https://jp.vuejs.org/v2/guide/installation.html#ランタイム-コンパイラとランタイム限定の違い)を参照してください。 ::: + + Vue.js と vue-router を使ったシングルページアプリケーションの構築は驚くほど簡単です。Vue.js のコンポーネントを使ってアプリケーションを既に構成しています。vue-router を混ぜ込むには、コンポーネントとルートをマッピングさせて vue-router にどこで描画するかを知らせるだけです。以下が基本的な例です。 ## HTML diff --git a/docs/ja/guide/advanced/data-fetching.md b/docs/ja/guide/advanced/data-fetching.md index 22244af65..e337b4fb1 100644 --- a/docs/ja/guide/advanced/data-fetching.md +++ b/docs/ja/guide/advanced/data-fetching.md @@ -1,5 +1,7 @@ # データ取得 + + ルートが有効化された時にサーバーからデータを取得する必要がしばしばあります。例えば、ユーザープロフィールを描画する前に、サーバーからユーザーデータを取得する必要があります。これを実現するためには 2 種類の方法があります。 - **ナビゲーション後の取得**: ナビゲーションを先に実行し、その後次に入ってくるコンポーネントのライフサイクルフック内でデータを取得します。データ取得中にローディングを表示します。 @@ -17,7 +19,7 @@ ``` html