@@ -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