mirror of https://github.com/vuejs/core.git
feat(compiler-vapor): support v-on for component (#175)
Co-authored-by: Kevin Deng 三咲智子 <sxzz@sxzz.moe>
This commit is contained in:
parent
bdc43226a0
commit
a49b6f91ca
|
@ -1,5 +1,20 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`generate component > generate component with emits 1`] = `
|
||||
"import { toHandlerKey as _toHandlerKey } from 'vue';
|
||||
import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createComponent(_resolveComponent("Comp"), [{
|
||||
onClick: () => (fn)
|
||||
}])
|
||||
const n1 = _createComponent(_resolveComponent("Comp"), [{
|
||||
[_toHandlerKey(eventName)]: () => (fn)
|
||||
}])
|
||||
return [n0, n1]
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`generate component > generate multi root component 1`] = `
|
||||
"import { resolveComponent as _resolveComponent, createComponent as _createComponent, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("123")
|
||||
|
|
|
@ -20,4 +20,12 @@ describe('generate component', () => {
|
|||
const { code } = compile(`<div><Comp/></div>`)
|
||||
expect(code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('generate component with emits', () => {
|
||||
const { code } = compile(`
|
||||
<Comp @click="fn" />
|
||||
<Comp @[eventName]="fn" />
|
||||
`)
|
||||
expect(code).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -86,7 +86,7 @@ function genLiteralObjectProps(
|
|||
}
|
||||
|
||||
export function genPropKey(
|
||||
{ key: node, runtimeCamelize, modifier }: IRProp,
|
||||
{ key: node, modifier, runtimeCamelize, runtimeHandler }: IRProp,
|
||||
context: CodegenContext,
|
||||
): CodeFragment[] {
|
||||
const { helper } = context
|
||||
|
@ -104,13 +104,14 @@ export function genPropKey(
|
|||
]
|
||||
}
|
||||
|
||||
const key = genExpression(node, context)
|
||||
return [
|
||||
'[',
|
||||
modifier && `${JSON.stringify(modifier)} + `,
|
||||
...(runtimeCamelize ? genCall(helper('camelize'), key) : key),
|
||||
']',
|
||||
]
|
||||
let key = genExpression(node, context)
|
||||
if (runtimeCamelize) {
|
||||
key = genCall(helper('camelize'), key)
|
||||
}
|
||||
if (runtimeHandler) {
|
||||
key = genCall(helper('toHandlerKey'), key)
|
||||
}
|
||||
return ['[', modifier && `${JSON.stringify(modifier)} + `, ...key, ']']
|
||||
}
|
||||
|
||||
function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) {
|
||||
|
|
|
@ -43,6 +43,7 @@ export interface DirectiveTransformResult {
|
|||
value: SimpleExpressionNode
|
||||
modifier?: '.' | '^'
|
||||
runtimeCamelize?: boolean
|
||||
runtimeHandler?: boolean
|
||||
}
|
||||
|
||||
// A structural directive transform is technically also a NodeTransform;
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import { ErrorCodes, createCompilerError } from '@vue/compiler-dom'
|
||||
import {
|
||||
ElementTypes,
|
||||
ErrorCodes,
|
||||
createCompilerError,
|
||||
} from '@vue/compiler-dom'
|
||||
import type { DirectiveTransform } from '../transform'
|
||||
import { IRNodeTypes, type KeyOverride, type SetEventIRNode } from '../ir'
|
||||
import { resolveModifiers } from '@vue/compiler-dom'
|
||||
import { extend, makeMap } from '@vue/shared'
|
||||
import { extend, makeMap, toHandlerKey } from '@vue/shared'
|
||||
import { resolveExpression } from '../utils'
|
||||
import { EMPTY_EXPRESSION } from './utils'
|
||||
|
||||
const delegatedEvents = /*#__PURE__*/ makeMap(
|
||||
'beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,' +
|
||||
|
@ -14,6 +19,8 @@ const delegatedEvents = /*#__PURE__*/ makeMap(
|
|||
|
||||
export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
||||
let { arg, exp, loc, modifiers } = dir
|
||||
const isComponent = node.tagType === ElementTypes.COMPONENT
|
||||
|
||||
if (!exp && (!modifiers.length || !arg)) {
|
||||
context.options.onError(
|
||||
createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc),
|
||||
|
@ -70,6 +77,18 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
|||
}
|
||||
}
|
||||
|
||||
if (isComponent) {
|
||||
if (arg.isStatic) {
|
||||
arg = extend({}, arg, { content: toHandlerKey(arg.content) })
|
||||
}
|
||||
const handler = exp || EMPTY_EXPRESSION
|
||||
return {
|
||||
key: arg,
|
||||
value: handler,
|
||||
runtimeHandler: !arg.isStatic,
|
||||
}
|
||||
}
|
||||
|
||||
const operation: SetEventIRNode = {
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
element: context.reference(),
|
||||
|
|
Loading…
Reference in New Issue