feat(compiler-core): create transform for v-model (#146)
This commit is contained in:
parent
99bdc5a8c8
commit
87c3d2edae
@ -0,0 +1,97 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = `
|
||||||
|
"import { createVNode, createBlock, openBlock } from \\"vue\\"
|
||||||
|
|
||||||
|
export default function render() {
|
||||||
|
const _ctx = this
|
||||||
|
return (openBlock(), createBlock(\\"input\\", {
|
||||||
|
modelValue: _ctx.model[_ctx.index],
|
||||||
|
\\"onUpdate:modelValue\\": $event => (_ctx.model[_ctx.index] = $event)
|
||||||
|
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: transform v-model compound expression 1`] = `
|
||||||
|
"const _Vue = Vue
|
||||||
|
|
||||||
|
return function render() {
|
||||||
|
with (this) {
|
||||||
|
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
|
||||||
|
|
||||||
|
return (_openBlock(), _createBlock(\\"input\\", {
|
||||||
|
modelValue: model[index],
|
||||||
|
\\"onUpdate:modelValue\\": $event => (model[index] = $event)
|
||||||
|
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: transform v-model simple exprssion (with prefixIdentifiers) 1`] = `
|
||||||
|
"import { createVNode, createBlock, openBlock } from \\"vue\\"
|
||||||
|
|
||||||
|
export default function render() {
|
||||||
|
const _ctx = this
|
||||||
|
return (openBlock(), createBlock(\\"input\\", {
|
||||||
|
modelValue: _ctx.model,
|
||||||
|
\\"onUpdate:modelValue\\": $event => (_ctx.model = $event)
|
||||||
|
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: transform v-model simple exprssion 1`] = `
|
||||||
|
"const _Vue = Vue
|
||||||
|
|
||||||
|
return function render() {
|
||||||
|
with (this) {
|
||||||
|
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
|
||||||
|
|
||||||
|
return (_openBlock(), _createBlock(\\"input\\", {
|
||||||
|
modelValue: model,
|
||||||
|
\\"onUpdate:modelValue\\": $event => (model = $event)
|
||||||
|
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: transform v-model with argument 1`] = `
|
||||||
|
"const _Vue = Vue
|
||||||
|
|
||||||
|
return function render() {
|
||||||
|
with (this) {
|
||||||
|
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
|
||||||
|
|
||||||
|
return (_openBlock(), _createBlock(\\"input\\", {
|
||||||
|
value: model,
|
||||||
|
\\"onUpdate:value\\": $event => (model = $event)
|
||||||
|
}, null, 8 /* PROPS */, [\\"value\\", \\"onUpdate:value\\"]))
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = `
|
||||||
|
"import { createVNode, createBlock, openBlock } from \\"vue\\"
|
||||||
|
|
||||||
|
export default function render() {
|
||||||
|
const _ctx = this
|
||||||
|
return (openBlock(), createBlock(\\"input\\", {
|
||||||
|
[_ctx.value]: _ctx.model,
|
||||||
|
[\\"onUpdate:\\"+_ctx.value]: $event => (_ctx.model = $event)
|
||||||
|
}, null, 16 /* FULL_PROPS */))
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: transform v-model with dynamic argument 1`] = `
|
||||||
|
"const _Vue = Vue
|
||||||
|
|
||||||
|
return function render() {
|
||||||
|
with (this) {
|
||||||
|
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
|
||||||
|
|
||||||
|
return (_openBlock(), _createBlock(\\"input\\", {
|
||||||
|
[value]: model,
|
||||||
|
[\\"onUpdate:\\"+value]: $event => (model = $event)
|
||||||
|
}, null, 16 /* FULL_PROPS */))
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
355
packages/compiler-core/__tests__/transforms/vModel.spec.ts
Normal file
355
packages/compiler-core/__tests__/transforms/vModel.spec.ts
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
import {
|
||||||
|
parse,
|
||||||
|
transform,
|
||||||
|
generate,
|
||||||
|
ElementNode,
|
||||||
|
ObjectExpression,
|
||||||
|
CompilerOptions,
|
||||||
|
CallExpression
|
||||||
|
} from '../../src'
|
||||||
|
import { ErrorCodes } from '../../src/errors'
|
||||||
|
import { transformModel } from '../../src/transforms/vModel'
|
||||||
|
import { transformElement } from '../../src/transforms/transformElement'
|
||||||
|
import { transformExpression } from '../../src/transforms/transformExpression'
|
||||||
|
|
||||||
|
function parseWithVModel(template: string, options: CompilerOptions = {}) {
|
||||||
|
const ast = parse(template)
|
||||||
|
|
||||||
|
transform(ast, {
|
||||||
|
nodeTransforms: [transformExpression, transformElement],
|
||||||
|
directiveTransforms: {
|
||||||
|
...options.directiveTransforms,
|
||||||
|
model: transformModel
|
||||||
|
},
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
|
||||||
|
return ast
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('compiler: transform v-model', () => {
|
||||||
|
test('simple exprssion', () => {
|
||||||
|
const root = parseWithVModel('<input v-model="model" />')
|
||||||
|
const node = root.children[0] as ElementNode
|
||||||
|
const props = ((node.codegenNode as CallExpression)
|
||||||
|
.arguments[1] as ObjectExpression).properties
|
||||||
|
|
||||||
|
expect(props[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: 'model',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(props[1]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'onUpdate:modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
'$event => (',
|
||||||
|
{
|
||||||
|
content: 'model',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
' = $event)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(generate(root).code).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('simple exprssion (with prefixIdentifiers)', () => {
|
||||||
|
const root = parseWithVModel('<input v-model="model" />', {
|
||||||
|
prefixIdentifiers: true
|
||||||
|
})
|
||||||
|
const node = root.children[0] as ElementNode
|
||||||
|
const props = ((node.codegenNode as CallExpression)
|
||||||
|
.arguments[1] as ObjectExpression).properties
|
||||||
|
|
||||||
|
expect(props[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: '_ctx.model',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(props[1]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'onUpdate:modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
'$event => (',
|
||||||
|
{
|
||||||
|
content: '_ctx.model',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
' = $event)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('compound expression', () => {
|
||||||
|
const root = parseWithVModel('<input v-model="model[index]" />')
|
||||||
|
const node = root.children[0] as ElementNode
|
||||||
|
const props = ((node.codegenNode as CallExpression)
|
||||||
|
.arguments[1] as ObjectExpression).properties
|
||||||
|
|
||||||
|
expect(props[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: 'model[index]',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(props[1]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'onUpdate:modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
'$event => (',
|
||||||
|
{
|
||||||
|
content: 'model[index]',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
' = $event)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(generate(root).code).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('compound expression (with prefixIdentifiers)', () => {
|
||||||
|
const root = parseWithVModel('<input v-model="model[index]" />', {
|
||||||
|
prefixIdentifiers: true
|
||||||
|
})
|
||||||
|
const node = root.children[0] as ElementNode
|
||||||
|
const props = ((node.codegenNode as CallExpression)
|
||||||
|
.arguments[1] as ObjectExpression).properties
|
||||||
|
|
||||||
|
expect(props[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
content: '_ctx.model',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
'[',
|
||||||
|
{
|
||||||
|
content: '_ctx.index',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
']'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(props[1]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'onUpdate:modelValue',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
'$event => (',
|
||||||
|
{
|
||||||
|
content: '_ctx.model',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
'[',
|
||||||
|
{
|
||||||
|
content: '_ctx.index',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
']',
|
||||||
|
' = $event)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('with argument', () => {
|
||||||
|
const root = parseWithVModel('<input v-model:value="model" />')
|
||||||
|
const node = root.children[0] as ElementNode
|
||||||
|
const props = ((node.codegenNode as CallExpression)
|
||||||
|
.arguments[1] as ObjectExpression).properties
|
||||||
|
|
||||||
|
expect(props[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'value',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: 'model',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(props[1]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'onUpdate:value',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
'$event => (',
|
||||||
|
{
|
||||||
|
content: 'model',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
' = $event)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(generate(root).code).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('with dynamic argument', () => {
|
||||||
|
const root = parseWithVModel('<input v-model:[value]="model" />')
|
||||||
|
const node = root.children[0] as ElementNode
|
||||||
|
const props = ((node.codegenNode as CallExpression)
|
||||||
|
.arguments[1] as ObjectExpression).properties
|
||||||
|
|
||||||
|
expect(props[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: 'value',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: 'model',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(props[1]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
content: 'onUpdate:',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
'+',
|
||||||
|
{
|
||||||
|
content: 'value',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
'$event => (',
|
||||||
|
{
|
||||||
|
content: 'model',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
' = $event)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(generate(root).code).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('with dynamic argument (with prefixIdentifiers)', () => {
|
||||||
|
const root = parseWithVModel('<input v-model:[value]="model" />', {
|
||||||
|
prefixIdentifiers: true
|
||||||
|
})
|
||||||
|
const node = root.children[0] as ElementNode
|
||||||
|
const props = ((node.codegenNode as CallExpression)
|
||||||
|
.arguments[1] as ObjectExpression).properties
|
||||||
|
|
||||||
|
expect(props[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: '_ctx.value',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: '_ctx.model',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(props[1]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
content: 'onUpdate:',
|
||||||
|
isStatic: true
|
||||||
|
},
|
||||||
|
'+',
|
||||||
|
{
|
||||||
|
content: '_ctx.value',
|
||||||
|
isStatic: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
children: [
|
||||||
|
'$event => (',
|
||||||
|
{
|
||||||
|
content: '_ctx.model',
|
||||||
|
isStatic: false
|
||||||
|
},
|
||||||
|
' = $event)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('errors', () => {
|
||||||
|
test('missing expression', () => {
|
||||||
|
const onError = jest.fn()
|
||||||
|
parseWithVModel('<span v-model />', { onError })
|
||||||
|
|
||||||
|
expect(onError).toHaveBeenCalledTimes(1)
|
||||||
|
expect(onError).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
code: ErrorCodes.X_V_MODEL_NO_EXPRESSION
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('empty expression', () => {
|
||||||
|
const onError = jest.fn()
|
||||||
|
parseWithVModel('<span v-model="" />', { onError })
|
||||||
|
|
||||||
|
expect(onError).toHaveBeenCalledTimes(1)
|
||||||
|
expect(onError).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
code: ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -1,5 +1,9 @@
|
|||||||
import { Position } from '../src/ast'
|
import { Position, NodeTypes } from '../src/ast'
|
||||||
import { getInnerRange, advancePositionWithClone } from '../src/utils'
|
import {
|
||||||
|
getInnerRange,
|
||||||
|
advancePositionWithClone,
|
||||||
|
isEmptyExpression
|
||||||
|
} from '../src/utils'
|
||||||
|
|
||||||
function p(line: number, column: number, offset: number): Position {
|
function p(line: number, column: number, offset: number): Position {
|
||||||
return { column, line, offset }
|
return { column, line, offset }
|
||||||
@ -67,3 +71,38 @@ describe('getInnerRange', () => {
|
|||||||
expect(loc2.end.offset).toBe(7)
|
expect(loc2.end.offset).toBe(7)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('isEmptyExpression', () => {
|
||||||
|
test('empty', () => {
|
||||||
|
expect(
|
||||||
|
isEmptyExpression({
|
||||||
|
content: '',
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
isStatic: true,
|
||||||
|
loc: null as any
|
||||||
|
})
|
||||||
|
).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('spaces', () => {
|
||||||
|
expect(
|
||||||
|
isEmptyExpression({
|
||||||
|
content: ' \t ',
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
isStatic: true,
|
||||||
|
loc: null as any
|
||||||
|
})
|
||||||
|
).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('identifier', () => {
|
||||||
|
expect(
|
||||||
|
isEmptyExpression({
|
||||||
|
content: 'foo',
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
isStatic: true,
|
||||||
|
loc: null as any
|
||||||
|
})
|
||||||
|
).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@ -79,6 +79,8 @@ export const enum ErrorCodes {
|
|||||||
X_V_SLOT_DUPLICATE_SLOT_NAMES,
|
X_V_SLOT_DUPLICATE_SLOT_NAMES,
|
||||||
X_V_SLOT_EXTRANEOUS_NON_SLOT_CHILDREN,
|
X_V_SLOT_EXTRANEOUS_NON_SLOT_CHILDREN,
|
||||||
X_V_SLOT_MISPLACED,
|
X_V_SLOT_MISPLACED,
|
||||||
|
X_V_MODEL_NO_EXPRESSION,
|
||||||
|
X_V_MODEL_MALFORMED_EXPRESSION,
|
||||||
|
|
||||||
// generic errors
|
// generic errors
|
||||||
X_PREFIX_ID_NOT_SUPPORTED,
|
X_PREFIX_ID_NOT_SUPPORTED,
|
||||||
@ -167,6 +169,8 @@ export const errorMessages: { [code: number]: string } = {
|
|||||||
`Extraneous children found when component has explicit slots. ` +
|
`Extraneous children found when component has explicit slots. ` +
|
||||||
`These children will be ignored.`,
|
`These children will be ignored.`,
|
||||||
[ErrorCodes.X_V_SLOT_MISPLACED]: `v-slot can only be used on components or <template> tags.`,
|
[ErrorCodes.X_V_SLOT_MISPLACED]: `v-slot can only be used on components or <template> tags.`,
|
||||||
|
[ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`,
|
||||||
|
[ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model has invalid expression.`,
|
||||||
|
|
||||||
// generic errors
|
// generic errors
|
||||||
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
|
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
|
||||||
|
@ -1 +1,54 @@
|
|||||||
// TODO
|
import { DirectiveTransform } from '../transform'
|
||||||
|
import {
|
||||||
|
createSimpleExpression,
|
||||||
|
createObjectProperty,
|
||||||
|
createCompoundExpression,
|
||||||
|
NodeTypes,
|
||||||
|
Property
|
||||||
|
} from '../ast'
|
||||||
|
import { createCompilerError, ErrorCodes } from '../errors'
|
||||||
|
import { isEmptyExpression } from '../utils'
|
||||||
|
|
||||||
|
export const transformModel: DirectiveTransform = (dir, node, context) => {
|
||||||
|
const { exp, arg } = dir
|
||||||
|
if (!exp) {
|
||||||
|
context.onError(createCompilerError(ErrorCodes.X_V_MODEL_NO_EXPRESSION))
|
||||||
|
|
||||||
|
return createTransformProps()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmptyExpression(exp)) {
|
||||||
|
context.onError(
|
||||||
|
createCompilerError(ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION)
|
||||||
|
)
|
||||||
|
|
||||||
|
return createTransformProps()
|
||||||
|
}
|
||||||
|
|
||||||
|
const propName = arg ? arg : createSimpleExpression('modelValue', true)
|
||||||
|
const eventName = arg
|
||||||
|
? arg.type === NodeTypes.SIMPLE_EXPRESSION && arg.isStatic
|
||||||
|
? createSimpleExpression('onUpdate:' + arg.content, true)
|
||||||
|
: createCompoundExpression([
|
||||||
|
createSimpleExpression('onUpdate:', true),
|
||||||
|
'+',
|
||||||
|
...(arg.type === NodeTypes.SIMPLE_EXPRESSION ? [arg] : arg.children)
|
||||||
|
])
|
||||||
|
: createSimpleExpression('onUpdate:modelValue', true)
|
||||||
|
|
||||||
|
return createTransformProps([
|
||||||
|
createObjectProperty(propName, dir.exp!),
|
||||||
|
createObjectProperty(
|
||||||
|
eventName,
|
||||||
|
createCompoundExpression([
|
||||||
|
`$event => (`,
|
||||||
|
...(exp.type === NodeTypes.SIMPLE_EXPRESSION ? [exp] : exp.children),
|
||||||
|
` = $event)`
|
||||||
|
])
|
||||||
|
)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTransformProps(props: Property[] = []) {
|
||||||
|
return { props, needRuntime: false }
|
||||||
|
}
|
||||||
|
@ -20,7 +20,8 @@ import {
|
|||||||
BlockCodegenNode,
|
BlockCodegenNode,
|
||||||
ElementCodegenNode,
|
ElementCodegenNode,
|
||||||
SlotOutletCodegenNode,
|
SlotOutletCodegenNode,
|
||||||
ComponentCodegenNode
|
ComponentCodegenNode,
|
||||||
|
ExpressionNode
|
||||||
} from './ast'
|
} from './ast'
|
||||||
import { parse } from 'acorn'
|
import { parse } from 'acorn'
|
||||||
import { walk } from 'estree-walker'
|
import { walk } from 'estree-walker'
|
||||||
@ -237,3 +238,7 @@ export function toValidAssetId(
|
|||||||
): string {
|
): string {
|
||||||
return `_${type}_${name.replace(/[^\w]/g, '')}`
|
return `_${type}_${name.replace(/[^\w]/g, '')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isEmptyExpression(node: ExpressionNode) {
|
||||||
|
return node.type === NodeTypes.SIMPLE_EXPRESSION && !node.content.trim()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user