fix(compiler): patchFlag analysis should factor in props returned by directive transforms
This commit is contained in:
parent
095f5edf8d
commit
6059fe69e8
@ -292,18 +292,20 @@ describe('compiler: element transform', () => {
|
||||
}
|
||||
]
|
||||
})
|
||||
// should factor in props returned by custom directive transforms
|
||||
// in patchFlag analysis
|
||||
expect(node.arguments[3]).toMatch(PatchFlags.PROPS + '')
|
||||
expect(node.arguments[4]).toMatch(`"bar"`)
|
||||
})
|
||||
|
||||
test('directiveTransform with needRuntime: true', () => {
|
||||
let _dir: DirectiveNode
|
||||
const { root, node } = parseWithElementTransform(
|
||||
`<div v-foo:bar="hello" />`,
|
||||
{
|
||||
directiveTransforms: {
|
||||
foo(dir) {
|
||||
_dir = dir
|
||||
foo() {
|
||||
return {
|
||||
props: [createObjectProperty(dir.arg!, dir.exp!)],
|
||||
props: [],
|
||||
needRuntime: true
|
||||
}
|
||||
}
|
||||
@ -320,16 +322,7 @@ describe('compiler: element transform', () => {
|
||||
callee: `_${CREATE_VNODE}`,
|
||||
arguments: [
|
||||
`"div"`,
|
||||
{
|
||||
type: NodeTypes.JS_OBJECT_EXPRESSION,
|
||||
properties: [
|
||||
{
|
||||
type: NodeTypes.JS_PROPERTY,
|
||||
key: _dir!.arg,
|
||||
value: _dir!.exp
|
||||
}
|
||||
]
|
||||
},
|
||||
`null`,
|
||||
`null`,
|
||||
`${PatchFlags.NEED_PATCH} /* NEED_PATCH */` // should generate appropriate flag
|
||||
]
|
||||
|
@ -185,11 +185,30 @@ export function buildProps(
|
||||
|
||||
// patchFlag analysis
|
||||
let patchFlag = 0
|
||||
const dynamicPropNames: string[] = []
|
||||
let hasDynamicKeys = false
|
||||
let hasRef = false
|
||||
let hasClassBinding = false
|
||||
let hasStyleBinding = false
|
||||
let hasRef = false
|
||||
let hasDynamicKeys = false
|
||||
const dynamicPropNames: string[] = []
|
||||
|
||||
const anaylizePatchFlag = ({ key, value }: Property) => {
|
||||
if (key.type === NodeTypes.SIMPLE_EXPRESSION && key.isStatic) {
|
||||
if (value.type !== NodeTypes.SIMPLE_EXPRESSION || !value.isStatic) {
|
||||
const name = key.content
|
||||
if (name === 'ref') {
|
||||
hasRef = true
|
||||
} else if (name === 'class') {
|
||||
hasClassBinding = true
|
||||
} else if (name === 'style') {
|
||||
hasStyleBinding = true
|
||||
} else if (name !== 'key') {
|
||||
dynamicPropNames.push(key.content)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hasDynamicKeys = true
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
// static attribute
|
||||
@ -229,7 +248,8 @@ export function buildProps(
|
||||
|
||||
// special case for v-bind and v-on with no argument
|
||||
const isBind = name === 'bind'
|
||||
if (!arg && (isBind || name === 'on')) {
|
||||
const isOn = name === 'on'
|
||||
if (!arg && (isBind || isOn)) {
|
||||
hasDynamicKeys = true
|
||||
if (exp) {
|
||||
if (properties.length) {
|
||||
@ -262,32 +282,16 @@ export function buildProps(
|
||||
continue
|
||||
}
|
||||
|
||||
// patchFlag analysis
|
||||
if (isBind && arg) {
|
||||
if (arg.type === NodeTypes.SIMPLE_EXPRESSION && arg.isStatic) {
|
||||
const name = arg.content
|
||||
if (name === 'ref') {
|
||||
hasRef = true
|
||||
} else if (name === 'class') {
|
||||
hasClassBinding = true
|
||||
} else if (name === 'style') {
|
||||
hasStyleBinding = true
|
||||
} else if (name !== 'key') {
|
||||
dynamicPropNames.push(name)
|
||||
}
|
||||
} else {
|
||||
hasDynamicKeys = true
|
||||
}
|
||||
}
|
||||
|
||||
const directiveTransform = context.directiveTransforms[name]
|
||||
if (directiveTransform) {
|
||||
// has built-in directive transform.
|
||||
const { props, needRuntime } = directiveTransform(prop, context)
|
||||
if (isArray(props)) {
|
||||
properties.push(...props)
|
||||
properties.forEach(anaylizePatchFlag)
|
||||
} else {
|
||||
properties.push(props)
|
||||
anaylizePatchFlag(props)
|
||||
}
|
||||
if (needRuntime) {
|
||||
runtimeDirectives.push(prop)
|
||||
@ -325,7 +329,7 @@ export function buildProps(
|
||||
)
|
||||
}
|
||||
|
||||
// determine the flags to add
|
||||
// patchFlag analysis
|
||||
if (hasDynamicKeys) {
|
||||
patchFlag |= PatchFlags.FULL_PROPS
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user