fix(compiler-core): bail out to array children when the element has custom directives + only one text child node (#3757)
This commit is contained in:
parent
0e3bbd0626
commit
a56ab148fd
@ -62,6 +62,24 @@ return function render(_ctx, _cache) {
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: transform text element with custom directives and only one text child node 1`] = `
|
||||
"const _Vue = Vue
|
||||
|
||||
return function render(_ctx, _cache) {
|
||||
with (_ctx) {
|
||||
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveDirective: _resolveDirective, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
|
||||
|
||||
const _directive_foo = _resolveDirective(\\"foo\\")
|
||||
|
||||
return _withDirectives((_openBlock(), _createBlock(\\"p\\", null, [
|
||||
_createTextVNode(_toDisplayString(foo), 1 /* TEXT */)
|
||||
], 512 /* NEED_PATCH */)), [
|
||||
[_directive_foo]
|
||||
])
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: transform text no consecutive text 1`] = `
|
||||
"const _Vue = Vue
|
||||
|
||||
|
@ -4,7 +4,8 @@ import {
|
||||
transform,
|
||||
NodeTypes,
|
||||
generate,
|
||||
ForNode
|
||||
ForNode,
|
||||
ElementNode
|
||||
} from '../../src'
|
||||
import { transformFor } from '../../src/transforms/vFor'
|
||||
import { transformText } from '../../src/transforms/transformText'
|
||||
@ -20,8 +21,8 @@ function transformWithTextOpt(template: string, options: CompilerOptions = {}) {
|
||||
nodeTransforms: [
|
||||
transformFor,
|
||||
...(options.prefixIdentifiers ? [transformExpression] : []),
|
||||
transformText,
|
||||
transformElement
|
||||
transformElement,
|
||||
transformText
|
||||
],
|
||||
...options
|
||||
})
|
||||
@ -193,4 +194,29 @@ describe('compiler: transform text', () => {
|
||||
}).code
|
||||
).toMatchSnapshot()
|
||||
})
|
||||
|
||||
// #3756
|
||||
test('element with custom directives and only one text child node', () => {
|
||||
const root = transformWithTextOpt(`<p v-foo>{{ foo }}</p>`)
|
||||
expect(root.children.length).toBe(1)
|
||||
expect(root.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||
expect((root.children[0] as ElementNode).children[0]).toMatchObject({
|
||||
type: NodeTypes.TEXT_CALL,
|
||||
codegenNode: {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: CREATE_TEXT,
|
||||
arguments: [
|
||||
{
|
||||
type: NodeTypes.INTERPOLATION,
|
||||
content: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'foo'
|
||||
}
|
||||
},
|
||||
genFlagText(PatchFlags.TEXT)
|
||||
]
|
||||
}
|
||||
})
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
@ -64,6 +64,16 @@ export const transformText: NodeTransform = (node, context) => {
|
||||
(node.type === NodeTypes.ROOT ||
|
||||
(node.type === NodeTypes.ELEMENT &&
|
||||
node.tagType === ElementTypes.ELEMENT &&
|
||||
// #3756
|
||||
// custom directives can potentially add DOM elements arbitrarily,
|
||||
// we need to avoid setting textContent of the element at runtime
|
||||
// to avoid accidentally overwriting the DOM elements added
|
||||
// by the user through custom directives.
|
||||
!node.props.find(
|
||||
p =>
|
||||
p.type === NodeTypes.DIRECTIVE &&
|
||||
!context.directiveTransforms[p.name]
|
||||
) &&
|
||||
// in compat mode, <template> tags with no special directives
|
||||
// will be rendered as a fragment so its children must be
|
||||
// converted into vnodes.
|
||||
|
Loading…
Reference in New Issue
Block a user