Skip to content

Commit 3f44fb9

Browse files
committed
docs: Adding useStore and useRouter examples
1 parent e9e3ee2 commit 3f44fb9

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed

README.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,209 @@ Vue.use(VueCompositionAPI)
144144
- [@vue/composition-api](https://github.com/vuejs/composition-api)
145145
- [@vue/test-utils](https://vue-test-utils.vuejs.org/)
146146
- [Jest](https://jestjs.io/)
147+
148+
## 🎁 Other examples of composition API functions
149+
150+
Some Vue composition API functions have not been included in this library but
151+
can be created easily by following the steps below.
152+
153+
<details><summary>useStore</summary><p>
154+
Creating a useStore function connected to Vuex store is pretty straightforward.
155+
First we have to export our Vuex store:
156+
157+
```typescript
158+
// @src/mystore.ts
159+
import Vue from 'vue'
160+
import Vuex from 'vuex'
161+
162+
Vue.use(Vuex)
163+
164+
const store = new Vuex.Store({
165+
state: { searchTerm: '' },
166+
mutations: {
167+
SET_SEARCH(state, newVal) {
168+
state.searchTerm = newVal
169+
}
170+
},
171+
getters: { searchTerm: state => state.searchTerm },
172+
actions: {},
173+
modules: {}
174+
})
175+
176+
export default store
177+
```
178+
179+
Then we import the store and expose it in useStore function:
180+
181+
```typescript
182+
// @src/useStore.ts
183+
import store from '@src/mystore'
184+
185+
export function useStore() {
186+
return store
187+
}
188+
```
189+
190+
Now we can use it inside the setup() method of our component:
191+
192+
```html
193+
// MyComponent.vue
194+
<template>
195+
<input type="text" v-model="searchTerm" placeholder="🔎 Search..." />
196+
</template>
197+
198+
<script lang="ts">
199+
import Vue from 'vue'
200+
import { ref, watch } from '@src/api'
201+
import { useStore } from '@src/useStore'
202+
203+
export default Vue.extend({
204+
name: 'UseStoreDemo',
205+
setup() {
206+
const { commit, getters } = useStore()
207+
const searchTerm = ref(getters['searchTerm'])
208+
watch(searchTerm, newVal => commit('SET_SEARCH', newVal))
209+
return { searchTerm }
210+
}
211+
})
212+
</script>
213+
```
214+
215+
</p></details>
216+
217+
<details><summary>useRouter</summary><p>
218+
Creating a useRouter function that exposes `this.$router` and `this.$route` from VueRouter is very easy.
219+
First we have to export the Vue's `vm` instance:
220+
221+
```typescript
222+
// @src/main.ts
223+
import VueCompositionAPI from '@src/api'
224+
import router from '@src/router'
225+
import App from '@src/App.vue'
226+
227+
Vue.use(VueCompositionAPI)
228+
229+
export const vm = new Vue({
230+
router,
231+
render: h => h(App)
232+
}).$mount('#app')
233+
```
234+
235+
Then we can expose `$router` and `$route` in our useRouter function:
236+
237+
```typescript
238+
// @src/useRouter.ts
239+
import { vm } from '@src/main'
240+
241+
export function useRouter() {
242+
const route = vm.$route
243+
const router = vm.$router
244+
return { route, router }
245+
}
246+
```
247+
248+
Now we can use it inside the setup() method of our component:
249+
250+
```html
251+
// MyComponent.vue
252+
<template>
253+
<div>
254+
Current id: {{ id }}
255+
</div>
256+
</template>
257+
258+
<script lang="ts">
259+
import Vue from 'vue'
260+
import { useRouter } from '@src/useRouter'
261+
262+
export default Vue.extend({
263+
name: 'UseRouterDemo',
264+
setup() {
265+
const { route } = useRouter()
266+
return { id: route.params.id }
267+
}
268+
})
269+
</script>
270+
```
271+
272+
Note that a drawback of this useRouter example is that it may be difficult to test since when we define `localVue`
273+
the `vm` instance is going to be different from the one we exported from `@src/main`.
274+
275+
To fix this we have to create a small runtime utility function:
276+
277+
```typescript
278+
// @src/runtimeHelper.ts
279+
const runtime = {};
280+
281+
export const runtimeHelper {
282+
set(vm) {
283+
runtime.vm = vm;
284+
},
285+
get() {
286+
if (runtime.vm) return runtime.vm;
287+
throw new ReferenceError("Vue instance not found.");
288+
}
289+
}
290+
```
291+
292+
Then we have to get the `vm` on runtime:
293+
294+
```typescript
295+
// @src/main.ts
296+
import Vue from 'vue'
297+
import VueCompositionAPI from '@src/api'
298+
import { runtimeHelper } from '@src/runtimeHelper'
299+
import App from '@src/App.vue'
300+
import router from '@src/router'
301+
302+
Vue.use(VueCompositionAPI)
303+
304+
new Vue({
305+
router,
306+
beforeCreate() {
307+
// Set the runtime so that we can access the vm from anywhere
308+
runtimeHelper.set(this)
309+
},
310+
render: h => h(App)
311+
}).$mount('#app')
312+
```
313+
314+
Now in the useRouter function we can get the `vm` on runtime:
315+
316+
```typescript
317+
// @src/useRouter.ts
318+
import { runtimeHelper } from '@src/runtimeHelper'
319+
320+
export function useRouter() {
321+
const vm = runtimeHelper.get()
322+
const route = vm.$route
323+
const router = vm.$router
324+
return { route, router }
325+
}
326+
```
327+
328+
Finally, we can test the router easily by passing the right `vm` on runtime:
329+
330+
```typescript
331+
// @src/mytest.ts
332+
import VueRouter from 'vue-router'
333+
import { createLocalVue, mount } from '@vue/test-utils'
334+
import VueCompositionAPI from '@src/api'
335+
import { runtimeHelper } from '@src/runtimeHelper'
336+
import router from '@src/router'
337+
338+
const localVue = createLocalVue()
339+
localVue.use(VueCompositionAPI)
340+
localVue.use(VueRouter)
341+
342+
mount(localVue.extend(ComponentHere), {
343+
localVue,
344+
router,
345+
beforeCreate() {
346+
// Set the runtime so that we can access the vm from anywhere
347+
runtimeHelper.set(this)
348+
}
349+
})
350+
```
351+
352+
</p></details>

0 commit comments

Comments
 (0)