Skip to content

Commit

Permalink
feat: expose providePinia to use multiple root stores
Browse files Browse the repository at this point in the history
  • Loading branch information
bodograumann committed Dec 6, 2021
1 parent eaed48a commit ee7911b
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
98 changes: 98 additions & 0 deletions packages/pinia/__tests__/multipleRoots.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { createPinia, defineStore, providePinia } from '../src'
import { mount } from '@vue/test-utils'
import { defineComponent } from 'vue'

describe('Multiple Roots', () => {
function defineMyStore() {
return defineStore({
id: 'main',
state: () => ({
n: 0,
}),
})
}

it('uses the same root in child components by default', () => {
expect.assertions(2)
const pinia = createPinia()
const useStore = defineMyStore()

const ChildComponent = defineComponent({
template: 'no',
setup() {
const store = useStore()
expect(store.n).toBe(1)
},
})

mount(
{
template: '<ChildComponent />',
components: { ChildComponent },
setup() {
const store = useStore()
expect(store.n).toBe(0)
store.n++
},
},
{ global: { plugins: [pinia] } }
)
})

it('can use a new pinia root for all child components', async () => {
expect.assertions(2)
const pinia = createPinia()
const useStore = defineMyStore()

const ChildComponent = defineComponent({
template: 'no',
setup() {
const store = useStore()
expect(store.n).toBe(0)
},
})
mount(
{
template: '<ChildComponent />',
components: { ChildComponent },
setup() {
providePinia(createPinia())
const store = useStore()
expect(store.n).toBe(0)
store.n++
},
},
{ global: { plugins: [pinia] } }
)
})

it('state is shared between child components', async () => {
expect.assertions(3)
const pinia = createPinia()
const useStore = defineMyStore()

const ChildComponent = defineComponent({
template: 'no',
props: { counter: { type: Number, required: true } },
setup(props: { counter: number }) {
const store = useStore()
expect(store.n).toBe(props.counter)
store.n++
},
})
mount(
{
template:
'<ChildComponent :counter="0" /><ChildComponent :counter="1" />',
components: { ChildComponent },
setup() {
const store = useStore()
expect(store.n).toBe(0)
store.n++
providePinia(createPinia())
},
},
{ global: { plugins: [pinia] } }
)
})
})
2 changes: 1 addition & 1 deletion packages/pinia/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @module pinia
*/
export { setActivePinia, getActivePinia } from './rootStore'
export { setActivePinia, getActivePinia, providePinia } from './rootStore'
export { createPinia } from './createPinia'
export type {
Pinia,
Expand Down
8 changes: 8 additions & 0 deletions packages/pinia/src/rootStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getCurrentInstance,
inject,
InjectionKey,
provide,
Ref,
} from 'vue-demi'
import {
Expand Down Expand Up @@ -97,6 +98,13 @@ export const piniaSymbol = (
__DEV__ ? Symbol('pinia') : /* istanbul ignore next */ Symbol()
) as InjectionKey<Pinia>

/**
* Define which pinia to use in all child components.
*/
export function providePinia(pinia: Pinia) {
provide(piniaSymbol, pinia)
}

/**
* Context argument passed to Pinia plugins.
*/
Expand Down

0 comments on commit ee7911b

Please sign in to comment.