Skip to content

Commit

Permalink
feat: add useRoute, useRouter and useStore wrapper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Feb 9, 2021
1 parent 6484e97 commit 80e6c08
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 3 deletions.
38 changes: 38 additions & 0 deletions docs/content/en/packages/routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: useRoute, useRouter
description: 'Access this.$route and this.$router with the Nuxt Composition API.'
category: Packages
position: 12
---

In Vue 3, `vue-router` exports composition functions for accessing the current route and router.

These helpers provide an equivalent while using Nuxt 2

## useRoute

Returns `this.$route`.

```ts
import { defineComponent, useRoute } from '@nuxtjs/composition-api'

export default defineComponent({
setup() {
const route = useRoute()
}
})
```

## useRouter

Returns `this.$router`.

```ts
import { defineComponent, useRoute } from '@nuxtjs/composition-api'

export default defineComponent({
setup() {
const router = useRouter()
}
})
```
42 changes: 42 additions & 0 deletions docs/content/en/packages/store.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: useStore
description: 'Access this.$store with the Nuxt Composition API.'
category: Packages
badge: migration
position: 12
---

Vuex v4 [provides a helper function](https://next.vuex.vuejs.org/api/#usestore) for accessing it within the Composition API. This helper provides an equivalent while using Nuxt 2

## useStore

Returns `this.$store`.

```ts
import { defineComponent, useStore } from '@nuxtjs/composition-api'

export default defineComponent({
setup() {
const store = useStore()
}
})
```

You can also provide an injection key to get back a semi-typed store:

```ts
import { defineComponent, useStore } from '@nuxtjs/composition-api'

export interface State {
count: number
}

export const key: InjectionKey<Store<State>> = Symbol()

export default defineComponent({
setup() {
const store = useStore(key)
// store.state.count will be typed as a number
}
})
```
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: useMeta
description: '@nuxtjs/composition-api provides a way to use the Vue 3 Composition API with Nuxt-specific features.'
category: Helpers
description: 'You can define your head and meta properties with the Nuxt Composition API.'
category: Packages
fullscreen: True
position: 18
position: 10
---

You can interact directly with [head properties](https://nuxtjs.org/api/pages-head/) in `setup` (and within the `onGlobalSetup` method) by means of the `useMeta()` helper.
Expand Down
1 change: 1 addition & 0 deletions src/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { reqRef, reqSsrRef } from './req-ref'
export { ssrRef, shallowSsrRef, setSSRContext, ssrPromise } from './ssr-ref'
export { useStatic } from './static'
export * from './defineHelpers'
export * from './wrappers'

export type {
ComponentInstance,
Expand Down
35 changes: 35 additions & 0 deletions src/wrappers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { InjectionKey } from '@vue/composition-api'
import type { Store } from 'vuex'

import { getCurrentInstance } from './utils'

const wrapProperty = (
property: keyof NonNullable<ReturnType<typeof getCurrentInstance>>
) => {
return () => {
const vm = getCurrentInstance()
if (!vm) throw new Error('This must be called within a setup function.')

return vm[property]
}
}

/**
* Gain access to the router just like using this.$router in a non-Composition API manner.
*/
export const useRouter = wrapProperty('$router')

/**
* Gain access to the route just like using this.$route in a non-Composition API manner.
*/
export const useRoute = wrapProperty('$route')

/**
* Gain access to the store just like using this.$store in a non-Composition API manner.
*/
export const useStore = <S>(key?: InjectionKey<S>): Store<S> => {
const vm = getCurrentInstance()
if (!vm) throw new Error('This must be called within a setup function.')

return vm.$store
}
21 changes: 21 additions & 0 deletions test/e2e/wrappers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Selector } from 'testcafe'
import { navigateTo, expectOnPage, expectPathnameToBe } from './helpers'

// eslint-disable-next-line
fixture`Wrappers`

test('Shows data on ssr-loaded page', async () => {
await navigateTo('/wrappers')
await expectOnPage('store: true')
await expectOnPage('route: true')
await expectOnPage('router: true')
})

test('Shows appropriate data on client-loaded page', async t => {
await navigateTo('/')
await t.click(Selector('a').withText('wrappers'))
await expectPathnameToBe('/wrappers')
await expectOnPage('store: true')
await expectOnPage('route: true')
await expectOnPage('router: true')
})
1 change: 1 addition & 0 deletions test/fixture/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<nuxt-link to="/no-setup">ssr ref defined outside of setup</nuxt-link>
</li>
<li><nuxt-link to="/meta">meta</nuxt-link></li>
<li><nuxt-link to="/wrappers">wrappers</nuxt-link></li>
</ul>
<div>
TTFB: {{ ttfb }}ms
Expand Down
28 changes: 28 additions & 0 deletions test/fixture/pages/wrappers.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<blockquote>
<p>
<code>store: {{ storeExists }}</code>
<code>route: {{ routeExists }}</code>
<code>router: {{ routerExists }}</code>
</p>
</blockquote>
</template>

<script>
import {
defineComponent,
useRoute,
useRouter,
useStore,
} from '@nuxtjs/composition-api'
export default defineComponent({
setup() {
return {
routeExists: !!useRoute(),
routerExists: !!useRouter(),
storeExists: !!useStore(''),
}
},
})
</script>
1 change: 1 addition & 0 deletions test/fixture/store/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const state = () => ({})

0 comments on commit 80e6c08

Please sign in to comment.