Skip to content

Commit 0d32ea7

Browse files
committed
refactor: move context into its own file
1 parent 63bd8d3 commit 0d32ea7

File tree

6 files changed

+68
-66
lines changed

6 files changed

+68
-66
lines changed

src/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { reactive } from '@vue/reactivity'
22
import { Block } from './block'
33
import { Directive } from './directives'
4-
import { createContext } from './walk'
4+
import { createContext } from './context'
55
import { toDisplayString } from './directives/text'
66
import { nextTick } from './scheduler'
77

src/block.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Context, createContext, walk } from './walk'
1+
import { Context, createContext } from './context'
2+
import { walk } from './walk'
23
import { remove } from '@vue/shared'
34
import { stop } from '@vue/reactivity'
45

src/context.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { effect as rawEffect, reactive, ReactiveEffect } from '@vue/reactivity'
2+
import { Block } from './block'
3+
import { Directive } from './directives'
4+
import { queueJob } from './scheduler'
5+
import { inOnce } from './walk'
6+
7+
export interface Context {
8+
key?: any
9+
scope: Record<string, any>
10+
dirs: Record<string, Directive>
11+
blocks: Block[]
12+
effect: typeof rawEffect
13+
effects: ReactiveEffect[]
14+
cleanups: (() => void)[]
15+
}
16+
17+
export const createContext = (parent?: Context): Context => {
18+
const ctx: Context = {
19+
...parent,
20+
scope: parent ? parent.scope : reactive({}),
21+
dirs: parent ? parent.dirs : {},
22+
effects: [],
23+
blocks: [],
24+
cleanups: [],
25+
effect: (fn) => {
26+
if (inOnce) {
27+
queueJob(fn)
28+
return fn as any
29+
}
30+
const e: ReactiveEffect = rawEffect(fn, {
31+
scheduler: () => queueJob(e)
32+
})
33+
ctx.effects.push(e)
34+
return e
35+
}
36+
}
37+
return ctx
38+
}
39+
40+
export const createScopedContext = (ctx: Context, data = {}): Context => {
41+
const parentScope = ctx.scope
42+
const mergedScope = Object.create(parentScope)
43+
Object.defineProperties(mergedScope, Object.getOwnPropertyDescriptors(data))
44+
mergedScope.$refs = Object.create(parentScope.$refs)
45+
const reactiveProxy = reactive(
46+
new Proxy(mergedScope, {
47+
set(target, key, val, receiver) {
48+
// when setting a property that doesn't exist on current scope,
49+
// do not create it on the current scope and fallback to parent scope.
50+
if (receiver === reactiveProxy && !target.hasOwnProperty(key)) {
51+
return Reflect.set(parentScope, key, val)
52+
}
53+
return Reflect.set(target, key, val, receiver)
54+
}
55+
})
56+
)
57+
return {
58+
...ctx,
59+
scope: reactiveProxy
60+
}
61+
}

src/directives/for.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { isArray, isObject } from '@vue/shared'
22
import { Block } from '../block'
33
import { evaluate } from '../eval'
4-
import { Context } from '../walk'
5-
import { createScopedContext } from './scope'
4+
import { Context, createScopedContext } from '../context'
65

76
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
87
const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/

src/directives/scope.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/walk.ts

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,18 @@ import { builtInDirectives, Directive } from './directives'
22
import { _if } from './directives/if'
33
import { _for } from './directives/for'
44
import { bind } from './directives/bind'
5-
import { createScopedContext } from './directives/scope'
65
import { on } from './directives/on'
76
import { text } from './directives/text'
87
import { evaluate } from './eval'
9-
import { effect as rawEffect, reactive, ReactiveEffect } from '@vue/reactivity'
10-
import { Block } from './block'
11-
import { queueJob } from './scheduler'
128
import { checkAttr } from './utils'
139
import { ref } from './directives/ref'
14-
15-
export interface Context {
16-
key?: any
17-
scope: Record<string, any>
18-
dirs: Record<string, Directive>
19-
blocks: Block[]
20-
effect: typeof rawEffect
21-
effects: ReactiveEffect[]
22-
cleanups: (() => void)[]
23-
}
24-
25-
export const createContext = (parent?: Context): Context => {
26-
const ctx: Context = {
27-
...parent,
28-
scope: parent ? parent.scope : reactive({}),
29-
dirs: parent ? parent.dirs : {},
30-
effects: [],
31-
blocks: [],
32-
cleanups: [],
33-
effect: (fn) => {
34-
if (inOnce) {
35-
queueJob(fn)
36-
return fn as any
37-
}
38-
const e: ReactiveEffect = rawEffect(fn, {
39-
scheduler: () => queueJob(e)
40-
})
41-
ctx.effects.push(e)
42-
return e
43-
}
44-
}
45-
return ctx
46-
}
10+
import { Context, createScopedContext } from './context'
4711

4812
const dirRE = /^(?:v-|:|@)/
4913
const modifierRE = /\.([\w-]+)/g
5014
const interpolationRE = /\{\{([^]+?)\}\}/g
51-
let inOnce = false
15+
16+
export let inOnce = false
5217

5318
export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
5419
const type = node.nodeType

0 commit comments

Comments
 (0)