Skip to content

Commit

Permalink
Merge pull request vuejs#36 from vuejs/feat/support-root-attributes
Browse files Browse the repository at this point in the history
Support root-level attributes, close vuejs#32
  • Loading branch information
nickmessing authored Jan 6, 2019
2 parents 5c0c710 + 96b182c commit b0bc857
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
18 changes: 15 additions & 3 deletions packages/babel-plugin-transform-vue-jsx/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ const parseAttributeJSXAttribute = (t, path, attributes, tagName, elementType) =
} else {
name = namePath.get('name').node
}
if (prefixes.includes(name) && t.isJSXExpressionContainer(path.get('value'))) {
return t.JSXSpreadAttribute(t.objectExpression([t.objectProperty(t.stringLiteral(name), path.get('value').node.expression)]))
}

;[name, ...modifiers] = name.split('_')
;[name, argument] = name.split(':')
Expand Down Expand Up @@ -233,16 +236,24 @@ const parseAttributeJSXSpreadAttribute = (t, path, attributes, attributesArray)
* @param t
* @param paths Array<JSXAttribute | JSXSpreadAttribute>
* @param tag Identifier | StringLiteral | MemberExpression
* @param openingElementPath JSXOpeningElement
* @returns Array<Expression>
*/
const getAttributes = (t, paths, tag) => {
const getAttributes = (t, paths, tag, openingElementPath) => {
const attributesArray = []
let attributes = {}

const { tagName, canContainDomProps, elementType } = parseMagicDomPropsInfo(t, paths, tag)
paths.forEach(path => {
if (t.isJSXAttribute(path)) {
parseAttributeJSXAttribute(t, path, attributes, tagName, elementType)
const possibleSpreadNode = parseAttributeJSXAttribute(t, path, attributes, tagName, elementType)
if (possibleSpreadNode) {
openingElementPath.node.attributes.push(possibleSpreadNode)
const attributePaths = openingElementPath.get('attributes')
const lastAttributePath = attributePaths[attributePaths.length - 1]
attributes = parseAttributeJSXSpreadAttribute(t, lastAttributePath, attributes, attributesArray)
lastAttributePath.remove()
}
return
}
/* istanbul ignore else */
Expand Down Expand Up @@ -328,7 +339,8 @@ const transformAttributes = (t, attributes) =>
const transformJSXElement = (t, path) => {
const tag = getTag(t, path.get('openingElement'))
const children = getChildren(t, path.get('children'))
const attributes = getAttributes(t, path.get('openingElement.attributes'), tag)
const openingElementPath = path.get('openingElement')
const attributes = getAttributes(t, openingElementPath.get('attributes'), tag, openingElementPath)

const args = [tag]
if (attributes) {
Expand Down
15 changes: 15 additions & 0 deletions packages/babel-plugin-transform-vue-jsx/test/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,21 @@ render(h => h("div", _mergeJSXProps([{}, spread, {
}
});`,
},
{
name: 'Root attribute',
from: `<MyComponent propsProp1="foo" props={{ prop1: 'alpha', prop2: 'beta' }} />`,
to: `import _mergeJSXProps from "@vue/babel-helper-vue-jsx-merge-props";
h("MyComponent", _mergeJSXProps([{
"props": {
"prop1": "foo"
}
}, {
"props": {
prop1: 'alpha',
prop2: 'beta'
}
}]));`,
},
]

tests.forEach(({ name, from, to }) => test(name, async t => t.is(await transpile(from), to)))
Expand Down

0 comments on commit b0bc857

Please sign in to comment.