Skip to content

Commit ad701ee

Browse files
authored
Merge pull request #81 from reedsy/reactive-provide
🐛 Fix reactivity for `@Provide`
2 parents b8ea646 + 950f0f2 commit ad701ee

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

src/option/provide.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { computed } from 'vue';
12
import type { Cons } from '../component';
23
import type { OptionBuilder } from '../optionBuilder'
34
import { obtainSlot, optionNullableMemberDecorator } from '../utils'
@@ -12,12 +13,11 @@ export const decorator = optionNullableMemberDecorator(function (proto: any, nam
1213

1314
export function build(cons: Cons, optionBuilder: OptionBuilder, vueInstance: any) {
1415
optionBuilder.provide ??= {}
15-
const sample = new cons(optionBuilder, vueInstance) as any
1616
const slot = obtainSlot(cons.prototype)
1717
const names = slot.obtainMap('provide')
1818
if (!names) return null
1919
names.forEach((value, name) => {
2020
const key = value === null ? name : value
21-
optionBuilder.provide![key] = sample[name]
21+
optionBuilder.provide![key] = computed(() => vueInstance[name])
2222
})
2323
}

test/option/provide.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { expect } from 'chai';
33
import 'mocha';
44
import { Component, Provide, Base, Inject, toNative } from '../../dist'
55
import { VueWrapper, mount } from '@vue/test-utils';
6+
import { Ref, computed, ref } from 'vue';
67

78
describe('decorator Provide',
89
() => {
@@ -14,13 +15,18 @@ describe('decorator Provide',
1415
})
1516
class Parent extends Base {
1617
@Provide
17-
readonly foo = 'provided foo'
18+
foo = 'provided foo'
1819

1920
@Provide
2021
readonly foo2 = this.foo
2122

2223
@Provide('overridden')
2324
readonly _internalName = 123
25+
26+
@Provide
27+
get getter() {
28+
return 'from getter'
29+
}
2430
}
2531

2632
@Component({ template: '<span />' })
@@ -36,8 +42,12 @@ describe('decorator Provide',
3642

3743
@Inject
3844
readonly overridden!: number
45+
46+
@Inject
47+
readonly getter!: string
3948
}
4049

50+
let parent: VueWrapper<Parent>;
4151
let child: VueWrapper<Child>;
4252

4353
beforeEach(() => {
@@ -51,7 +61,14 @@ describe('decorator Provide',
5161
Parent,
5262
Child,
5363
}
64+
}, {
65+
global: {
66+
config: {
67+
unwrapInjectedRef: true,
68+
},
69+
},
5470
})
71+
parent = component.findComponent(Parent)
5572
child = component.findComponent(Child)
5673
})
5774

@@ -72,6 +89,18 @@ describe('decorator Provide',
7289
expect(child.vm.overridden).to.equal(123)
7390
})
7491

92+
it('getter', () => {
93+
expect(child.vm.getter).to.equal('from getter')
94+
})
95+
96+
it('honours reactivity', async () => {
97+
expect(parent.vm.foo).to.equal('provided foo')
98+
expect(child.vm.foo).to.equal('provided foo')
99+
100+
parent.vm.foo = 'bar'
101+
expect(child.vm.foo).to.equal('bar')
102+
})
103+
75104
it('prioritises the class decorator', () => {
76105
@Component({
77106
template: '<div><slot/></div>',

0 commit comments

Comments
 (0)