wip: refactor

This commit is contained in:
daiwei 2025-03-05 22:10:13 +08:00
parent 7c68b482c5
commit 2e45f06ad3
12 changed files with 53 additions and 106 deletions

View File

@ -130,10 +130,6 @@ export function generate(
) )
} }
if (ir.hasTransition) {
push(NEWLINE, `${context.helper('useVaporTransition')}()`)
}
push(...genBlockContent(ir.block, context, true)) push(...genBlockContent(ir.block, context, true))
push(INDENT_END, NEWLINE) push(INDENT_END, NEWLINE)

View File

@ -39,7 +39,8 @@ import { genEventHandler } from './event'
import { genDirectiveModifiers, genDirectivesForElement } from './directive' import { genDirectiveModifiers, genDirectivesForElement } from './directive'
import { genBlock } from './block' import { genBlock } from './block'
import { genModelHandler } from './vModel' import { genModelHandler } from './vModel'
import { isBuiltInComponent } from '../transforms/transformElement'
import { isBuiltInComponent } from '../utils'
export function genCreateComponent( export function genCreateComponent(
operation: CreateComponentIRNode, operation: CreateComponentIRNode,

View File

@ -68,7 +68,6 @@ export interface RootIRNode {
directive: Set<string> directive: Set<string>
block: BlockIRNode block: BlockIRNode
hasTemplateRef: boolean hasTemplateRef: boolean
hasTransition: boolean
} }
export interface IfIRNode extends BaseIRNode { export interface IfIRNode extends BaseIRNode {

View File

@ -230,7 +230,6 @@ export function transform(
directive: new Set(), directive: new Set(),
block: newBlock(node), block: newBlock(node),
hasTemplateRef: false, hasTemplateRef: false,
hasTransition: false,
} }
const context = new TransformContext(ir, node, options) const context = new TransformContext(ir, node, options)

View File

@ -1,4 +1,3 @@
import { isValidHTMLNesting } from '@vue/compiler-dom'
import { import {
type AttributeNode, type AttributeNode,
type ComponentNode, type ComponentNode,
@ -11,6 +10,7 @@ import {
createCompilerError, createCompilerError,
createSimpleExpression, createSimpleExpression,
isStaticArgOf, isStaticArgOf,
isValidHTMLNesting,
} from '@vue/compiler-dom' } from '@vue/compiler-dom'
import { import {
camelize, camelize,
@ -36,7 +36,7 @@ import {
type VaporDirectiveNode, type VaporDirectiveNode,
} from '../ir' } from '../ir'
import { EMPTY_EXPRESSION } from './utils' import { EMPTY_EXPRESSION } from './utils'
import { findProp } from '../utils' import { findProp, isBuiltInComponent } from '../utils'
export const isReservedProp: (key: string) => boolean = /*#__PURE__*/ makeMap( export const isReservedProp: (key: string) => boolean = /*#__PURE__*/ makeMap(
// the leading comma is intentional so empty string "" is also included // the leading comma is intentional so empty string "" is also included
@ -441,9 +441,3 @@ function mergePropValues(existing: IRProp, incoming: IRProp) {
function isComponentTag(tag: string) { function isComponentTag(tag: string) {
return tag === 'component' || tag === 'Component' return tag === 'component' || tag === 'Component'
} }
export function isBuiltInComponent(tag: string): string | undefined {
if (tag === 'Transition' || tag === 'transition') {
return 'Transition'
}
}

View File

@ -1,7 +1,6 @@
import { import {
type ElementNode, type ElementNode,
ErrorCodes, ErrorCodes,
NodeTypes,
createCompilerError, createCompilerError,
createSimpleExpression, createSimpleExpression,
} from '@vue/compiler-dom' } from '@vue/compiler-dom'
@ -19,7 +18,7 @@ import {
import { extend } from '@vue/shared' import { extend } from '@vue/shared'
import { newBlock, wrapTemplate } from './utils' import { newBlock, wrapTemplate } from './utils'
import { getSiblingIf } from './transformComment' import { getSiblingIf } from './transformComment'
import { isStaticExpression } from '../utils' import { isInTransition, isStaticExpression } from '../utils'
export const transformVIf: NodeTransform = createStructuralDirectiveTransform( export const transformVIf: NodeTransform = createStructuralDirectiveTransform(
['if', 'else', 'else-if'], ['if', 'else', 'else-if'],
@ -129,25 +128,3 @@ export function createIfBranch(
branch.dynamic.needsKey = isInTransition(context) branch.dynamic.needsKey = isInTransition(context)
return [branch, exitBlock] return [branch, exitBlock]
} }
export function isInTransition(
context: TransformContext<ElementNode>,
): boolean {
const parentNode = context.parent && context.parent.node
return !!(parentNode && isTransitionNode(parentNode as ElementNode, context))
}
export function isTransitionNode(
node: ElementNode,
context: TransformContext<ElementNode>,
): boolean {
const inTransition =
node.type === NodeTypes.ELEMENT &&
(node.tag === 'transition' || node.tag === 'Transition')
if (inTransition) {
context.ir.hasTransition = true
}
return inTransition
}

View File

@ -23,8 +23,12 @@ import {
type SlotBlockIRNode, type SlotBlockIRNode,
type VaporDirectiveNode, type VaporDirectiveNode,
} from '../ir' } from '../ir'
import { findDir, findProp, resolveExpression } from '../utils' import {
import { isTransitionNode } from './vIf' findDir,
findProp,
isTransitionNode,
resolveExpression,
} from '../utils'
export const transformVSlot: NodeTransform = (node, context) => { export const transformVSlot: NodeTransform = (node, context) => {
if (node.type !== NodeTypes.ELEMENT) return if (node.type !== NodeTypes.ELEMENT) return
@ -74,7 +78,7 @@ function transformComponentSlot(
) )
let slotKey let slotKey
if (isTransitionNode(node, context)) { if (isTransitionNode(node)) {
const keyProp = findProp( const keyProp = findProp(
nonSlotTemplateChildren[0] as ElementNode, nonSlotTemplateChildren[0] as ElementNode,
'key', 'key',

View File

@ -15,6 +15,7 @@ import {
} from '@vue/compiler-dom' } from '@vue/compiler-dom'
import type { VaporDirectiveNode } from './ir' import type { VaporDirectiveNode } from './ir'
import { EMPTY_EXPRESSION } from './transforms/utils' import { EMPTY_EXPRESSION } from './transforms/utils'
import type { TransformContext } from './transform'
export const findProp = _findProp as ( export const findProp = _findProp as (
node: ElementNode, node: ElementNode,
@ -88,3 +89,25 @@ export function getLiteralExpressionValue(
} }
return exp.isStatic ? exp.content : null return exp.isStatic ? exp.content : null
} }
export function isInTransition(
context: TransformContext<ElementNode>,
): boolean {
const parentNode = context.parent && context.parent.node
return !!(parentNode && isTransitionNode(parentNode as ElementNode))
}
export function isTransitionNode(node: ElementNode): boolean {
return node.type === NodeTypes.ELEMENT && isTransitionTag(node.tag)
}
export function isTransitionTag(tag: string): boolean {
tag = tag.toLowerCase()
return tag === 'transition' || tag === 'vaportransition'
}
export function isBuiltInComponent(tag: string): string | undefined {
if (isTransitionTag(tag)) {
return 'VaporTransition'
}
}

View File

@ -4,11 +4,9 @@ import {
BaseTransitionPropsValidators, BaseTransitionPropsValidators,
DeprecationTypes, DeprecationTypes,
type FunctionalComponent, type FunctionalComponent,
type Slots,
assertNumber, assertNumber,
compatUtils, compatUtils,
h, h,
renderSlot,
} from '@vue/runtime-core' } from '@vue/runtime-core'
import { extend, isArray, isObject, toNumber } from '@vue/shared' import { extend, isArray, isObject, toNumber } from '@vue/shared'
@ -34,20 +32,6 @@ export interface TransitionProps extends BaseTransitionProps<Element> {
leaveToClass?: string leaveToClass?: string
} }
export interface VaporTransitionInterface {
applyTransition: (
props: TransitionProps,
slots: { default: () => any },
) => any
}
let vaporTransitionImpl: VaporTransitionInterface | null = null
export const registerVaporTransition = (
impl: VaporTransitionInterface,
): void => {
vaporTransitionImpl = impl
}
export const vtcKey: unique symbol = Symbol('_vtc') export const vtcKey: unique symbol = Symbol('_vtc')
export interface ElementWithTransition extends HTMLElement { export interface ElementWithTransition extends HTMLElement {
@ -101,27 +85,9 @@ const decorate = (t: typeof Transition) => {
* base Transition component, with DOM-specific logic. * base Transition component, with DOM-specific logic.
*/ */
export const Transition: FunctionalComponent<TransitionProps> = export const Transition: FunctionalComponent<TransitionProps> =
/*@__PURE__*/ decorate((props, { slots }) => { /*@__PURE__*/ decorate((props, { slots }) =>
const resolvedProps = resolveTransitionProps(props) h(BaseTransition, resolveTransitionProps(props), slots),
if (slots.__vapor) { )
// with vapor interop plugin
if (slots.__interop) {
const children = vaporTransitionImpl!.applyTransition(
resolvedProps,
slots as any,
)
const vaporSlots = {
default: () => children,
__interop: true,
} as any as Slots
return renderSlot(vaporSlots, 'default')
}
return vaporTransitionImpl!.applyTransition(resolvedProps, slots as any)
}
return h(BaseTransition, resolvedProps, slots)
})
/** /**
* #3227 Incoming hooks may be merged into arrays when wrapping Transition * #3227 Incoming hooks may be merged into arrays when wrapping Transition

View File

@ -354,9 +354,4 @@ export {
export { export {
resolveTransitionProps, resolveTransitionProps,
TransitionPropsValidators, TransitionPropsValidators,
registerVaporTransition,
} from './components/Transition' } from './components/Transition'
/**
* @internal
*/
export type { VaporTransitionInterface } from './components/Transition'

View File

@ -1,15 +1,16 @@
import { import {
type FunctionalComponent,
type GenericComponentInstance, type GenericComponentInstance,
type TransitionElement, type TransitionElement,
type TransitionHooks, type TransitionHooks,
type TransitionHooksContext, type TransitionHooksContext,
type TransitionProps, type TransitionProps,
TransitionPropsValidators,
type TransitionState, type TransitionState,
type VaporTransitionInterface,
baseResolveTransitionHooks, baseResolveTransitionHooks,
currentInstance, currentInstance,
leaveCbKey, leaveCbKey,
registerVaporTransition, resolveTransitionProps,
useTransitionState, useTransitionState,
warn, warn,
} from '@vue/runtime-dom' } from '@vue/runtime-dom'
@ -21,13 +22,15 @@ import {
} from '../block' } from '../block'
import { isVaporComponent } from '../component' import { isVaporComponent } from '../component'
/*#__NO_SIDE_EFFECTS__*/ const decorate = (t: typeof VaporTransition) => {
export const vaporTransitionImpl: VaporTransitionInterface = { t.displayName = 'VaporTransition'
applyTransition: ( t.props = TransitionPropsValidators
props: TransitionProps, return t
slots: { default: () => Block }, }
): Block | undefined => {
const children = slots.default && slots.default() export const VaporTransition: FunctionalComponent<TransitionProps> =
/*@__PURE__*/ decorate((props, { slots }) => {
const children = (slots.default && slots.default()) as any as Block
if (!children) return if (!children) return
const { mode } = props const { mode } = props
@ -43,12 +46,11 @@ export const vaporTransitionImpl: VaporTransitionInterface = {
applyTransitionEnterHooks(children, { applyTransitionEnterHooks(children, {
state: useTransitionState(), state: useTransitionState(),
props, props: resolveTransitionProps(props),
} as VaporTransitionHooks) } as VaporTransitionHooks)
return children return children
}, })
}
const getTransitionHooksContext = ( const getTransitionHooksContext = (
key: String, key: String,
@ -236,12 +238,3 @@ export function findTransitionBlock(block: Block): TransitionBlock | undefined {
return child return child
} }
let registered = false
/*#__NO_SIDE_EFFECTS__*/
export function useVaporTransition(): void {
if (!registered) {
registerVaporTransition(vaporTransitionImpl)
registered = true
}
}

View File

@ -42,4 +42,4 @@ export {
applyDynamicModel, applyDynamicModel,
} from './directives/vModel' } from './directives/vModel'
export { withVaporDirectives } from './directives/custom' export { withVaporDirectives } from './directives/custom'
export { useVaporTransition } from './components/Transition' export { VaporTransition } from './components/Transition'