vue 2.7.6 → 2.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/vue.common.dev.js +139 -67
- package/dist/vue.common.prod.js +3 -3
- package/dist/vue.esm.browser.js +137 -66
- package/dist/vue.esm.browser.min.js +3 -3
- package/dist/vue.esm.js +138 -66
- package/dist/vue.js +140 -67
- package/dist/vue.min.js +3 -3
- package/dist/vue.runtime.common.dev.js +112 -58
- package/dist/vue.runtime.common.prod.js +3 -3
- package/dist/vue.runtime.esm.js +111 -57
- package/dist/vue.runtime.js +113 -58
- package/dist/vue.runtime.min.js +3 -3
- package/package.json +2 -2
- package/packages/compiler-sfc/dist/compiler-sfc.js +56 -26
- package/packages/compiler-sfc/package.json +2 -3
- package/packages/compiler-sfc/src/compileTemplate.ts +1 -2
- package/packages/compiler-sfc/src/rewriteDefault.ts +6 -1
- package/packages/compiler-sfc/src/templateCompilerModules/utils.ts +8 -3
- package/packages/compiler-sfc/test/rewriteDefault.spec.ts +245 -0
- package/src/compiler/codegen/index.ts +31 -10
- package/src/core/instance/init.ts +1 -0
- package/src/core/instance/inject.ts +10 -5
- package/src/core/instance/lifecycle.ts +18 -10
- package/src/core/instance/proxy.ts +2 -2
- package/src/core/instance/render.ts +8 -2
- package/src/core/instance/state.ts +1 -1
- package/src/core/observer/index.ts +1 -1
- package/src/core/observer/scheduler.ts +10 -1
- package/src/core/observer/watcher.ts +14 -5
- package/src/core/vdom/modules/directives.ts +9 -1
- package/src/core/vdom/vnode.ts +1 -0
- package/src/types/component.ts +1 -0
- package/src/v3/apiInject.ts +17 -12
- package/src/v3/apiLifecycle.ts +16 -1
- package/src/v3/apiSetup.ts +38 -17
- package/src/v3/apiWatch.ts +2 -5
- package/src/v3/index.ts +1 -1
- package/src/v3/reactivity/effectScope.ts +5 -1
- package/types/index.d.ts +2 -2
- package/types/options.d.ts +24 -9
- package/types/v3-component-options.d.ts +3 -0
- package/types/v3-component-public-instance.d.ts +2 -4
- package/types/v3-define-component.d.ts +34 -34
- package/types/v3-generated.d.ts +11 -2
- package/types/v3-manual-apis.d.ts +2 -2
- package/types/v3-setup-context.d.ts +4 -0
- package/types/vue.d.ts +108 -31
|
@@ -144,8 +144,7 @@ function actuallyCompile(
|
|
|
144
144
|
errors
|
|
145
145
|
}
|
|
146
146
|
} else {
|
|
147
|
-
//
|
|
148
|
-
// version of Buble that applies ES2015 transforms + stripping `with` usage
|
|
147
|
+
// stripping `with` usage
|
|
149
148
|
let code =
|
|
150
149
|
`var __render__ = ${prefixIdentifiers(
|
|
151
150
|
`function render(${isFunctional ? `_c,_vm` : ``}){${render}\n}`,
|
|
@@ -42,7 +42,12 @@ export function rewriteDefault(
|
|
|
42
42
|
}).program.body
|
|
43
43
|
ast.forEach(node => {
|
|
44
44
|
if (node.type === 'ExportDefaultDeclaration') {
|
|
45
|
-
|
|
45
|
+
if (node.declaration.type === 'ClassDeclaration') {
|
|
46
|
+
s.overwrite(node.start!, node.declaration.id.start!, `class `)
|
|
47
|
+
s.append(`\nconst ${as} = ${node.declaration.id.name}`)
|
|
48
|
+
} else {
|
|
49
|
+
s.overwrite(node.start!, node.declaration.start!, `const ${as} = `)
|
|
50
|
+
}
|
|
46
51
|
}
|
|
47
52
|
if (node.type === 'ExportNamedDeclaration') {
|
|
48
53
|
for (const specifier of node.specifiers) {
|
|
@@ -24,10 +24,15 @@ export function urlToRequire(
|
|
|
24
24
|
// does not apply to absolute urls or urls that start with `@`
|
|
25
25
|
// since they are aliases
|
|
26
26
|
if (firstChar === '.' || firstChar === '~') {
|
|
27
|
+
// Allow for full hostnames provided in options.base
|
|
28
|
+
const base = parseUriParts(transformAssetUrlsOption.base)
|
|
29
|
+
const protocol = base.protocol || ''
|
|
30
|
+
const host = base.host ? protocol + '//' + base.host : ''
|
|
31
|
+
const basePath = base.path || '/'
|
|
27
32
|
// when packaged in the browser, path will be using the posix-
|
|
28
33
|
// only version provided by rollup-plugin-node-builtins.
|
|
29
|
-
return `"${(path.posix || path).join(
|
|
30
|
-
|
|
34
|
+
return `"${host}${(path.posix || path).join(
|
|
35
|
+
basePath,
|
|
31
36
|
uriParts.path + (uriParts.hash || '')
|
|
32
37
|
)}"`
|
|
33
38
|
}
|
|
@@ -64,7 +69,7 @@ function parseUriParts(urlString: string): UrlWithStringQuery {
|
|
|
64
69
|
// @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost
|
|
65
70
|
if ('string' === typeof urlString) {
|
|
66
71
|
// check is an uri
|
|
67
|
-
return uriParse(urlString) // take apart the uri
|
|
72
|
+
return uriParse(urlString, false, true) // take apart the uri
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
75
|
return returnValue
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { rewriteDefault } from '../src'
|
|
2
|
+
|
|
3
|
+
describe('compiler sfc: rewriteDefault', () => {
|
|
4
|
+
test('without export default', () => {
|
|
5
|
+
expect(rewriteDefault(`export a = {}`, 'script')).toMatchInlineSnapshot(`
|
|
6
|
+
"export a = {}
|
|
7
|
+
const script = {}"
|
|
8
|
+
`)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
test('rewrite export default', () => {
|
|
12
|
+
expect(
|
|
13
|
+
rewriteDefault(`export default {}`, 'script')
|
|
14
|
+
).toMatchInlineSnapshot(`"const script = {}"`)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('rewrite export named default', () => {
|
|
18
|
+
expect(
|
|
19
|
+
rewriteDefault(
|
|
20
|
+
`const a = 1 \n export { a as b, a as default, a as c}`,
|
|
21
|
+
'script'
|
|
22
|
+
)
|
|
23
|
+
).toMatchInlineSnapshot(`
|
|
24
|
+
"const a = 1
|
|
25
|
+
export { a as b, a as c}
|
|
26
|
+
const script = a"
|
|
27
|
+
`)
|
|
28
|
+
|
|
29
|
+
expect(
|
|
30
|
+
rewriteDefault(
|
|
31
|
+
`const a = 1 \n export { a as b, a as default , a as c}`,
|
|
32
|
+
'script'
|
|
33
|
+
)
|
|
34
|
+
).toMatchInlineSnapshot(`
|
|
35
|
+
"const a = 1
|
|
36
|
+
export { a as b, a as c}
|
|
37
|
+
const script = a"
|
|
38
|
+
`)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('w/ comments', async () => {
|
|
42
|
+
expect(rewriteDefault(`// export default\nexport default {}`, 'script'))
|
|
43
|
+
.toMatchInlineSnapshot(`
|
|
44
|
+
"// export default
|
|
45
|
+
const script = {}"
|
|
46
|
+
`)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('export named default multiline', () => {
|
|
50
|
+
expect(
|
|
51
|
+
rewriteDefault(`let App = {}\n export {\nApp as default\n}`, '_sfc_main')
|
|
52
|
+
).toMatchInlineSnapshot(`
|
|
53
|
+
"let App = {}
|
|
54
|
+
export {
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
const _sfc_main = App"
|
|
58
|
+
`)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('export named default multiline /w comments', () => {
|
|
62
|
+
expect(
|
|
63
|
+
rewriteDefault(
|
|
64
|
+
`const a = 1 \n export {\n a as b,\n a as default,\n a as c}\n` +
|
|
65
|
+
`// export { myFunction as default }`,
|
|
66
|
+
'script'
|
|
67
|
+
)
|
|
68
|
+
).toMatchInlineSnapshot(`
|
|
69
|
+
"const a = 1
|
|
70
|
+
export {
|
|
71
|
+
a as b,
|
|
72
|
+
|
|
73
|
+
a as c}
|
|
74
|
+
// export { myFunction as default }
|
|
75
|
+
const script = a"
|
|
76
|
+
`)
|
|
77
|
+
|
|
78
|
+
expect(
|
|
79
|
+
rewriteDefault(
|
|
80
|
+
`const a = 1 \n export {\n a as b,\n a as default ,\n a as c}\n` +
|
|
81
|
+
`// export { myFunction as default }`,
|
|
82
|
+
'script'
|
|
83
|
+
)
|
|
84
|
+
).toMatchInlineSnapshot(`
|
|
85
|
+
"const a = 1
|
|
86
|
+
export {
|
|
87
|
+
a as b,
|
|
88
|
+
|
|
89
|
+
a as c}
|
|
90
|
+
// export { myFunction as default }
|
|
91
|
+
const script = a"
|
|
92
|
+
`)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test(`export { default } from '...'`, async () => {
|
|
96
|
+
expect(
|
|
97
|
+
rewriteDefault(`export { default, foo } from './index.js'`, 'script')
|
|
98
|
+
).toMatchInlineSnapshot(`
|
|
99
|
+
"import { default as __VUE_DEFAULT__ } from './index.js'
|
|
100
|
+
export { foo } from './index.js'
|
|
101
|
+
const script = __VUE_DEFAULT__"
|
|
102
|
+
`)
|
|
103
|
+
|
|
104
|
+
expect(
|
|
105
|
+
rewriteDefault(`export { default , foo } from './index.js'`, 'script')
|
|
106
|
+
).toMatchInlineSnapshot(`
|
|
107
|
+
"import { default as __VUE_DEFAULT__ } from './index.js'
|
|
108
|
+
export { foo } from './index.js'
|
|
109
|
+
const script = __VUE_DEFAULT__"
|
|
110
|
+
`)
|
|
111
|
+
|
|
112
|
+
expect(
|
|
113
|
+
rewriteDefault(`export { foo, default } from './index.js'`, 'script')
|
|
114
|
+
).toMatchInlineSnapshot(`
|
|
115
|
+
"import { default as __VUE_DEFAULT__ } from './index.js'
|
|
116
|
+
export { foo, } from './index.js'
|
|
117
|
+
const script = __VUE_DEFAULT__"
|
|
118
|
+
`)
|
|
119
|
+
|
|
120
|
+
expect(
|
|
121
|
+
rewriteDefault(
|
|
122
|
+
`export { foo as default, bar } from './index.js'`,
|
|
123
|
+
'script'
|
|
124
|
+
)
|
|
125
|
+
).toMatchInlineSnapshot(`
|
|
126
|
+
"import { foo } from './index.js'
|
|
127
|
+
export { bar } from './index.js'
|
|
128
|
+
const script = foo"
|
|
129
|
+
`)
|
|
130
|
+
|
|
131
|
+
expect(
|
|
132
|
+
rewriteDefault(
|
|
133
|
+
`export { foo as default , bar } from './index.js'`,
|
|
134
|
+
'script'
|
|
135
|
+
)
|
|
136
|
+
).toMatchInlineSnapshot(`
|
|
137
|
+
"import { foo } from './index.js'
|
|
138
|
+
export { bar } from './index.js'
|
|
139
|
+
const script = foo"
|
|
140
|
+
`)
|
|
141
|
+
|
|
142
|
+
expect(
|
|
143
|
+
rewriteDefault(
|
|
144
|
+
`export { bar, foo as default } from './index.js'`,
|
|
145
|
+
'script'
|
|
146
|
+
)
|
|
147
|
+
).toMatchInlineSnapshot(`
|
|
148
|
+
"import { foo } from './index.js'
|
|
149
|
+
export { bar, } from './index.js'
|
|
150
|
+
const script = foo"
|
|
151
|
+
`)
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
test('export default class', async () => {
|
|
155
|
+
expect(rewriteDefault(`export default class Foo {}`, 'script'))
|
|
156
|
+
.toMatchInlineSnapshot(`
|
|
157
|
+
"class Foo {}
|
|
158
|
+
const script = Foo"
|
|
159
|
+
`)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
test('export default class w/ comments', async () => {
|
|
163
|
+
expect(
|
|
164
|
+
rewriteDefault(`// export default\nexport default class Foo {}`, 'script')
|
|
165
|
+
).toMatchInlineSnapshot(`
|
|
166
|
+
"// export default
|
|
167
|
+
class Foo {}
|
|
168
|
+
const script = Foo"
|
|
169
|
+
`)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
test('export default class w/ comments 2', async () => {
|
|
173
|
+
expect(
|
|
174
|
+
rewriteDefault(
|
|
175
|
+
`export default {}\n` + `// export default class Foo {}`,
|
|
176
|
+
'script'
|
|
177
|
+
)
|
|
178
|
+
).toMatchInlineSnapshot(`
|
|
179
|
+
"const script = {}
|
|
180
|
+
// export default class Foo {}"
|
|
181
|
+
`)
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
test('export default class w/ comments 3', async () => {
|
|
185
|
+
expect(
|
|
186
|
+
rewriteDefault(
|
|
187
|
+
`/*\nexport default class Foo {}*/\n` + `export default class Bar {}`,
|
|
188
|
+
'script'
|
|
189
|
+
)
|
|
190
|
+
).toMatchInlineSnapshot(`
|
|
191
|
+
"/*
|
|
192
|
+
export default class Foo {}*/
|
|
193
|
+
class Bar {}
|
|
194
|
+
const script = Bar"
|
|
195
|
+
`)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
test('@Component\nexport default class', async () => {
|
|
199
|
+
expect(rewriteDefault(`@Component\nexport default class Foo {}`, 'script'))
|
|
200
|
+
.toMatchInlineSnapshot(`
|
|
201
|
+
"@Component
|
|
202
|
+
class Foo {}
|
|
203
|
+
const script = Foo"
|
|
204
|
+
`)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('@Component\nexport default class w/ comments', async () => {
|
|
208
|
+
expect(
|
|
209
|
+
rewriteDefault(`// export default\n@Component\nexport default class Foo {}`, 'script')
|
|
210
|
+
).toMatchInlineSnapshot(`
|
|
211
|
+
"// export default
|
|
212
|
+
@Component
|
|
213
|
+
class Foo {}
|
|
214
|
+
const script = Foo"
|
|
215
|
+
`)
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
test('@Component\nexport default class w/ comments 2', async () => {
|
|
219
|
+
expect(
|
|
220
|
+
rewriteDefault(
|
|
221
|
+
`export default {}\n` + `// @Component\n// export default class Foo {}`,
|
|
222
|
+
'script'
|
|
223
|
+
)
|
|
224
|
+
).toMatchInlineSnapshot(`
|
|
225
|
+
"const script = {}
|
|
226
|
+
// @Component
|
|
227
|
+
// export default class Foo {}"
|
|
228
|
+
`)
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
test('@Component\nexport default class w/ comments 3', async () => {
|
|
232
|
+
expect(
|
|
233
|
+
rewriteDefault(
|
|
234
|
+
`/*\n@Component\nexport default class Foo {}*/\n` + `export default class Bar {}`,
|
|
235
|
+
'script'
|
|
236
|
+
)
|
|
237
|
+
).toMatchInlineSnapshot(`
|
|
238
|
+
"/*
|
|
239
|
+
@Component
|
|
240
|
+
export default class Foo {}*/
|
|
241
|
+
class Bar {}
|
|
242
|
+
const script = Bar"
|
|
243
|
+
`)
|
|
244
|
+
})
|
|
245
|
+
})
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
ASTText,
|
|
14
14
|
CompilerOptions
|
|
15
15
|
} from 'types/compiler'
|
|
16
|
-
import { BindingMetadata } from 'sfc/types'
|
|
16
|
+
import { BindingMetadata, BindingTypes } from 'sfc/types'
|
|
17
17
|
|
|
18
18
|
type TransformFunction = (el: ASTElement, code: string) => string
|
|
19
19
|
type DataGenFunction = (el: ASTElement) => string
|
|
@@ -95,18 +95,16 @@ export function genElement(el: ASTElement, state: CodegenState): string {
|
|
|
95
95
|
code = genComponent(el.component, el, state)
|
|
96
96
|
} else {
|
|
97
97
|
let data
|
|
98
|
-
|
|
98
|
+
const maybeComponent = state.maybeComponent(el)
|
|
99
|
+
if (!el.plain || (el.pre && maybeComponent)) {
|
|
99
100
|
data = genData(el, state)
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
let tag: string | undefined
|
|
103
104
|
// check if this is a component in <script setup>
|
|
104
105
|
const bindings = state.options.bindings
|
|
105
|
-
if (bindings && bindings.__isScriptSetup !== false) {
|
|
106
|
-
tag =
|
|
107
|
-
checkBindingType(bindings, el.tag) ||
|
|
108
|
-
checkBindingType(bindings, camelize(el.tag)) ||
|
|
109
|
-
checkBindingType(bindings, capitalize(camelize(el.tag)))
|
|
106
|
+
if (maybeComponent && bindings && bindings.__isScriptSetup !== false) {
|
|
107
|
+
tag = checkBindingType(bindings, el.tag)
|
|
110
108
|
}
|
|
111
109
|
if (!tag) tag = `'${el.tag}'`
|
|
112
110
|
|
|
@@ -126,9 +124,32 @@ export function genElement(el: ASTElement, state: CodegenState): string {
|
|
|
126
124
|
}
|
|
127
125
|
|
|
128
126
|
function checkBindingType(bindings: BindingMetadata, key: string) {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
const camelName = camelize(key)
|
|
128
|
+
const PascalName = capitalize(camelName)
|
|
129
|
+
const checkType = (type) => {
|
|
130
|
+
if (bindings[key] === type) {
|
|
131
|
+
return key
|
|
132
|
+
}
|
|
133
|
+
if (bindings[camelName] === type) {
|
|
134
|
+
return camelName
|
|
135
|
+
}
|
|
136
|
+
if (bindings[PascalName] === type) {
|
|
137
|
+
return PascalName
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const fromConst =
|
|
141
|
+
checkType(BindingTypes.SETUP_CONST) ||
|
|
142
|
+
checkType(BindingTypes.SETUP_REACTIVE_CONST)
|
|
143
|
+
if (fromConst) {
|
|
144
|
+
return fromConst
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const fromMaybeRef =
|
|
148
|
+
checkType(BindingTypes.SETUP_LET) ||
|
|
149
|
+
checkType(BindingTypes.SETUP_REF) ||
|
|
150
|
+
checkType(BindingTypes.SETUP_MAYBE_REF)
|
|
151
|
+
if (fromMaybeRef) {
|
|
152
|
+
return fromMaybeRef
|
|
132
153
|
}
|
|
133
154
|
}
|
|
134
155
|
|
|
@@ -34,6 +34,7 @@ export function initMixin(Vue: typeof Component) {
|
|
|
34
34
|
vm.__v_skip = true
|
|
35
35
|
// effect scope
|
|
36
36
|
vm._scope = new EffectScope(true /* detached */)
|
|
37
|
+
vm._scope._vm = true
|
|
37
38
|
// merge options
|
|
38
39
|
if (options && options._isComponent) {
|
|
39
40
|
// optimize internal component instantiation
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { warn, hasSymbol, isFunction, isObject } from '../util/index'
|
|
2
2
|
import { defineReactive, toggleObserving } from '../observer/index'
|
|
3
3
|
import type { Component } from 'types/component'
|
|
4
|
-
import {
|
|
5
|
-
import { setCurrentInstance } from '../../v3/currentInstance'
|
|
4
|
+
import { resolveProvided } from 'v3/apiInject'
|
|
6
5
|
|
|
7
6
|
export function initProvide(vm: Component) {
|
|
8
7
|
const provideOption = vm.$options.provide
|
|
@@ -13,12 +12,18 @@ export function initProvide(vm: Component) {
|
|
|
13
12
|
if (!isObject(provided)) {
|
|
14
13
|
return
|
|
15
14
|
}
|
|
15
|
+
const source = resolveProvided(vm)
|
|
16
|
+
// IE9 doesn't support Object.getOwnPropertyDescriptors so we have to
|
|
17
|
+
// iterate the keys ourselves.
|
|
16
18
|
const keys = hasSymbol ? Reflect.ownKeys(provided) : Object.keys(provided)
|
|
17
|
-
setCurrentInstance(vm)
|
|
18
19
|
for (let i = 0; i < keys.length; i++) {
|
|
19
|
-
|
|
20
|
+
const key = keys[i]
|
|
21
|
+
Object.defineProperty(
|
|
22
|
+
source,
|
|
23
|
+
key,
|
|
24
|
+
Object.getOwnPropertyDescriptor(provided, key)!
|
|
25
|
+
)
|
|
20
26
|
}
|
|
21
|
-
setCurrentInstance()
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
invokeWithErrorHandling
|
|
19
19
|
} from '../util/index'
|
|
20
20
|
import { currentInstance, setCurrentInstance } from 'v3/currentInstance'
|
|
21
|
-
import {
|
|
21
|
+
import { syncSetupProxy } from 'v3/apiSetup'
|
|
22
22
|
|
|
23
23
|
export let activeInstance: any = null
|
|
24
24
|
export let isUpdatingChildComponent: boolean = false
|
|
@@ -288,11 +288,12 @@ export function updateChildComponent(
|
|
|
288
288
|
// force update if attrs are accessed and has changed since it may be
|
|
289
289
|
// passed to a child component.
|
|
290
290
|
if (
|
|
291
|
-
|
|
291
|
+
syncSetupProxy(
|
|
292
292
|
vm._attrsProxy,
|
|
293
293
|
attrs,
|
|
294
294
|
(prevVNode.data && prevVNode.data.attrs) || emptyObject,
|
|
295
|
-
vm
|
|
295
|
+
vm,
|
|
296
|
+
'$attrs'
|
|
296
297
|
)
|
|
297
298
|
) {
|
|
298
299
|
needsForceUpdate = true
|
|
@@ -300,7 +301,20 @@ export function updateChildComponent(
|
|
|
300
301
|
}
|
|
301
302
|
vm.$attrs = attrs
|
|
302
303
|
|
|
303
|
-
|
|
304
|
+
// update listeners
|
|
305
|
+
listeners = listeners || emptyObject
|
|
306
|
+
const prevListeners = vm.$options._parentListeners
|
|
307
|
+
if (vm._listenersProxy) {
|
|
308
|
+
syncSetupProxy(
|
|
309
|
+
vm._listenersProxy,
|
|
310
|
+
listeners,
|
|
311
|
+
prevListeners || emptyObject,
|
|
312
|
+
vm,
|
|
313
|
+
'$listeners'
|
|
314
|
+
)
|
|
315
|
+
}
|
|
316
|
+
vm.$listeners = vm.$options._parentListeners = listeners
|
|
317
|
+
updateComponentListeners(vm, listeners, prevListeners)
|
|
304
318
|
|
|
305
319
|
// update props
|
|
306
320
|
if (propsData && vm.$options.props) {
|
|
@@ -317,12 +331,6 @@ export function updateChildComponent(
|
|
|
317
331
|
vm.$options.propsData = propsData
|
|
318
332
|
}
|
|
319
333
|
|
|
320
|
-
// update listeners
|
|
321
|
-
listeners = listeners || emptyObject
|
|
322
|
-
const oldListeners = vm.$options._parentListeners
|
|
323
|
-
vm.$options._parentListeners = listeners
|
|
324
|
-
updateComponentListeners(vm, listeners, oldListeners)
|
|
325
|
-
|
|
326
334
|
// resolve slots + force update if has children
|
|
327
335
|
if (needsForceUpdate) {
|
|
328
336
|
vm.$slots = resolveSlots(renderChildren, parentVnode.context)
|
|
@@ -19,7 +19,7 @@ if (__DEV__) {
|
|
|
19
19
|
'referenced during render. Make sure that this property is reactive, ' +
|
|
20
20
|
'either in the data option, or for class-based components, by ' +
|
|
21
21
|
'initializing the property. ' +
|
|
22
|
-
'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
|
|
22
|
+
'See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
|
|
23
23
|
target
|
|
24
24
|
)
|
|
25
25
|
}
|
|
@@ -29,7 +29,7 @@ if (__DEV__) {
|
|
|
29
29
|
`Property "${key}" must be accessed with "$data.${key}" because ` +
|
|
30
30
|
'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
|
|
31
31
|
'prevent conflicts with Vue internals. ' +
|
|
32
|
-
'See: https://vuejs.org/v2/api/#data',
|
|
32
|
+
'See: https://v2.vuejs.org/v2/api/#data',
|
|
33
33
|
target
|
|
34
34
|
)
|
|
35
35
|
}
|
|
@@ -25,7 +25,13 @@ export function initRender(vm: Component) {
|
|
|
25
25
|
const parentVnode = (vm.$vnode = options._parentVnode!) // the placeholder node in parent tree
|
|
26
26
|
const renderContext = parentVnode && (parentVnode.context as Component)
|
|
27
27
|
vm.$slots = resolveSlots(options._renderChildren, renderContext)
|
|
28
|
-
vm.$scopedSlots =
|
|
28
|
+
vm.$scopedSlots = parentVnode
|
|
29
|
+
? normalizeScopedSlots(
|
|
30
|
+
vm.$parent!,
|
|
31
|
+
parentVnode.data!.scopedSlots,
|
|
32
|
+
vm.$slots
|
|
33
|
+
)
|
|
34
|
+
: emptyObject
|
|
29
35
|
// bind the createElement fn to this instance
|
|
30
36
|
// so that we get proper render context inside it.
|
|
31
37
|
// args order: tag, data, children, normalizationType, alwaysNormalize
|
|
@@ -98,7 +104,7 @@ export function renderMixin(Vue: typeof Component) {
|
|
|
98
104
|
const vm: Component = this
|
|
99
105
|
const { render, _parentVnode } = vm.$options
|
|
100
106
|
|
|
101
|
-
if (_parentVnode) {
|
|
107
|
+
if (_parentVnode && vm._isMounted) {
|
|
102
108
|
vm.$scopedSlots = normalizeScopedSlots(
|
|
103
109
|
vm.$parent!,
|
|
104
110
|
_parentVnode.data!.scopedSlots,
|
|
@@ -127,7 +127,7 @@ function initData(vm: Component) {
|
|
|
127
127
|
__DEV__ &&
|
|
128
128
|
warn(
|
|
129
129
|
'data functions should return an object:\n' +
|
|
130
|
-
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
|
|
130
|
+
'https://v2.vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
|
|
131
131
|
vm
|
|
132
132
|
)
|
|
133
133
|
}
|
|
@@ -191,7 +191,7 @@ export function defineReactive(
|
|
|
191
191
|
} else if (getter) {
|
|
192
192
|
// #7981: for accessor properties without setter
|
|
193
193
|
return
|
|
194
|
-
} else if (isRef(value) && !isRef(newVal)) {
|
|
194
|
+
} else if (!shallow && isRef(value) && !isRef(newVal)) {
|
|
195
195
|
value.value = newVal
|
|
196
196
|
return
|
|
197
197
|
} else {
|
|
@@ -59,6 +59,15 @@ if (inBrowser && !isIE) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
const sortCompareFn = (a: Watcher, b: Watcher): number => {
|
|
63
|
+
if (a.post) {
|
|
64
|
+
if (!b.post) return 1
|
|
65
|
+
} else if (b.post) {
|
|
66
|
+
return -1
|
|
67
|
+
}
|
|
68
|
+
return a.id - b.id
|
|
69
|
+
}
|
|
70
|
+
|
|
62
71
|
/**
|
|
63
72
|
* Flush both queues and run the watchers.
|
|
64
73
|
*/
|
|
@@ -75,7 +84,7 @@ function flushSchedulerQueue() {
|
|
|
75
84
|
// user watchers are created before the render watcher)
|
|
76
85
|
// 3. If a component is destroyed during a parent component's watcher run,
|
|
77
86
|
// its watchers can be skipped.
|
|
78
|
-
queue.sort(
|
|
87
|
+
queue.sort(sortCompareFn)
|
|
79
88
|
|
|
80
89
|
// do not cache length because more watchers might be pushed
|
|
81
90
|
// as we run existing watchers
|
|
@@ -58,6 +58,7 @@ export default class Watcher implements DepTarget {
|
|
|
58
58
|
noRecurse?: boolean
|
|
59
59
|
getter: Function
|
|
60
60
|
value: any
|
|
61
|
+
post: boolean
|
|
61
62
|
|
|
62
63
|
// dev only
|
|
63
64
|
onTrack?: ((event: DebuggerEvent) => void) | undefined
|
|
@@ -70,11 +71,18 @@ export default class Watcher implements DepTarget {
|
|
|
70
71
|
options?: WatcherOptions | null,
|
|
71
72
|
isRenderWatcher?: boolean
|
|
72
73
|
) {
|
|
73
|
-
recordEffectScope(
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
recordEffectScope(
|
|
75
|
+
this,
|
|
76
|
+
// if the active effect scope is manually created (not a component scope),
|
|
77
|
+
// prioritize it
|
|
78
|
+
activeEffectScope && !activeEffectScope._vm
|
|
79
|
+
? activeEffectScope
|
|
80
|
+
: vm
|
|
81
|
+
? vm._scope
|
|
82
|
+
: undefined
|
|
83
|
+
)
|
|
84
|
+
if ((this.vm = vm) && isRenderWatcher) {
|
|
85
|
+
vm._watcher = this
|
|
78
86
|
}
|
|
79
87
|
// options
|
|
80
88
|
if (options) {
|
|
@@ -93,6 +101,7 @@ export default class Watcher implements DepTarget {
|
|
|
93
101
|
this.cb = cb
|
|
94
102
|
this.id = ++uid // uid for batching
|
|
95
103
|
this.active = true
|
|
104
|
+
this.post = false
|
|
96
105
|
this.dirty = this.lazy // for lazy watchers
|
|
97
106
|
this.deps = []
|
|
98
107
|
this.newDeps = []
|
|
@@ -103,7 +103,15 @@ function normalizeDirectives(
|
|
|
103
103
|
}
|
|
104
104
|
res[getRawDirName(dir)] = dir
|
|
105
105
|
if (vm._setupState && vm._setupState.__sfc) {
|
|
106
|
-
|
|
106
|
+
const setupDef = dir.def || resolveAsset(vm, '_setupState', 'v-' + dir.name)
|
|
107
|
+
if (typeof setupDef === 'function') {
|
|
108
|
+
dir.def = {
|
|
109
|
+
bind: setupDef,
|
|
110
|
+
update: setupDef,
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
dir.def = setupDef
|
|
114
|
+
}
|
|
107
115
|
}
|
|
108
116
|
dir.def = dir.def || resolveAsset(vm.$options, 'directives', dir.name, true)
|
|
109
117
|
}
|
package/src/core/vdom/vnode.ts
CHANGED
|
@@ -33,6 +33,7 @@ export default class VNode {
|
|
|
33
33
|
fnOptions?: ComponentOptions | null // for SSR caching
|
|
34
34
|
devtoolsMeta?: Object | null // used to store functional render context for devtools
|
|
35
35
|
fnScopeId?: string | null // functional scope id support
|
|
36
|
+
isComponentRootElement?: boolean | null // for SSR directives
|
|
36
37
|
|
|
37
38
|
constructor(
|
|
38
39
|
tag?: string,
|
package/src/types/component.ts
CHANGED
|
@@ -111,6 +111,7 @@ export declare class Component {
|
|
|
111
111
|
_setupProxy?: Record<string, any>
|
|
112
112
|
_setupContext?: SetupContext
|
|
113
113
|
_attrsProxy?: Record<string, any>
|
|
114
|
+
_listenersProxy?: Record<string, Function | Function[]>
|
|
114
115
|
_slotsProxy?: Record<string, () => VNode[]>
|
|
115
116
|
_preWatchers?: Watcher[]
|
|
116
117
|
|
package/src/v3/apiInject.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isFunction, warn } from 'core/util'
|
|
2
2
|
import { currentInstance } from './currentInstance'
|
|
3
|
+
import type { Component } from 'types/component'
|
|
3
4
|
|
|
4
5
|
export interface InjectionKey<T> extends Symbol {}
|
|
5
6
|
|
|
@@ -9,19 +10,23 @@ export function provide<T>(key: InjectionKey<T> | string | number, value: T) {
|
|
|
9
10
|
warn(`provide() can only be used inside setup().`)
|
|
10
11
|
}
|
|
11
12
|
} else {
|
|
12
|
-
let provides = currentInstance._provided
|
|
13
|
-
// by default an instance inherits its parent's provides object
|
|
14
|
-
// but when it needs to provide values of its own, it creates its
|
|
15
|
-
// own provides object using parent provides object as prototype.
|
|
16
|
-
// this way in `inject` we can simply look up injections from direct
|
|
17
|
-
// parent and let the prototype chain do the work.
|
|
18
|
-
const parentProvides =
|
|
19
|
-
currentInstance.$parent && currentInstance.$parent._provided
|
|
20
|
-
if (parentProvides === provides) {
|
|
21
|
-
provides = currentInstance._provided = Object.create(parentProvides)
|
|
22
|
-
}
|
|
23
13
|
// TS doesn't allow symbol as index type
|
|
24
|
-
|
|
14
|
+
resolveProvided(currentInstance)[key as string] = value
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function resolveProvided(vm: Component): Record<string, any> {
|
|
19
|
+
// by default an instance inherits its parent's provides object
|
|
20
|
+
// but when it needs to provide values of its own, it creates its
|
|
21
|
+
// own provides object using parent provides object as prototype.
|
|
22
|
+
// this way in `inject` we can simply look up injections from direct
|
|
23
|
+
// parent and let the prototype chain do the work.
|
|
24
|
+
const existing = vm._provided
|
|
25
|
+
const parentProvides = vm.$parent && vm.$parent._provided
|
|
26
|
+
if (parentProvides === existing) {
|
|
27
|
+
return (vm._provided = Object.create(parentProvides))
|
|
28
|
+
} else {
|
|
29
|
+
return existing
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
|