feat: support v-bind .prop & .attr modifiers
Also allows render function usage like the following:
```js
h({
'.prop': 1, // force set as property
'^attr': 'foo' // force set as attribute
})
```
This commit is contained in:
@@ -700,21 +700,26 @@ export function buildProps(
|
||||
// but still need to deal with dynamic key binding
|
||||
let classKeyIndex = -1
|
||||
let styleKeyIndex = -1
|
||||
let dynamicKeyIndex = -1
|
||||
let hasDynamicKey = false
|
||||
|
||||
for (let i = 0; i < propsExpression.properties.length; i++) {
|
||||
const p = propsExpression.properties[i]
|
||||
if (p.key.type !== NodeTypes.SIMPLE_EXPRESSION) continue
|
||||
if (!isStaticExp(p.key)) dynamicKeyIndex = i
|
||||
if (isStaticExp(p.key) && p.key.content === 'class') classKeyIndex = i
|
||||
if (isStaticExp(p.key) && p.key.content === 'style') styleKeyIndex = i
|
||||
const key = propsExpression.properties[i].key
|
||||
if (isStaticExp(key)) {
|
||||
if (key.content === 'class') {
|
||||
classKeyIndex = i
|
||||
} else if (key.content === 'style') {
|
||||
styleKeyIndex = i
|
||||
}
|
||||
} else if (!key.isHandlerKey) {
|
||||
hasDynamicKey = true
|
||||
}
|
||||
}
|
||||
|
||||
const classProp = propsExpression.properties[classKeyIndex]
|
||||
const styleProp = propsExpression.properties[styleKeyIndex]
|
||||
|
||||
// no dynamic key
|
||||
if (dynamicKeyIndex === -1) {
|
||||
if (!hasDynamicKey) {
|
||||
if (classProp && !isStaticExp(classProp.value)) {
|
||||
classProp.value = createCallExpression(
|
||||
context.helper(NORMALIZE_CLASS),
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { DirectiveTransform } from '../transform'
|
||||
import { createObjectProperty, createSimpleExpression, NodeTypes } from '../ast'
|
||||
import {
|
||||
createObjectProperty,
|
||||
createSimpleExpression,
|
||||
ExpressionNode,
|
||||
NodeTypes
|
||||
} from '../ast'
|
||||
import { createCompilerError, ErrorCodes } from '../errors'
|
||||
import { camelize } from '@vue/shared'
|
||||
import { CAMELIZE } from '../runtimeHelpers'
|
||||
@@ -18,7 +23,6 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
||||
arg.content = `${arg.content} || ""`
|
||||
}
|
||||
|
||||
// .prop is no longer necessary due to new patch behavior
|
||||
// .sync is replaced by v-model:arg
|
||||
if (modifiers.includes('camel')) {
|
||||
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||
@@ -33,6 +37,14 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (modifiers.includes('prop')) {
|
||||
injectPrefix(arg, '.')
|
||||
}
|
||||
|
||||
if (modifiers.includes('attr')) {
|
||||
injectPrefix(arg, '^')
|
||||
}
|
||||
|
||||
if (
|
||||
!exp ||
|
||||
(exp.type === NodeTypes.SIMPLE_EXPRESSION && !exp.content.trim())
|
||||
@@ -47,3 +59,16 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
||||
props: [createObjectProperty(arg!, exp)]
|
||||
}
|
||||
}
|
||||
|
||||
const injectPrefix = (arg: ExpressionNode, prefix: string) => {
|
||||
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||
if (arg.isStatic) {
|
||||
arg.content = prefix + arg.content
|
||||
} else {
|
||||
arg.content = `\`${prefix}\${${arg.content}}\``
|
||||
}
|
||||
} else {
|
||||
arg.children.unshift(`'${prefix}' + (`)
|
||||
arg.children.push(`)`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,5 +163,7 @@ export const transformOn: DirectiveTransform = (
|
||||
ret.props[0].value = context.cache(ret.props[0].value)
|
||||
}
|
||||
|
||||
// mark the key as handler for props normalization check
|
||||
ret.props.forEach(p => (p.key.isHandlerKey = true))
|
||||
return ret
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user