diff --git a/packages/language-core/lib/codegen/template/elementEvents.ts b/packages/language-core/lib/codegen/template/elementEvents.ts index b8646dd7f0..e6ec49a56a 100644 --- a/packages/language-core/lib/codegen/template/elementEvents.ts +++ b/packages/language-core/lib/codegen/template/elementEvents.ts @@ -1,8 +1,7 @@ import * as CompilerDOM from '@vue/compiler-dom'; import { camelize, capitalize } from '@vue/shared'; import type * as ts from 'typescript'; -import type { Code, VueCodeInformation } from '../../types'; -import { hyphenateAttr } from '../../utils/shared'; +import type { Code } from '../../types'; import { combineLastMapping, createTsAst, endOfLine, newLine, variableNameRegex, wrapWith } from '../utils'; import { generateCamelized } from '../utils/camelized'; import type { TemplateCodegenContext } from './context'; @@ -32,9 +31,18 @@ export function* generateElementEvents( propsVar = ctx.getInternalVariable(); yield `let ${propsVar}!: __VLS_FunctionalComponentProps${endOfLine}`; } - const originalPropName = camelize('on-' + prop.arg.loc.source); - yield `const ${ctx.getInternalVariable()}: __VLS_NormalizeComponentEvent = {${newLine}`; - yield* generateEventArg(ctx, prop.arg, true); + let source = prop.arg.loc.source; + let start = prop.arg.loc.start.offset; + let propPrefix = 'on'; + let emitPrefix = ''; + if (source.startsWith('vue:')) { + source = source.slice('vue:'.length); + start = start + 'vue:'.length; + propPrefix = 'onVnode'; + emitPrefix = 'vnode-'; + } + yield `const ${ctx.getInternalVariable()}: __VLS_NormalizeComponentEvent = {${newLine}`; + yield* generateEventArg(ctx, source, start, propPrefix); yield `: `; yield* generateEventExpression(options, ctx, prop); yield `}${endOfLine}`; @@ -43,54 +51,36 @@ export function* generateElementEvents( return usedComponentEventsVar; } -const eventArgFeatures: VueCodeInformation = { - navigation: { - // @click-outside -> onClickOutside - resolveRenameNewName(newName) { - return camelize('on-' + newName); - }, - // onClickOutside -> @click-outside - resolveRenameEditText(newName) { - const hName = hyphenateAttr(newName); - if (hyphenateAttr(newName).startsWith('on-')) { - return camelize(hName.slice('on-'.length)); - } - return newName; - }, - }, -}; - export function* generateEventArg( ctx: TemplateCodegenContext, - arg: CompilerDOM.SimpleExpressionNode, - enableHover: boolean + name: string, + start: number, + directive = 'on' ): Generator { - const features = enableHover - ? { - ...ctx.codeFeatures.withoutHighlightAndCompletion, - ...eventArgFeatures, - } - : eventArgFeatures; - if (variableNameRegex.test(camelize(arg.loc.source))) { - yield ['', 'template', arg.loc.start.offset, features]; - yield `on`; + const features = { + ...ctx.codeFeatures.withoutHighlightAndCompletion, + ...ctx.codeFeatures.navigationWithoutRename, + }; + if (variableNameRegex.test(camelize(name))) { + yield ['', 'template', start, features]; + yield directive; yield* generateCamelized( - capitalize(arg.loc.source), - arg.loc.start.offset, + capitalize(name), + start, combineLastMapping ); } else { yield* wrapWith( - arg.loc.start.offset, - arg.loc.end.offset, + start, + start + name.length, features, `'`, - ['', 'template', arg.loc.start.offset, combineLastMapping], - 'on', + ['', 'template', start, combineLastMapping], + directive, ...generateCamelized( - capitalize(arg.loc.source), - arg.loc.start.offset, + capitalize(name), + start, combineLastMapping ), `'` diff --git a/packages/language-core/lib/codegen/template/elementProps.ts b/packages/language-core/lib/codegen/template/elementProps.ts index 20e2bc7ff4..1557aad18c 100644 --- a/packages/language-core/lib/codegen/template/elementProps.ts +++ b/packages/language-core/lib/codegen/template/elementProps.ts @@ -44,7 +44,7 @@ export function* generateElementProps( ) { if (!isComponent) { yield `...{ `; - yield* generateEventArg(ctx, prop.arg, true); + yield* generateEventArg(ctx, prop.arg.loc.source, prop.arg.loc.start.offset); yield `: `; yield* generateEventExpression(options, ctx, prop); yield `},`; diff --git a/packages/language-service/lib/plugins/vue-template.ts b/packages/language-service/lib/plugins/vue-template.ts index 54f4db2638..d76c55d2ef 100644 --- a/packages/language-service/lib/plugins/vue-template.ts +++ b/packages/language-service/lib/plugins/vue-template.ts @@ -557,7 +557,11 @@ export function create( } const { attrs, propsInfo, events } = tagInfo; - const props = propsInfo.map(prop => prop.name); + const props = propsInfo.map(prop => + hyphenateTag(prop.name).startsWith('on-vnode-') + ? 'onVue:' + prop.name.slice('onVnode'.length) + : prop.name + ); const attributes: html.IAttributeData[] = []; const _tsCodegen = tsCodegen.get(vueCode._sfc); @@ -894,7 +898,7 @@ export function create( } else if (isEvent) { item.kind = 23 satisfies typeof vscode.CompletionItemKind.Event; - if (propName.startsWith('vnode-')) { + if (propName.startsWith('vue:')) { tokens.push('\u0004'); } }