}"
`;
+exports[`compiler: transform v-model simple expression (with multilines) 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
+
+ return (_openBlock(), _createBlock(\\"input\\", {
+ modelValue:
+ model
+,
+ \\"onUpdate:modelValue\\": $event => (
+ model
+ = $event)
+ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
+ }
+}"
+`;
+
exports[`compiler: transform v-model simple expression (with prefixIdentifiers) 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()
})
+ test('simple expression (with multilines)', () => {
+ const root = parseWithVModel('<input v-model="\n model \n" />')
+ const node = root.children[0] as ElementNode
+ const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
+ .properties
+
+ expect(props[0]).toMatchObject({
+ key: {
+ content: 'modelValue',
+ isStatic: true
+ },
+ value: {
+ content: '\n model \n',
+ isStatic: false
+ }
+ })
+
+ expect(props[1]).toMatchObject({
+ key: {
+ content: 'onUpdate:modelValue',
+ isStatic: true
+ },
+ value: {
+ children: [
+ '$event => (',
+ {
+ content: '\n model \n',
+ isStatic: false
+ },
+ ' = $event)'
+ ]
+ }
+ })
+
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
test('compound expression', () => {
const root = parseWithVModel('<input v-model="model[index]" />')
const node = root.children[0] as ElementNode
})
})
+ test('should handle multiple line statement', () => {
+ const { node } = parseWithVOn(`<div @click="\nfoo();\nbar()\n"/>`)
+ expect((node.codegenNode as VNodeCall).props).toMatchObject({
+ properties: [
+ {
+ key: { content: `onClick` },
+ value: {
+ type: NodeTypes.COMPOUND_EXPRESSION,
+ // should wrap with `{` for multiple statements
+ // in this case the return value is discarded and the behavior is
+ // consistent with 2.x
+ children: [`$event => {`, { content: `\nfoo();\nbar()\n` }, `}`]
+ }
+ }
+ ]
+ })
+ })
+
test('inline statement w/ prefixIdentifiers: true', () => {
const { node } = parseWithVOn(`<div @click="foo($event)"/>`, {
prefixIdentifiers: true
const expString =
exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : exp.loc.source
+
if (!isMemberExpression(expString)) {
context.onError(
createCompilerError(ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION, exp.loc)
!nonIdentifierRE.test(name)
const memberExpRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\[[^\]]+\])*$/
-export const isMemberExpression = (path: string): boolean =>
- memberExpRE.test(path)
+export const isMemberExpression = (path: string): boolean => {
+ if (!path) return false
+ return memberExpRE.test(path.trim())
+}
export function getInnerRange(
loc: SourceLocation,