Vue 3 Router

一個 Storybook 裝飾器,讓您為具路由功能的元件建立 stories。

在 Github 上檢視

Storybook Vue3 Router

minified + gzip size Npm package monthly downloads Release CodeFactor Storybook

一個 Storybook 裝飾器,讓您可以使用您的 Vue 3 具路由功能的元件。

如果您想使用 <router-view><router-link> 為 Vue 3 元件建立 stories,那麼您需要使用 vue-router 包裹您的 stories,這個擴充功能將讓您輕鬆完成此操作。

對於只需要存取 $route$router 屬性的使用者,還有一個 模擬路由器裝飾器 選項。

如何使用

這個裝飾器適用於 Storybook 的 Component Story Format (CSF)hoisted CSF annotations,這是自 Storybook 6 以來推薦的撰寫 stories 方式。它尚未在 storiesOf API 中進行測試。

Storybook v6:請使用套件版本 2.x

Storybook v7:請使用套件版本 3+

請參閱 遷移指南

安裝裝飾器

npm install --save-dev storybook-vue3-router
// or
yarn add --dev storybook-vue3-router

在您的 stories 中使用

預設設定將建立一個 vue-router 實例,其中包含 2 個路由(//about) - 這些可以在 defaultRoutes.ts 檔案中檢視。

/* import storybook-vue3-router */
import { vueRouter } from 'storybook-vue3-router'

/* ...story setup... */

/* your story export */
export const Default = Template.bind({})

/* adding storybook-vue3-router decorator */
Default.decorators = [
  /* this is the basic setup with no params passed to the decorator */
  vueRouter()
]

範例

您可以在這個 demo 上看到發布的 範例 stories

進階使用

此裝飾器帶有可選參數,用於自訂 Storybook 中 vue-router 的實作。

自訂路由

/* define our custom routes */
const customRoutes = [
  {
    path: '/',
    name: 'home',
    component: HomeComponent // this would need to be defined/imported into the `.stories` file
  },
  {
    path: '/about',
    name: 'about',
    component: AboutComponent // this would need to be defined/imported into the `.stories` file
  }
]

/* adding storybook-vue3-router decorator */
Default.decorators = [
  /* pass custom routes to the decorator */
  vueRouter(customRoutes)
]

自訂路由(帶有守衛)

/* define our custom routes */
const customRoutes = [
  // ...
  {
    path: '/admin',
    name: 'admin',
    component: AdminComponent,
    /* add per-route navigation guard */
    beforeEnter: (to, from, next) => {
      // ...
    }
  }
]

/* adding storybook-vue3-router decorator */
Default.decorators = [
  /* pass custom routes to the decorator */
  vueRouter(customRoutes)
]

自訂路由(帶有初始路由)

預設情況下,裝飾器會將起始路由預設為 /,如果您想變更此設定,可以作為參數傳遞給裝飾器

/* define our custom routes */
const customRoutes = [
  {
    path: '/',
    name: 'dashboard',
    component: Dashboard
  },
  {
    path: '/intro',
    name: 'intro',
    component: Intro
  }
]

### With Router Options
We can pass [Vue Router options](https://router.vuejs.org/api/index.html#history) into our decorator.

```typescript
/* adding storybook-vue3-router decorator */
Default.decorators = [
  /* pass vueRouterOptions to the decorator */
  vueRouter(undefined, {
    vueRouterOptions: {
      linkActiveClass: 'my-active-class',
      linkExactActiveClass: 'my-exact-active-class'
      ...etc
    }
  })
]

router.isReady()

如果您使用 router.isReady() 設置了路由器,和/或您的元件需要在建立生命週期掛鉤上具有特定的路由/路由數據,您可能需要使用 asyncVueRouter 導出。

此導出提供路由器,直到路由器準備好才會渲染 story。

Story 設定

import { asyncVueRouter } from 'storybook-vue3-router'

/* define our custom routes */
const customRoutes = [
  {
    path: '/',
    name: 'dashboard',
    component: Dashboard
  },
  {
    path: '/intro',
    name: 'intro',
    component: Intro
  }
]

/* adding storybook-vue3-router decorator */
Default.decorators = [
  /* pass initialRoute to the decorator */
  asyncVueRouter(customRoutes, {
    initialRoute: '/intro'
  })
]

Preview.js 異步設定

為了使用 async 路由器設定方法,您需要修改您的 .storybook/preview.js 檔案,以使用 Vue 3 的 <Suspense> 元件包裹 stories。這是因為裝飾器需要一個 async setup() 才能正確地 await router.isReady()。您可以將預覽修改為

const preview = {
  decorators: [
    (story) => ({
      components: { story },
      template: '<Suspense><story /></Suspense>',
    }),
  ],
};

export default preview;

有關更進階的使用方式,請參閱 範例資料夾

裝飾器參數


function vueRouter(routes: RouteRecordRaw[], options?: { initialRoute?: string, beforeEach?: NavigationGuard, vueRouterOptions?: RouterOptions })
function asyncVueRouter(routes: RouteRecordRaw[], options?: { initialRoute?: string, beforeEach?: NavigationGuard, vueRouterOptions?: RouterOptions })

模擬路由器

並非總是需要完整的 vue-router - 例如,如果您沒有使用 <router-view><router-link> 的元件,則使用 mockRouter 導出可能會滿足您的需求(並減少您的 stories 中使用的導入)。

注意:mockRouter 僅適用於使用選項 API this.$route 和/或 this.$router 的情況,不適用於使用 vue router composables(例如 useRoute()useRouter())的使用案例。

在您的 stories 中使用 mockRouter

預設設定將從 vue-router 建立模擬的 $router$route,這讓您可以為使用程式化導航和基於路由邏輯的元件建立 stories。

我們也可以將自訂選項傳遞到 mockRouter 裝飾器中

{ 
  meta?: Array<string>, 
  params?: Array<string>, 
  query?: Array<string>
}
/* import storybook-vue3-router mockRouter */
import { mockRouter } from 'storybook-vue3-router'

/* ...story setup... */

/* your story export */
export const Default = Template.bind({})

/* adding storybook-vue3-router mockRouter decorator */
Default.decorators = [
  mockRouter({
    meta: ['some_meta'],
    params: ['some_param'],
    query: ['some_query']
  })
]

您可以在我們的 storybook demo 網站和我們的 程式碼範例中看到 mockRouter 的範例

v2.x > v3+ 遷移

⚠️ 重大變更 ⚠️

v3.x 版本不再對 vueRouter 裝飾器使用預設匯出,您需要更新為使用具名匯入

/* DONT */
import vueRouter from 'storybook-vue3-router'
/* DO */
import { vueRouter } from 'storybook-vue3-router'

v1.x > v2.x 遷移

從 v1 的遷移帶來了一些重大變更

// v1.x - 2nd param is used to pass `beforeEach` router guard
// in this example the guard is used to fire a storybook action with `to` and `from` router objects
vueRouter(customRoutes, (to, from) => action('ROUTE CHANGED')({ to: to, from: from })) // LEGACY

// v2.1 - 2nd param is used to pass additional options to the decorator
vueRouter(customRoutes, {
  /* add global beforeEach guard */
  beforeEach: (to, from) => action('ROUTE CHANGED')({ to: to, from: from })
})

如果您先前在第二個參數中使用 v1 的路由守衛,則需要將其重構為使用 路由特定路由守衛 (建議),或者您可以使用 beforeEach 選項傳遞您的全域路由守衛。

v2.0 沒有此 beforeEach 選項,請升級到 v2.1

⚠️ 警告

當使用全域 beforeEach 選項時,如果現有的 story 也使用此裝飾器,則我們必須強制重新載入頁面,才能設定特定的 story 路由守衛,這會對 UX/效能產生輕微影響。請查看 demo 以取得此範例:README > 使用路由守衛 > 全域守衛 - 當點擊「全域守衛」連結時,您會注意到頁面已重新整理以套用全域守衛(由於先前存在 stories)。

如果您僅將此裝飾器用於一個 story,則不會有這個問題。

在解決 此問題後,為了讓可以使用不同的路由設定建立多個 stories,發現這會導致全域 beforeEach 函數被新增到每個路由上。例如,每次您點擊不同的 story 時,都會新增新的 beforeEach 掛鉤 - 但不會移除先前的掛鉤,這會導致多個守衛在與「作用中」story 無關的 stories 上觸發。

  • nickmcburney
    nickmcburney 製作
適用於
    Vue
標籤