Skip to content

Commit 11dad4c

Browse files
authored
Merge pull request #780 from vuejs/next
2 parents e06a9e2 + 244a2cf commit 11dad4c

File tree

14 files changed

+616
-59
lines changed

14 files changed

+616
-59
lines changed

CHANGELOG.md

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,68 @@
1-
<a name="1.0.6"></a>
2-
## [1.0.6](https://github.com/vuejs/composition-api/compare/v1.0.5...v1.0.6) (2021-08-09)
1+
<a name="1.1.0-beta.7"></a>
2+
# [1.1.0-beta.7](https://github.com/vuejs/composition-api/compare/v1.1.0-beta.6...v1.1.0-beta.7) (2021-08-09)
3+
4+
### Bug Fixes
5+
6+
* **effectScope:** should have a vaild scope with component ([da21873](https://github.com/vuejs/composition-api/commit/da21873))
7+
8+
9+
<a name="1.1.0-beta.6"></a>
10+
# [1.1.0-beta.6](https://github.com/vuejs/composition-api/compare/v1.1.0-beta.5...v1.1.0-beta.6) (2021-08-09)
11+
12+
* new watchPostEffect api ([92fe90c](https://github.com/vuejs/composition-api/commit/92fe90c))
13+
* support second target argument for lifecycle functions ([0133c1e](https://github.com/vuejs/composition-api/commit/0133c1e))
14+
15+
16+
<a name="1.1.0-beta.4"></a>
17+
# [1.1.0-beta.4](https://github.com/vuejs/composition-api/compare/v1.0.4...v1.1.0-beta.4) (2021-07-22)
18+
19+
20+
### Bug Fixes
21+
22+
* revert module field to `esm.js` version, close [#769](https://github.com/vuejs/composition-api/issues/769) ([92afa6f](https://github.com/vuejs/composition-api/commit/92afa6f))
23+
24+
25+
26+
<a name="1.1.0-beta.3"></a>
27+
# [1.1.0-beta.3](https://github.com/vuejs/composition-api/compare/v1.0.3...v1.1.0-beta.3) (2021-07-18)
28+
29+
30+
### Bug Fixes
31+
32+
* build for mjs and exports all submodules ([c116714](https://github.com/vuejs/composition-api/commit/c116714))
33+
34+
35+
36+
<a name="1.1.0-beta.2"></a>
37+
# [1.1.0-beta.2](https://github.com/vuejs/composition-api/compare/v1.1.0-beta.1...v1.1.0-beta.2) (2021-07-16)
38+
39+
40+
### Bug Fixes
41+
42+
* **effectScope:** should stop along with parent component ([784d96c](https://github.com/vuejs/composition-api/commit/784d96c))
43+
44+
45+
46+
<a name="1.1.0-beta.1"></a>
47+
# [1.1.0-beta.1](https://github.com/vuejs/composition-api/compare/v1.0.2...v1.1.0-beta.1) (2021-07-16)
48+
49+
50+
### Features
51+
52+
* implement `effectScope` api ([#762](https://github.com/vuejs/composition-api/issues/762)) ([fcadec2](https://github.com/vuejs/composition-api/commit/fcadec2))
353

454

555
### Features
656

57+
* implement `effectScope` api ([#762](https://github.com/vuejs/composition-api/issues/762)) ([fcadec2](https://github.com/vuejs/composition-api/commit/fcadec2))
758
* support second target argument for lifecycle functions ([3f3b9c6](https://github.com/vuejs/composition-api/commit/3f3b9c6))
859

960

61+
<a name="1.0.6"></a>
62+
## [1.0.6](https://github.com/vuejs/composition-api/compare/v1.0.5...v1.0.6) (2021-08-09)
63+
64+
65+
### Features
1066

1167
<a name="1.0.5"></a>
1268
## [1.0.5](https://github.com/vuejs/composition-api/compare/v1.0.4...v1.0.5) (2021-08-01)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Include `@vue/composition-api` after Vue and it will install itself automaticall
4141
<!--cdn-links-start-->
4242
```html
4343
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
44-
<script src="https://cdn.jsdelivr.net/npm/@vue/composition-api@1.0.6"></script>
44+
<script src="https://cdn.jsdelivr.net/npm/@vue/composition-api@1.1.0-beta.7"></script>
4545
```
4646
<!--cdn-links-end-->
4747

README.zh-CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { ref, reactive } from '@vue/composition-api'
4040
<!--cdn-links-start-->
4141
```html
4242
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
43-
<script src="https://cdn.jsdelivr.net/npm/@vue/composition-api@1.0.6"></script>
43+
<script src="https://cdn.jsdelivr.net/npm/@vue/composition-api@1.1.0-beta.7"></script>
4444
```
4545
<!--cdn-links-end-->
4646

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue/composition-api",
3-
"version": "1.0.6",
3+
"version": "1.1.0-beta.7",
44
"description": "Provide logic composition capabilities for Vue.",
55
"keywords": [
66
"vue",
@@ -42,7 +42,7 @@
4242
"update-readme": "node ./scripts/update-readme.js",
4343
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
4444
"version": "yarn changelog && yarn update-readme && git add CHANGELOG.md README.*",
45-
"release": "yarn version && yarn test && yarn publish --non-interactive && git push --follow-tags",
45+
"release": "yarn version && yarn test && yarn publish --non-interactive --tag next && git push --follow-tags",
4646
"release-gh": "conventional-github-releaser -p angular"
4747
},
4848
"bugs": {

src/apis/computed.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getVueConstructor, getCurrentInstance } from '../runtimeContext'
1+
import { getVueConstructor } from '../runtimeContext'
22
import { createRef, Ref } from '../reactivity'
33
import {
44
warn,
@@ -7,6 +7,7 @@ import {
77
getVueInternalClasses,
88
isFunction,
99
} from '../utils'
10+
import { getCurrentScopeVM } from './effectScope'
1011

1112
export interface ComputedRef<T = any> extends WritableComputedRef<T> {
1213
readonly value: T
@@ -32,7 +33,7 @@ export function computed<T>(
3233
export function computed<T>(
3334
getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>
3435
): ComputedRef<T> | WritableComputedRef<T> {
35-
const vm = getCurrentInstance()?.proxy
36+
const vm = getCurrentScopeVM()
3637
let getter: ComputedGetter<T>
3738
let setter: ComputedSetter<T> | undefined
3839

src/apis/effectScope.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import {
2+
ComponentInternalInstance,
3+
getCurrentInstance,
4+
getVueConstructor,
5+
withCurrentInstanceTrackingDisabled,
6+
} from '../runtimeContext'
7+
import { defineComponentInstance } from '../utils'
8+
import { warn } from './warn'
9+
10+
let activeEffectScope: EffectScope | undefined
11+
const effectScopeStack: EffectScope[] = []
12+
13+
class EffectScopeImpl {
14+
active = true
15+
effects: EffectScope[] = []
16+
cleanups: (() => void)[] = []
17+
18+
/**
19+
* @internal
20+
**/
21+
vm: Vue
22+
23+
constructor(vm: Vue) {
24+
this.vm = vm
25+
}
26+
27+
run<T>(fn: () => T): T | undefined {
28+
if (this.active) {
29+
try {
30+
this.on()
31+
return fn()
32+
} finally {
33+
this.off()
34+
}
35+
} else if (__DEV__) {
36+
warn(`cannot run an inactive effect scope.`)
37+
}
38+
return
39+
}
40+
41+
on() {
42+
if (this.active) {
43+
effectScopeStack.push(this)
44+
activeEffectScope = this
45+
}
46+
}
47+
48+
off() {
49+
if (this.active) {
50+
effectScopeStack.pop()
51+
activeEffectScope = effectScopeStack[effectScopeStack.length - 1]
52+
}
53+
}
54+
55+
stop() {
56+
if (this.active) {
57+
this.vm.$destroy()
58+
this.effects.forEach((e) => e.stop())
59+
this.cleanups.forEach((cleanup) => cleanup())
60+
this.active = false
61+
}
62+
}
63+
}
64+
65+
export class EffectScope extends EffectScopeImpl {
66+
constructor(detached = false) {
67+
let vm: Vue = undefined!
68+
withCurrentInstanceTrackingDisabled(() => {
69+
vm = defineComponentInstance(getVueConstructor())
70+
})
71+
super(vm)
72+
if (!detached) {
73+
recordEffectScope(this)
74+
}
75+
}
76+
}
77+
78+
export function recordEffectScope(
79+
effect: EffectScope,
80+
scope?: EffectScope | null
81+
) {
82+
scope = scope || activeEffectScope
83+
if (scope && scope.active) {
84+
scope.effects.push(effect)
85+
return
86+
}
87+
// destory on parent component unmounted
88+
const vm = getCurrentInstance()?.proxy
89+
vm && vm.$on('hook:destroyed', () => effect.stop())
90+
}
91+
92+
export function effectScope(detached?: boolean) {
93+
return new EffectScope(detached)
94+
}
95+
96+
export function getCurrentScope() {
97+
return activeEffectScope
98+
}
99+
100+
export function onScopeDispose(fn: () => void) {
101+
if (activeEffectScope) {
102+
activeEffectScope.cleanups.push(fn)
103+
} else if (__DEV__) {
104+
warn(
105+
`onDispose() is called when there is no active effect scope ` +
106+
` to be associated with.`
107+
)
108+
}
109+
}
110+
111+
/**
112+
* @internal
113+
**/
114+
export function getCurrentScopeVM() {
115+
return getCurrentScope()?.vm || getCurrentInstance()?.proxy
116+
}
117+
118+
/**
119+
* @internal
120+
**/
121+
export function bindCurrentScopeToVM(
122+
vm: ComponentInternalInstance
123+
): EffectScope {
124+
if (!vm.scope) {
125+
const scope = new EffectScopeImpl(vm.proxy) as EffectScope
126+
vm.scope = scope
127+
vm.proxy.$on('hook:destroyed', () => scope.stop())
128+
}
129+
return vm.scope
130+
}

src/apis/index.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
export * from '../reactivity'
2-
export * from './lifecycle'
2+
export {
3+
onBeforeMount,
4+
onMounted,
5+
onBeforeUpdate,
6+
onUpdated,
7+
onBeforeUnmount,
8+
onUnmounted,
9+
onErrorCaptured,
10+
onActivated,
11+
onDeactivated,
12+
onServerPrefetch,
13+
} from './lifecycle'
314
export * from './watch'
415
export * from './computed'
516
export * from './inject'
@@ -8,3 +19,9 @@ export { App, createApp } from './createApp'
819
export { nextTick } from './nextTick'
920
export { createElement as h } from './createElement'
1021
export { warn } from './warn'
22+
export {
23+
effectScope,
24+
EffectScope,
25+
getCurrentScope,
26+
onScopeDispose,
27+
} from './effectScope'

src/apis/inject.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { ComponentInstance } from '../component'
2-
import { hasOwn, warn, currentVMInFn, isFunction, proxy } from '../utils'
2+
import {
3+
hasOwn,
4+
warn,
5+
getCurrentInstanceForFn,
6+
isFunction,
7+
proxy,
8+
} from '../utils'
39
import { getCurrentInstance } from '../runtimeContext'
410

511
const NOT_FOUND = {}
@@ -23,7 +29,7 @@ function resolveInject(
2329
}
2430

2531
export function provide<T>(key: InjectionKey<T> | string, value: T): void {
26-
const vm: any = currentVMInFn('provide')
32+
const vm: any = getCurrentInstanceForFn('provide')?.proxy
2733
if (!vm) return
2834

2935
if (!vm._provided) {

src/apis/lifecycle.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,51 @@
11
import { VueConstructor } from 'vue'
2-
import { ComponentInstance } from '../component'
32
import {
43
getVueConstructor,
54
setCurrentInstance,
65
getCurrentInstance,
76
ComponentInternalInstance,
87
} from '../runtimeContext'
9-
import { currentVMInFn } from '../utils/helper'
8+
import { getCurrentInstanceForFn } from '../utils/helper'
109

1110
const genName = (name: string) => `on${name[0].toUpperCase() + name.slice(1)}`
1211
function createLifeCycle(lifeCyclehook: string) {
1312
return (callback: Function, target?: ComponentInternalInstance | null) => {
14-
const vm = currentVMInFn(genName(lifeCyclehook), target)
13+
const instance = getCurrentInstanceForFn(genName(lifeCyclehook), target)
1514
return (
16-
vm && injectHookOption(getVueConstructor(), vm, lifeCyclehook, callback)
15+
instance &&
16+
injectHookOption(getVueConstructor(), instance, lifeCyclehook, callback)
1717
)
1818
}
1919
}
2020

2121
function injectHookOption(
2222
Vue: VueConstructor,
23-
vm: ComponentInstance,
23+
instance: ComponentInternalInstance,
2424
hook: string,
2525
val: Function
2626
) {
27-
const options = vm.$options as Record<string, unknown>
27+
const options = instance.proxy.$options as Record<string, unknown>
2828
const mergeFn = Vue.config.optionMergeStrategies[hook]
29-
const wrappedHook = wrapHookCall(vm, val)
29+
const wrappedHook = wrapHookCall(instance, val)
3030
options[hook] = mergeFn(options[hook], wrappedHook)
3131
return wrappedHook
3232
}
3333

34-
function wrapHookCall(vm: ComponentInstance, fn: Function): Function {
34+
function wrapHookCall(
35+
instance: ComponentInternalInstance,
36+
fn: Function
37+
): Function {
3538
return (...args: any) => {
36-
let preVm = getCurrentInstance()?.proxy
37-
setCurrentInstance(vm)
39+
let prev = getCurrentInstance()
40+
setCurrentInstance(instance)
3841
try {
3942
return fn(...args)
4043
} finally {
41-
setCurrentInstance(preVm!)
44+
setCurrentInstance(prev)
4245
}
4346
}
4447
}
4548

46-
// export const onCreated = createLifeCycle('created');
4749
export const onBeforeMount = createLifeCycle('beforeMount')
4850
export const onMounted = createLifeCycle('mounted')
4951
export const onBeforeUpdate = createLifeCycle('beforeUpdate')

0 commit comments

Comments
 (0)