Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(runtime-core): EMPTY_ARR should be frozen to prevent changes #2419

Merged
merged 3 commits into from
Oct 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/runtime-core/src/componentProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ export function normalizePropsOptions(
}

if (!raw && !hasExtends) {
return (comp.__props = EMPTY_ARR)
return (comp.__props = EMPTY_ARR as any)
}

if (isArray(raw)) {
Expand Down
12 changes: 7 additions & 5 deletions packages/runtime-core/src/componentRenderUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ const getChildRoot = (
return [vnode, undefined]
}
const rawChildren = vnode.children as VNodeArrayChildren
const dynamicChildren = vnode.dynamicChildren as VNodeArrayChildren
const dynamicChildren = vnode.dynamicChildren
const childRoot = filterSingleRoot(rawChildren)
if (!childRoot) {
return [vnode, undefined]
Expand All @@ -235,10 +235,12 @@ const getChildRoot = (
const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1
const setRoot = (updatedRoot: VNode) => {
rawChildren[index] = updatedRoot
if (dynamicIndex > -1) {
dynamicChildren[dynamicIndex] = updatedRoot
} else if (dynamicChildren && updatedRoot.patchFlag > 0) {
dynamicChildren.push(updatedRoot)
if (dynamicChildren) {
if (dynamicIndex > -1) {
dynamicChildren[dynamicIndex] = updatedRoot
} else if (updatedRoot.patchFlag > 0) {
vnode.dynamicChildren = [...dynamicChildren, updatedRoot]
}
}
}
return [normalizeVNode(childRoot), setRoot]
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime-core/src/vnode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export function createBlock(
true /* isBlock: prevent a block from tracking itself */
)
// save current block children on the block vnode
vnode.dynamicChildren = currentBlock || EMPTY_ARR
vnode.dynamicChildren = currentBlock || (EMPTY_ARR as any)
// close block
closeBlock()
// a block is always going to be patched, so track it as a child of its
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const babelParserDefaultPlugins = [
export const EMPTY_OBJ: { readonly [key: string]: any } = __DEV__
? Object.freeze({})
: {}
export const EMPTY_ARR: [] = []
export const EMPTY_ARR = __DEV__ ? Object.freeze([]) : []

export const NOOP = () => {}

Expand Down
11 changes: 11 additions & 0 deletions packages/vue/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EMPTY_ARR } from '@vue/shared'
import { createApp, ref, nextTick, reactive } from '../src'

describe('compiler + runtime integration', () => {
Expand Down Expand Up @@ -281,4 +282,14 @@ describe('compiler + runtime integration', () => {
await nextTick()
expect(container.innerHTML).toBe(`<div>2<div>1</div></div>`)
})

// #2413
it('EMPTY_ARR should not change', () => {
const App = {
template: `<div v-for="v of ['a']">{{ v }}</div>`
}
const container = document.createElement('div')
createApp(App).mount(container)
expect(EMPTY_ARR.length).toBe(0)
})
})