mirror of https://github.com/vuejs/core.git
wip: component with fallback
This commit is contained in:
parent
300bb0859a
commit
ae5ec075ad
|
@ -54,7 +54,9 @@ export function genCreateComponent(
|
|||
NEWLINE,
|
||||
`const n${operation.id} = `,
|
||||
...genCall(
|
||||
vaporHelper('createComponent'),
|
||||
operation.asset
|
||||
? vaporHelper('createComponentWithFallback')
|
||||
: vaporHelper('createComponent'),
|
||||
tag,
|
||||
rawProps,
|
||||
rawSlots,
|
||||
|
|
|
@ -19,17 +19,19 @@ import {
|
|||
} from '@vue/runtime-dom'
|
||||
import { type Block, isBlock } from './block'
|
||||
import { pauseTracking, resetTracking } from '@vue/reactivity'
|
||||
import { EMPTY_OBJ, isFunction } from '@vue/shared'
|
||||
import { EMPTY_OBJ, isFunction, isString } from '@vue/shared'
|
||||
import {
|
||||
type RawProps,
|
||||
getPropsProxyHandlers,
|
||||
hasFallthroughAttrs,
|
||||
normalizePropsOptions,
|
||||
resolveDynamicProps,
|
||||
setupPropsValidation,
|
||||
} from './componentProps'
|
||||
import { setDynamicProp } from './dom/prop'
|
||||
import { renderEffect } from './renderEffect'
|
||||
import { emit, normalizeEmitsOptions } from './componentEmits'
|
||||
import { setStyle } from './dom/style'
|
||||
import { setClass, setDynamicProp } from './dom/prop'
|
||||
|
||||
export { currentInstance } from '@vue/runtime-dom'
|
||||
|
||||
|
@ -266,7 +268,7 @@ export function isVaporComponent(
|
|||
export class SetupContext<E = EmitsOptions> {
|
||||
attrs: Record<string, any>
|
||||
emit: EmitFn<E>
|
||||
// slots: Readonly<StaticSlots>
|
||||
// TODO slots: Readonly<StaticSlots>
|
||||
expose: (exposed?: Record<string, any>) => void
|
||||
|
||||
constructor(instance: VaporComponentInstance) {
|
||||
|
@ -278,3 +280,47 @@ export class SetupContext<E = EmitsOptions> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createComponentWithFallback(
|
||||
comp: VaporComponent | string,
|
||||
rawProps: RawProps | undefined,
|
||||
// TODO slots: RawSlots | null
|
||||
isSingleRoot?: boolean,
|
||||
): HTMLElement | VaporComponentInstance {
|
||||
if (!isString(comp)) {
|
||||
return createComponent(comp, rawProps, isSingleRoot)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const el = document.createElement(comp)
|
||||
|
||||
if (rawProps) {
|
||||
renderEffect(() => {
|
||||
let classes: unknown[] | undefined
|
||||
let styles: unknown[] | undefined
|
||||
const resolved = resolveDynamicProps(rawProps)
|
||||
for (const key in resolved) {
|
||||
const value = resolved[key]
|
||||
if (key === 'class') (classes ||= []).push(value)
|
||||
else if (key === 'style') (styles ||= []).push(value)
|
||||
else setDynamicProp(el, key, value)
|
||||
}
|
||||
if (classes) setClass(el, classes)
|
||||
if (styles) setStyle(el, styles)
|
||||
})
|
||||
}
|
||||
|
||||
// TODO
|
||||
// if (slots) {
|
||||
// if (!Array.isArray(slots)) slots = [slots]
|
||||
// for (let i = 0; i < slots.length; i++) {
|
||||
// const slot = slots[i]
|
||||
// if (!isDynamicSlotFn(slot) && slot.default) {
|
||||
// const block = slot.default && slot.default()
|
||||
// if (block) el.append(...normalizeBlock(block))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return el
|
||||
}
|
||||
|
|
|
@ -231,14 +231,25 @@ export function setupPropsValidation(instance: VaporComponentInstance): void {
|
|||
const rawProps = instance.rawProps
|
||||
if (!rawProps) return
|
||||
renderEffect(() => {
|
||||
pushWarningContext(instance)
|
||||
validateProps(
|
||||
resolveDynamicProps(rawProps),
|
||||
instance.props,
|
||||
normalizePropsOptions(instance.type)[0]!,
|
||||
)
|
||||
popWarningContext()
|
||||
}, true /* noLifecycle */)
|
||||
}
|
||||
|
||||
export function resolveDynamicProps(props: RawProps): Record<string, unknown> {
|
||||
const mergedRawProps: Record<string, any> = {}
|
||||
for (const key in rawProps) {
|
||||
for (const key in props) {
|
||||
if (key !== '$') {
|
||||
mergedRawProps[key] = rawProps[key]()
|
||||
mergedRawProps[key] = props[key]()
|
||||
}
|
||||
}
|
||||
if (rawProps.$) {
|
||||
for (const source of rawProps.$) {
|
||||
if (props.$) {
|
||||
for (const source of props.$) {
|
||||
const isDynamic = isFunction(source)
|
||||
const resolved = isDynamic ? source() : source
|
||||
for (const key in resolved) {
|
||||
|
@ -248,12 +259,5 @@ export function setupPropsValidation(instance: VaporComponentInstance): void {
|
|||
}
|
||||
}
|
||||
}
|
||||
pushWarningContext(instance)
|
||||
validateProps(
|
||||
mergedRawProps,
|
||||
instance.props,
|
||||
normalizePropsOptions(instance.type)[0]!,
|
||||
)
|
||||
popWarningContext()
|
||||
}, true /* noLifecycle */)
|
||||
return mergedRawProps
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export { createComponent } from './component'
|
||||
export { createComponent, createComponentWithFallback } from './component'
|
||||
export { renderEffect } from './renderEffect'
|
||||
export { createVaporApp } from './apiCreateApp'
|
||||
export { defineComponent } from './apiDefineComponent'
|
||||
|
@ -19,3 +19,6 @@ export {
|
|||
} from './dom/prop'
|
||||
export { on, delegate, delegateEvents, setDynamicEvents } from './dom/event'
|
||||
export { setRef } from './dom/templateRef'
|
||||
|
||||
// re-exports
|
||||
export { resolveComponent } from '@vue/runtime-dom'
|
||||
|
|
Loading…
Reference in New Issue