Gathering detailed insights and metrics for storybook-vue3-router
Gathering detailed insights and metrics for storybook-vue3-router
Gathering detailed insights and metrics for storybook-vue3-router
Gathering detailed insights and metrics for storybook-vue3-router
A Storybook decorator that allows you to use Vue 3 / vue-router@4 routing-aware components.
npm install storybook-vue3-router
Typescript
Module System
Node Version
NPM Version
53.1
Supply Chain
81.4
Quality
75.3
Maintenance
100
Vulnerability
99.3
License
TypeScript (90.78%)
JavaScript (7.69%)
HTML (1.52%)
Total Downloads
3,459,651
Last Day
1,434
Last Week
46,385
Last Month
191,072
Last Year
2,087,828
29 Stars
233 Commits
8 Forks
3 Watching
5 Branches
6 Contributors
Minified
Minified + Gzipped
Latest Version
5.0.0
Package Id
storybook-vue3-router@5.0.0
Unpacked Size
60.96 kB
Size
10.26 kB
File Count
8
NPM Version
8.19.2
Node Version
18.12.1
Publised On
04 Dec 2023
Cumulative downloads
Total Downloads
Last day
63%
1,434
Compared to previous day
Last week
-2.9%
46,385
Compared to previous week
Last month
-9.2%
191,072
Compared to previous month
Last year
107.1%
2,087,828
Compared to previous year
1
4
26
A Storybook decorator that allows you to use your Vue 3 routing-aware components.
If you want to build stories for Vue 3 components using <router-view>
or <router-link>
then you need to wrap your stories with vue-router
this addon will allow for you to easily do this.
There is also a mocked router decorator option for users who only need access to $route
and $router
properties.
This decorator works with Storybook's Component Story Format (CSF) and hoisted CSF annotations, which is the recommended way to write stories since Storybook 6. It has not been tested with the storiesOf API.
See migration guides.
1npm install --save-dev storybook-vue3-router 2// or 3yarn add --dev storybook-vue3-router
The default setup will create a vue-router
instance, with 2 routes (/
and /about
) - these can be reviewed in the defaultRoutes.ts file.
1/* import storybook-vue3-router */ 2import { vueRouter } from 'storybook-vue3-router' 3 4/* ...story setup... */ 5 6/* your story export */ 7export const Default = Template.bind({}) 8 9/* adding storybook-vue3-router decorator */ 10Default.decorators = [ 11 /* this is the basic setup with no params passed to the decorator */ 12 vueRouter() 13]
You can see the examples stories published on this demo.
This decorator comes with optioal params for customising the implementation of your vue-router
within Storybook.
1/* define our custom routes */ 2const customRoutes = [ 3 { 4 path: '/', 5 name: 'home', 6 component: HomeComponent // this would need to be defined/imported into the `.stories` file 7 }, 8 { 9 path: '/about', 10 name: 'about', 11 component: AboutComponent // this would need to be defined/imported into the `.stories` file 12 } 13] 14 15/* adding storybook-vue3-router decorator */ 16Default.decorators = [ 17 /* pass custom routes to the decorator */ 18 vueRouter(customRoutes) 19]
1/* define our custom routes */ 2const customRoutes = [ 3 // ... 4 { 5 path: '/admin', 6 name: 'admin', 7 component: AdminComponent, 8 /* add per-route navigation guard */ 9 beforeEnter: (to, from, next) => { 10 // ... 11 } 12 } 13] 14 15/* adding storybook-vue3-router decorator */ 16Default.decorators = [ 17 /* pass custom routes to the decorator */ 18 vueRouter(customRoutes) 19]
By default the decorator will default the starting route to /
, if you want to change this you can pass as a paramtor to the decorator
1/* define our custom routes */ 2const customRoutes = [ 3 { 4 path: '/', 5 name: 'dashboard', 6 component: Dashboard 7 }, 8 { 9 path: '/intro', 10 name: 'intro', 11 component: Intro 12 } 13] 14 15### With Router Options 16We can pass [Vue Router options](https://router.vuejs.org/api/index.html#history) into our decorator. 17 18```typescript 19/* adding storybook-vue3-router decorator */ 20Default.decorators = [ 21 /* pass vueRouterOptions to the decorator */ 22 vueRouter(undefined, { 23 vueRouterOptions: { 24 linkActiveClass: 'my-active-class', 25 linkExactActiveClass: 'my-exact-active-class' 26 ...etc 27 } 28 }) 29]
router.isReady()
If you have a router setup using router.isReady()
and / or you have components which require specific route / route data on created lifecycle hook you may need to use the asyncVueRouter
export.
This export provides router which won't render story until router is ready.
1import { asyncVueRouter } from 'storybook-vue3-router' 2 3/* define our custom routes */ 4const customRoutes = [ 5 { 6 path: '/', 7 name: 'dashboard', 8 component: Dashboard 9 }, 10 { 11 path: '/intro', 12 name: 'intro', 13 component: Intro 14 } 15] 16 17/* adding storybook-vue3-router decorator */ 18Default.decorators = [ 19 /* pass initialRoute to the decorator */ 20 asyncVueRouter(customRoutes, { 21 initialRoute: '/intro' 22 }) 23]
In order to use async
router setup method, you will need to amend your .storybook/preview.js file to wrap stories in Vue 3's <Suspense>
component. This is because the decorator requires an async setup()
to correctly await router.isReady()
. You can modify preview to:
1const preview = { 2 decorators: [ 3 (story) => ({ 4 components: { story }, 5 template: '<Suspense><story /></Suspense>', 6 }), 7 ], 8}; 9 10export default preview;
See the examples folder for more advanced usage.
1 2function vueRouter(routes: RouteRecordRaw[], options?: { initialRoute?: string, beforeEach?: NavigationGuard, vueRouterOptions?: RouterOptions }) 3function asyncVueRouter(routes: RouteRecordRaw[], options?: { initialRoute?: string, beforeEach?: NavigationGuard, vueRouterOptions?: RouterOptions })
The full vue-router
is not always needed - for example if you don't have components using <router-view>
or <router-link>
then using the mockRouter
export may cover your needs (and reduce the imports being used in your stories).
Note: mockRouter
will only work in instances where you are using options API this.$route
and/or this.$router
, it is not suitable for use-cases using vue router composables such as useRoute()
and useRouter()
.
mockRouter
in your storiesThe default setup will create mock $router
and $route
from vue-router
, this allows you to create stories for components using programatic navigation and route based logic.
We can also pass custom options into the mockRouter
decorator:
1{ 2 meta?: Array<string>, 3 params?: Array<string>, 4 query?: Array<string> 5}
1/* import storybook-vue3-router mockRouter */ 2import { mockRouter } from 'storybook-vue3-router' 3 4/* ...story setup... */ 5 6/* your story export */ 7export const Default = Template.bind({}) 8 9/* adding storybook-vue3-router mockRouter decorator */ 10Default.decorators = [ 11 mockRouter({ 12 meta: ['some_meta'], 13 params: ['some_param'], 14 query: ['some_query'] 15 }) 16]
You can see examples of the mockRouter
in our storybook demo site, and our code examples
v3.x version no longer uses default export for vueRouter
decorator, you will need to update to using named import:
1/* DONT */ 2import vueRouter from 'storybook-vue3-router' 3/* DO */ 4import { vueRouter } from 'storybook-vue3-router'
The migration from v1 brings some breaking changes:
1// v1.x - 2nd param is used to pass `beforeEach` router guard 2// in this example the guard is used to fire a storybook action with `to` and `from` router objects 3vueRouter(customRoutes, (to, from) => action('ROUTE CHANGED')({ to: to, from: from })) // LEGACY 4 5// v2.1 - 2nd param is used to pass additional options to the decorator 6vueRouter(customRoutes, { 7 /* add global beforeEach guard */ 8 beforeEach: (to, from) => action('ROUTE CHANGED')({ to: to, from: from }) 9})
If you were previously using v1 with router guards in the second parameter, these will need to be refactored to use the route specific router guards (recommended) or you can pass your global route guards using the beforeEach
option.
v2.0 DOES NOT HAVE THIS beforeEach
option, please upgrade to v2.1
When using the global beforeEach
option, if there is an existing story also using this decorator then we must force a page reload in order to setup the specific story router guard and this has a minor UX / performance impact. Checkout the demo for an example of this: README > With Router Guards > Global Guard - when clicking the 'Global Guard' link you will notice the page is refreshed to apply global guards (due to previously existing stories).
This will not be an issue if you are using this decorator for just one story.
After resolving this issue, to enable multiple stories to be created using different route setups, it was noticed that this caused the global beforeEach
function to be added on every route. For example every time you click a different story the new beforeEach
hook is added - but previous ones are not removed, this results in multiple guards firing on stories unrelated to the 'active' story.
No vulnerabilities found.
No security vulnerabilities found.