Skip to content

Commit 109995a

Browse files
committed
feat(hooks): add useStore hook
1 parent 5420fee commit 109995a

File tree

6 files changed

+148
-17
lines changed

6 files changed

+148
-17
lines changed

src/__tests__/useStore.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Store } from 'vuex';
2+
import useStore from '../useStore';
3+
import renderHook from '../util/renderHook';
4+
5+
declare module 'vue/types/vue' {
6+
interface Vue {
7+
store: Store<any>;
8+
}
9+
}
10+
11+
describe('useStore', () => {
12+
it('should be defined', () => {
13+
expect(useStore).toBeDefined();
14+
});
15+
16+
it('should have store property', () => {
17+
const { vm } = renderHook((context) => ({ store: useStore(context) }));
18+
expect(vm).toHaveProperty('store');
19+
});
20+
21+
it('should update store', () => {
22+
const { vm } = renderHook((context) => ({ store: useStore(context) }));
23+
expect(vm.store.state.count).toBe(0);
24+
expect(vm.store.getters.plusOne).toBe(1);
25+
expect(vm.store.state.test.count).toBe(0);
26+
expect(vm.store.getters['test/minusOne']).toBe(-1);
27+
28+
vm.store.commit('increment');
29+
vm.store.commit('test/decrement');
30+
31+
expect(vm.store.state.count).toBe(1);
32+
expect(vm.store.getters.plusOne).toBe(2);
33+
expect(vm.store.state.test.count).toBe(-1);
34+
expect(vm.store.getters['test/minusOne']).toBe(-2);
35+
36+
vm.store.dispatch('incrementAsync', 0);
37+
vm.store.dispatch('test/decrementAsync', 0);
38+
39+
expect(vm.store.state.count).toBe(1);
40+
expect(vm.store.getters.plusOne).toBe(2);
41+
expect(vm.store.state.test.count).toBe(-1);
42+
expect(vm.store.getters['test/minusOne']).toBe(-2);
43+
44+
setTimeout(() => {
45+
expect(vm.store.state.count).toBe(2);
46+
expect(vm.store.getters.plusOne).toBe(3);
47+
expect(vm.store.state.test.count).toBe(-2);
48+
expect(vm.store.getters['test/minusOne']).toBe(-3);
49+
}, 0);
50+
});
51+
});

src/mocks/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Router from './router';
2+
import Store from './store';
3+
4+
export { Router, Store };

src/mocks/router.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { VueConstructor } from 'vue';
2+
import VueRouter from 'vue-router';
3+
4+
export default function register(localVue: VueConstructor) {
5+
localVue.use(VueRouter);
6+
return new VueRouter({
7+
routes: [
8+
{
9+
path: '/',
10+
name: 'index',
11+
meta: { title: 'Vue Hooks' },
12+
},
13+
{
14+
path: '*',
15+
name: '404',
16+
meta: { title: '404 - Not Found' },
17+
},
18+
],
19+
});
20+
}

src/mocks/store.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { VueConstructor } from 'vue';
2+
import Vuex, { Module } from 'vuex';
3+
4+
export interface CounterState {
5+
count: number;
6+
}
7+
8+
export default function register(localVue: VueConstructor) {
9+
localVue.use(Vuex);
10+
return new Vuex.Store<CounterState>({
11+
state: {
12+
count: 0,
13+
},
14+
15+
actions: {
16+
incrementAsync(context, delay = 1000) {
17+
setTimeout(() => {
18+
context.commit('increment');
19+
}, delay);
20+
},
21+
},
22+
23+
mutations: {
24+
increment(state) {
25+
Object.assign(state, { count: state.count + 1 });
26+
},
27+
},
28+
29+
getters: {
30+
plusOne: (state) => state.count + 1,
31+
},
32+
33+
modules: {
34+
test: {
35+
namespaced: true,
36+
37+
state: {
38+
count: 0,
39+
},
40+
41+
actions: {
42+
decrementAsync(context, delay = 1000) {
43+
setTimeout(() => {
44+
context.commit('decrement');
45+
}, delay);
46+
},
47+
},
48+
49+
mutations: {
50+
decrement(state) {
51+
Object.assign(state, { count: state.count - 1 });
52+
},
53+
},
54+
55+
getters: {
56+
minusOne: (state) => state.count - 1,
57+
},
58+
} as Module<CounterState, CounterState>,
59+
},
60+
});
61+
}

src/useStore.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { computed } from 'vue-function-api';
2+
import { Store } from 'vuex';
3+
import withContext from './util/withContext';
4+
5+
export default withContext(function useStore<TState>(vue) {
6+
const store = computed(() => vue.$store as Store<TState>);
7+
return store;
8+
});

src/util/renderHook.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,14 @@
11
/* eslint import/no-extraneous-dependencies: off */
22
import { shallowMount, createLocalVue } from '@vue/test-utils';
33
import { plugin, createComponent } from 'vue-function-api';
4-
import VueRouter from 'vue-router';
4+
import { Router, Store } from '../mocks';
55

66
const localVue = createLocalVue();
7+
const router = Router(localVue);
8+
const store = Store(localVue);
79

8-
localVue.use(VueRouter);
910
localVue.use(plugin);
1011

11-
const router = new VueRouter({
12-
routes: [
13-
{
14-
path: '/',
15-
name: 'index',
16-
meta: { title: 'Vue Hooks' },
17-
},
18-
{
19-
path: '*',
20-
name: '404',
21-
meta: { title: '404 - Not Found' },
22-
},
23-
],
24-
});
25-
2612
export default function renderHook(hook: Function) {
2713
const App = createComponent({
2814
template: `
@@ -39,6 +25,7 @@ export default function renderHook(hook: Function) {
3925
return shallowMount(App, {
4026
localVue,
4127
router,
28+
store,
4229
stubs: ['router-view'],
4330
});
4431
}

0 commit comments

Comments
 (0)