Skip to content

Commit b0bc857

Browse files
authored
Merge pull request #36 from vuejs/feat/support-root-attributes
Support root-level attributes, close #32
2 parents 5c0c710 + 96b182c commit b0bc857

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

Diff for: packages/babel-plugin-transform-vue-jsx/src/index.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ const parseAttributeJSXAttribute = (t, path, attributes, tagName, elementType) =
158158
} else {
159159
name = namePath.get('name').node
160160
}
161+
if (prefixes.includes(name) && t.isJSXExpressionContainer(path.get('value'))) {
162+
return t.JSXSpreadAttribute(t.objectExpression([t.objectProperty(t.stringLiteral(name), path.get('value').node.expression)]))
163+
}
161164

162165
;[name, ...modifiers] = name.split('_')
163166
;[name, argument] = name.split(':')
@@ -233,16 +236,24 @@ const parseAttributeJSXSpreadAttribute = (t, path, attributes, attributesArray)
233236
* @param t
234237
* @param paths Array<JSXAttribute | JSXSpreadAttribute>
235238
* @param tag Identifier | StringLiteral | MemberExpression
239+
* @param openingElementPath JSXOpeningElement
236240
* @returns Array<Expression>
237241
*/
238-
const getAttributes = (t, paths, tag) => {
242+
const getAttributes = (t, paths, tag, openingElementPath) => {
239243
const attributesArray = []
240244
let attributes = {}
241245

242246
const { tagName, canContainDomProps, elementType } = parseMagicDomPropsInfo(t, paths, tag)
243247
paths.forEach(path => {
244248
if (t.isJSXAttribute(path)) {
245-
parseAttributeJSXAttribute(t, path, attributes, tagName, elementType)
249+
const possibleSpreadNode = parseAttributeJSXAttribute(t, path, attributes, tagName, elementType)
250+
if (possibleSpreadNode) {
251+
openingElementPath.node.attributes.push(possibleSpreadNode)
252+
const attributePaths = openingElementPath.get('attributes')
253+
const lastAttributePath = attributePaths[attributePaths.length - 1]
254+
attributes = parseAttributeJSXSpreadAttribute(t, lastAttributePath, attributes, attributesArray)
255+
lastAttributePath.remove()
256+
}
246257
return
247258
}
248259
/* istanbul ignore else */
@@ -328,7 +339,8 @@ const transformAttributes = (t, attributes) =>
328339
const transformJSXElement = (t, path) => {
329340
const tag = getTag(t, path.get('openingElement'))
330341
const children = getChildren(t, path.get('children'))
331-
const attributes = getAttributes(t, path.get('openingElement.attributes'), tag)
342+
const openingElementPath = path.get('openingElement')
343+
const attributes = getAttributes(t, openingElementPath.get('attributes'), tag, openingElementPath)
332344

333345
const args = [tag]
334346
if (attributes) {

Diff for: packages/babel-plugin-transform-vue-jsx/test/snapshot.js

+15
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,21 @@ render(h => h("div", _mergeJSXProps([{}, spread, {
301301
}
302302
});`,
303303
},
304+
{
305+
name: 'Root attribute',
306+
from: `<MyComponent propsProp1="foo" props={{ prop1: 'alpha', prop2: 'beta' }} />`,
307+
to: `import _mergeJSXProps from "@vue/babel-helper-vue-jsx-merge-props";
308+
h("MyComponent", _mergeJSXProps([{
309+
"props": {
310+
"prop1": "foo"
311+
}
312+
}, {
313+
"props": {
314+
prop1: 'alpha',
315+
prop2: 'beta'
316+
}
317+
}]));`,
318+
},
304319
]
305320

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

0 commit comments

Comments
 (0)