"
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
"
`;
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))',
)
})
"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
}"
`;
"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
}"
`;
"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
}"
`;
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
}"
`;
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
}"
`;
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
}"
`;
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
}"
`;
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
}"
`;
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
}"
`;
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
}"
`;
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
}"
`;
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
}"
`;
_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
}"
`;
})
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([
{
},
])
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([
},
])
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([
},
])
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)',
)
})
},
])
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))',
)
})
},
})
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)))',
)
})
],
})
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))',
)
})
],
})
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))',
)
})
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)))',
)
})
})
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)))',
)
})
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))`,
)
})
})
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))`,
)
})
`)
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)))',
)
})
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(', '))
}
import {
+ BindingTypes,
NewlineType,
type SimpleExpressionNode,
isSimpleIdentifier,
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 }
}
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
}
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
+}