| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- import type { DirectiveTransform } from '../transform'
- import {
- type ExpressionNode,
- NodeTypes,
- createObjectProperty,
- createSimpleExpression,
- } from '../ast'
- import { ErrorCodes, createCompilerError } from '../errors'
- import { camelize } from '@vue/shared'
- import { CAMELIZE } from '../runtimeHelpers'
- // v-bind without arg is handled directly in ./transformElement.ts due to its affecting
- // codegen for the entire props object. This transform here is only for v-bind
- // *with* args.
- export const transformBind: DirectiveTransform = (dir, _node, context) => {
- const { modifiers, loc } = dir
- const arg = dir.arg!
- let { exp } = dir
- // handle empty expression
- if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION && !exp.content.trim()) {
- if (!__BROWSER__) {
- // #10280 only error against empty expression in non-browser build
- // because :foo in in-DOM templates will be parsed into :foo="" by the
- // browser
- context.onError(
- createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
- )
- return {
- props: [
- createObjectProperty(arg, createSimpleExpression('', true, loc)),
- ],
- }
- } else {
- exp = undefined
- }
- }
- if (arg.type !== NodeTypes.SIMPLE_EXPRESSION) {
- arg.children.unshift(`(`)
- arg.children.push(`) || ""`)
- } else if (!arg.isStatic) {
- arg.content = arg.content ? `${arg.content} || ""` : `""`
- }
- // .sync is replaced by v-model:arg
- if (modifiers.some(mod => mod.content === 'camel')) {
- if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
- if (arg.isStatic) {
- arg.content = camelize(arg.content)
- } else {
- arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`
- }
- } else {
- arg.children.unshift(`${context.helperString(CAMELIZE)}(`)
- arg.children.push(`)`)
- }
- }
- if (!context.inSSR) {
- if (modifiers.some(mod => mod.content === 'prop')) {
- injectPrefix(arg, '.')
- }
- if (modifiers.some(mod => mod.content === 'attr')) {
- injectPrefix(arg, '^')
- }
- }
- return {
- props: [createObjectProperty(arg, exp!)],
- }
- }
- const injectPrefix = (arg: ExpressionNode, prefix: string) => {
- if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
- if (arg.isStatic) {
- arg.content = prefix + arg.content
- } else {
- arg.content = `\`${prefix}\${${arg.content}}\``
- }
- } else {
- arg.children.unshift(`'${prefix}' + (`)
- arg.children.push(`)`)
- }
- }
|