mirror of https://github.com/vuejs/core.git
fix(compiler-vapor): cache setDynamicProps deps when possible
This commit is contained in:
parent
1bd7136775
commit
21e241c85e
|
@ -206,7 +206,7 @@ exports[`compile > expression parsing > v-bind 1`] = `
|
|||
"
|
||||
const n0 = t0()
|
||||
let _key_value, _foo, _key_value_foo
|
||||
_renderEffect(() => (_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true)))
|
||||
_renderEffect(() => (_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)))
|
||||
return n0
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -195,7 +195,7 @@ describe('compile', () => {
|
|||
expect(code).matchSnapshot()
|
||||
expect(code).contains('key.value+1')
|
||||
expect(code).contains(
|
||||
'(_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true))',
|
||||
'(_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true))',
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -346,10 +346,10 @@ exports[`compiler: element transform > v-bind="obj" 1`] = `
|
|||
"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
export function render(_ctx, $props, $emit, $attrs, $slots) {
|
||||
const n0 = t0()
|
||||
let _obj, _prev_obj
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj], true)))
|
||||
let _prev_obj
|
||||
_renderEffect(() => _prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -358,10 +358,10 @@ exports[`compiler: element transform > v-bind="obj" after static prop 1`] = `
|
|||
"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
export function render(_ctx, $props, $emit, $attrs, $slots) {
|
||||
const n0 = t0()
|
||||
let _obj, _prev_obj
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, _ctx.obj], true)))
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, (_obj = _ctx.obj)], true)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -370,10 +370,10 @@ exports[`compiler: element transform > v-bind="obj" before static prop 1`] = `
|
|||
"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
export function render(_ctx, $props, $emit, $attrs, $slots) {
|
||||
const n0 = t0()
|
||||
let _obj, _prev_obj
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj, { id: "foo" }], true)))
|
||||
let _prev_obj
|
||||
_renderEffect(() => _prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj, { id: "foo" }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -385,7 +385,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _obj, _prev_obj
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true)))
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, (_obj = _ctx.obj), { class: "bar" }], true)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -79,7 +79,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _id, _prev_id
|
||||
_renderEffect(() => _id !== _ctx.id && (_prev_id = _setDynamicProp(n0, "fooBar", _prev_id, _ctx.id)))
|
||||
_renderEffect(() => _id !== _ctx.id && (_prev_id = _setDynamicProp(n0, "fooBar", _prev_id, (_id = _ctx.id))))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -91,7 +91,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _foo, _id, _foo_id
|
||||
_renderEffect(() => (_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize(_ctx.foo)]: _ctx.id }], true)))
|
||||
_renderEffect(() => (_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -103,7 +103,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _fooBar, _prev_fooBar
|
||||
_renderEffect(() => _fooBar !== _ctx.fooBar && (_prev_fooBar = _setDynamicProp(n0, "fooBar", _prev_fooBar, _ctx.fooBar)))
|
||||
_renderEffect(() => _fooBar !== _ctx.fooBar && (_prev_fooBar = _setDynamicProp(n0, "fooBar", _prev_fooBar, (_fooBar = _ctx.fooBar))))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -199,7 +199,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _fooBar, _id, _fooBar_id
|
||||
_renderEffect(() => (_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + _ctx.fooBar]: _ctx.id }], true)))
|
||||
_renderEffect(() => (_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -307,7 +307,7 @@ const t0 = _template("<progress></progress>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _foo, _prev_foo
|
||||
_renderEffect(() => _foo !== _ctx.foo && (_prev_foo = _setDynamicProp(n0, "value", _prev_foo, _ctx.foo)))
|
||||
_renderEffect(() => _foo !== _ctx.foo && (_prev_foo = _setDynamicProp(n0, "value", _prev_foo, (_foo = _ctx.foo))))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -440,7 +440,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _id, _title, _id_title
|
||||
_renderEffect(() => (_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true)))
|
||||
_renderEffect(() => (_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -452,7 +452,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _id, _prev_id
|
||||
_renderEffect(() => _id !== _ctx.id && (_prev_id = _setDynamicProps(n0, _prev_id, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true)))
|
||||
_renderEffect(() => _id !== _ctx.id && (_prev_id = _setDynamicProps(n0, _prev_id, [{ [(_id = _ctx.id)]: _ctx.id, foo: "bar", checked: "" }], true)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -464,7 +464,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
let _camelCase, _prev_camelCase
|
||||
_renderEffect(() => _camelCase !== _ctx.camelCase && (_prev_camelCase = _setDynamicProp(n0, "camel-case", _prev_camelCase, _ctx.camelCase)))
|
||||
_renderEffect(() => _camelCase !== _ctx.camelCase && (_prev_camelCase = _setDynamicProp(n0, "camel-case", _prev_camelCase, (_camelCase = _ctx.camelCase))))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -243,7 +243,7 @@ export function render(_ctx) {
|
|||
_withDirectives(n0, [[_vModelDynamic, () => _ctx.model]])
|
||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||
let _obj, _prev_obj
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj], true)))
|
||||
_renderEffect(() => _obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [(_obj = _ctx.obj)], true)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -543,7 +543,11 @@ describe('compiler: element transform', () => {
|
|||
})
|
||||
|
||||
test('v-bind="obj"', () => {
|
||||
const { code, ir } = compileWithElementTransform(`<div v-bind="obj" />`)
|
||||
const { code, ir } = compileWithElementTransform(`<div v-bind="obj" />`, {
|
||||
bindingMetadata: {
|
||||
obj: BindingTypes.SETUP_REACTIVE_CONST,
|
||||
},
|
||||
})
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(ir.block.effect).toMatchObject([
|
||||
{
|
||||
|
@ -573,13 +577,18 @@ describe('compiler: element transform', () => {
|
|||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
'_obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj], true))',
|
||||
'_prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj], true)',
|
||||
)
|
||||
})
|
||||
|
||||
test('v-bind="obj" after static prop', () => {
|
||||
const { code, ir } = compileWithElementTransform(
|
||||
`<div id="foo" v-bind="obj" />`,
|
||||
{
|
||||
bindingMetadata: {
|
||||
obj: BindingTypes.SETUP_REF,
|
||||
},
|
||||
},
|
||||
)
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(ir.block.effect).toMatchObject([
|
||||
|
@ -611,13 +620,18 @@ describe('compiler: element transform', () => {
|
|||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
'_obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, _ctx.obj], true))',
|
||||
'_obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, (_obj = _ctx.obj)], true))',
|
||||
)
|
||||
})
|
||||
|
||||
test('v-bind="obj" before static prop', () => {
|
||||
const { code, ir } = compileWithElementTransform(
|
||||
`<div v-bind="obj" id="foo" />`,
|
||||
{
|
||||
bindingMetadata: {
|
||||
obj: BindingTypes.SETUP_REACTIVE_CONST,
|
||||
},
|
||||
},
|
||||
)
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(ir.block.effect).toMatchObject([
|
||||
|
@ -639,7 +653,7 @@ describe('compiler: element transform', () => {
|
|||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
'_obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj, { id: "foo" }], true))',
|
||||
'_prev_obj = _setDynamicProps(n0, _prev_obj, [_ctx.obj, { id: "foo" }], true)',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -668,7 +682,7 @@ describe('compiler: element transform', () => {
|
|||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
'_obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true))',
|
||||
'_obj !== _ctx.obj && (_prev_obj = _setDynamicProps(n0, _prev_obj, [{ id: "foo" }, (_obj = _ctx.obj), { class: "bar" }], true))',
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains(
|
||||
'_camelCase !== _ctx.camelCase && (_prev_camelCase = _setDynamicProp(n0, "camel-case", _prev_camelCase, _ctx.camelCase))',
|
||||
'_camelCase !== _ctx.camelCase && (_prev_camelCase = _setDynamicProp(n0, "camel-case", _prev_camelCase, (_camelCase = _ctx.camelCase)))',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -177,7 +177,7 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
})
|
||||
expect(code).contains(
|
||||
'(_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true))',
|
||||
'(_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true))',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -230,7 +230,7 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
})
|
||||
expect(code).contains(
|
||||
'_id !== _ctx.id && (_prev_id = _setDynamicProps(n0, _prev_id, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true))',
|
||||
'_id !== _ctx.id && (_prev_id = _setDynamicProps(n0, _prev_id, [{ [(_id = _ctx.id)]: _ctx.id, foo: "bar", checked: "" }], true))',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -293,7 +293,7 @@ describe('compiler v-bind', () => {
|
|||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains(
|
||||
'_id !== _ctx.id && (_prev_id = _setDynamicProp(n0, "fooBar", _prev_id, _ctx.id))',
|
||||
'_id !== _ctx.id && (_prev_id = _setDynamicProp(n0, "fooBar", _prev_id, (_id = _ctx.id)))',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -319,7 +319,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains(
|
||||
'_fooBar !== _ctx.fooBar && (_prev_fooBar = _setDynamicProp(n0, "fooBar", _prev_fooBar, _ctx.fooBar))',
|
||||
'_fooBar !== _ctx.fooBar && (_prev_fooBar = _setDynamicProp(n0, "fooBar", _prev_fooBar, (_fooBar = _ctx.fooBar)))',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -351,7 +351,7 @@ describe('compiler v-bind', () => {
|
|||
expect(code).matchSnapshot()
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains(
|
||||
`(_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize(_ctx.foo)]: _ctx.id }], true))`,
|
||||
`(_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true))`,
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -436,7 +436,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains(
|
||||
`(_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + _ctx.fooBar]: _ctx.id }], true))`,
|
||||
`(_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true))`,
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -788,7 +788,7 @@ describe('compiler v-bind', () => {
|
|||
`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains(
|
||||
'_foo !== _ctx.foo && (_prev_foo = _setDynamicProp(n0, "value", _prev_foo, _ctx.foo))',
|
||||
'_foo !== _ctx.foo && (_prev_foo = _setDynamicProp(n0, "value", _prev_foo, (_foo = _ctx.foo)))',
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -112,11 +112,11 @@ export function genEffect(
|
|||
context: CodegenContext,
|
||||
allDeclareNames: Set<string>,
|
||||
): CodeFragment[] {
|
||||
const { processingRenderEffect } = context
|
||||
const [frag, push] = buildCodeFragment()
|
||||
const { declareNames, earlyCheckExps } = processingRenderEffect!
|
||||
const operationsExps = genOperations(operations, context)
|
||||
|
||||
const { processingRenderEffect } = context
|
||||
const { declareNames, earlyCheckExps } = processingRenderEffect!
|
||||
if (declareNames.size) {
|
||||
allDeclareNames.add([...declareNames].join(', '))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
BindingTypes,
|
||||
NewlineType,
|
||||
type SimpleExpressionNode,
|
||||
isSimpleIdentifier,
|
||||
|
@ -243,22 +244,28 @@ function processPropValues(
|
|||
const { shouldCacheRenderEffectDeps, processingRenderEffect } = context
|
||||
// single-line render effect and the operation needs cache return a value,
|
||||
// the expression needs to be wrapped in parentheses.
|
||||
// e.g. _foo === _ctx.foo && (_foo = _setStyle(...))
|
||||
// e.g. _foo === _ctx.foo && (_prev_foo = _setStyle(...))
|
||||
let shouldWrapInParentheses: boolean = false
|
||||
let prevValueName
|
||||
if (shouldCacheRenderEffectDeps()) {
|
||||
const { declareNames, operations, identifiers } = processingRenderEffect!
|
||||
// if render effect rely on any reactive object, it should not cache
|
||||
const canCache = identifiers.every(name => canCacheValue(context, name))
|
||||
const needReturnValue = helpersNeedCachedReturnValue.includes(helperName)
|
||||
processValues(context, values, !needReturnValue)
|
||||
const { declareNames } = processingRenderEffect!
|
||||
processValues(context, values, canCache)
|
||||
// if the operation needs to cache the return value and has multiple declareNames,
|
||||
// combine them into a single name as the return value name.
|
||||
if (declareNames.size > 0 && needReturnValue) {
|
||||
const names = [...declareNames]
|
||||
prevValueName =
|
||||
declareNames.size === 1 ? `_prev${names[0]}` : names.join('')
|
||||
if (!canCache) {
|
||||
declareNames.clear()
|
||||
processingRenderEffect!.earlyCheckExps.splice(0)
|
||||
}
|
||||
declareNames.add(prevValueName)
|
||||
}
|
||||
shouldWrapInParentheses = processingRenderEffect!.operations.length === 1
|
||||
shouldWrapInParentheses = operations.length === 1 && canCache
|
||||
}
|
||||
return { prevValueName, shouldWrapInParentheses }
|
||||
}
|
||||
|
@ -271,8 +278,7 @@ export function processValues(
|
|||
const allCheckExps: string[] = []
|
||||
values.forEach(value => {
|
||||
const checkExps = processValue(context, value, needRewrite)
|
||||
if (checkExps && checkExps.length > 0)
|
||||
allCheckExps.push(...checkExps, ' && ')
|
||||
if (checkExps && checkExps.length > 0) allCheckExps.push(...checkExps)
|
||||
})
|
||||
|
||||
return allCheckExps.length > 0
|
||||
|
@ -319,6 +325,13 @@ function processValue(
|
|||
}
|
||||
|
||||
if (earlyCheckExps.length > 0) {
|
||||
return [[...new Set(earlyCheckExps)].join(' && ')]
|
||||
return [...new Set(earlyCheckExps)]
|
||||
}
|
||||
}
|
||||
|
||||
function canCacheValue(context: CodegenContext, name: string): boolean {
|
||||
const {
|
||||
options: { bindingMetadata },
|
||||
} = context
|
||||
return bindingMetadata[name] !== BindingTypes.SETUP_REACTIVE_CONST
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue