vBind.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import {
  2. ErrorCodes,
  3. type SimpleExpressionNode,
  4. createCompilerError,
  5. createSimpleExpression,
  6. } from '@vue/compiler-dom'
  7. import { camelize, isReservedProp } from '@vue/shared'
  8. import { IRNodeTypes } from '../ir'
  9. import type { DirectiveTransform } from '../transform'
  10. export function normalizeBindShorthand(
  11. arg: SimpleExpressionNode,
  12. ): SimpleExpressionNode {
  13. // shorthand syntax https://github.com/vuejs/core/pull/9451
  14. const propName = camelize(arg.content)
  15. const exp = createSimpleExpression(propName, false, arg.loc)
  16. exp.ast = null
  17. return exp
  18. }
  19. export const transformVBind: DirectiveTransform = (dir, node, context) => {
  20. let { arg, exp, loc, modifiers } = dir
  21. if (!arg) {
  22. // TODO support v-bind="{}"
  23. return
  24. }
  25. if (arg.isStatic && isReservedProp(arg.content)) return
  26. if (!exp) exp = normalizeBindShorthand(arg)
  27. let camel = false
  28. if (modifiers.includes('camel')) {
  29. if (arg.isStatic) {
  30. arg.content = camelize(arg.content)
  31. } else {
  32. camel = true
  33. }
  34. }
  35. if (!exp.content.trim()) {
  36. context.options.onError(
  37. createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
  38. )
  39. context.template += ` ${arg.content}=""`
  40. return
  41. }
  42. context.registerEffect(
  43. [exp],
  44. [
  45. {
  46. type: IRNodeTypes.SET_PROP,
  47. element: context.reference(),
  48. key: arg,
  49. value: exp,
  50. runtimeCamelize: camel,
  51. modifier: modifiers.includes('prop')
  52. ? '.'
  53. : modifiers.includes('attr')
  54. ? '^'
  55. : undefined,
  56. },
  57. ],
  58. )
  59. }