mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-16 21:58:19 +00:00
refactor: use props in stead of attrs
This commit is contained in:
parent
1ad62a16f5
commit
c39bad01e2
@ -5,8 +5,14 @@ import type { AsyncComponentLoader, HydrationStrategy } from 'vue'
|
|||||||
export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
props: {
|
||||||
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnVisible(attrs.hydrate as IntersectionObserverInit | undefined) })
|
hydrate: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup (props, { attrs }) {
|
||||||
|
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnVisible(props.hydrate as IntersectionObserverInit | undefined) })
|
||||||
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
||||||
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
@ -18,27 +24,39 @@ export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
|||||||
export const createLazyNetworkComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyNetworkComponent = (loader: AsyncComponentLoader) => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
props: {
|
||||||
|
hydrate: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup (props, { attrs }) {
|
||||||
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
||||||
if (attrs.hydrate === 0) {
|
if (props.hydrate === 0) {
|
||||||
const comp = defineAsyncComponent(loader)
|
const comp = defineAsyncComponent(loader)
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
}
|
}
|
||||||
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnIdle(attrs.hydrate as number | undefined) })
|
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnIdle(props.hydrate) })
|
||||||
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTMLEvent = keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap>
|
|
||||||
/* @__NO_SIDE_EFFECTS__ */
|
/* @__NO_SIDE_EFFECTS__ */
|
||||||
export const createLazyEventComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyEventComponent = (loader: AsyncComponentLoader) => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
props: {
|
||||||
const events: HTMLEvent = attrs.hydrate as HTMLEvent ?? 'mouseover'
|
hydrate: {
|
||||||
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnInteraction(events) })
|
type: [String, Array],
|
||||||
|
required: false,
|
||||||
|
default: 'mouseover',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup (props, { attrs }) {
|
||||||
|
// @ts-expect-error Cannot type HTMLElementEventMap in props
|
||||||
|
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnInteraction(props.hydrate) })
|
||||||
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
||||||
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
@ -50,9 +68,15 @@ export const createLazyEventComponent = (loader: AsyncComponentLoader) => {
|
|||||||
export const createLazyMediaComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyMediaComponent = (loader: AsyncComponentLoader) => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
props: {
|
||||||
const mediaQuery = attrs.hydrate as string ?? '(min-width: 1px)'
|
hydrate: {
|
||||||
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnMediaQuery(mediaQuery) })
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '(min-width: 1px)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup (props, { attrs }) {
|
||||||
|
const comp = defineAsyncComponent({ loader, hydrate: hydrateOnMediaQuery(props.hydrate) })
|
||||||
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
||||||
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
@ -64,20 +88,26 @@ export const createLazyMediaComponent = (loader: AsyncComponentLoader) => {
|
|||||||
export const createLazyIfComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyIfComponent = (loader: AsyncComponentLoader) => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
props: {
|
||||||
const shouldHydrate = ref(!!(attrs.hydrate ?? true))
|
hydrate: {
|
||||||
if (shouldHydrate.value) {
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup (props, { attrs }) {
|
||||||
|
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
||||||
|
if (props.hydrate) {
|
||||||
const comp = defineAsyncComponent(loader)
|
const comp = defineAsyncComponent(loader)
|
||||||
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
|
||||||
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
}
|
}
|
||||||
const strategy: HydrationStrategy = (hydrate) => {
|
const strategy: HydrationStrategy = (hydrate) => {
|
||||||
const unwatch = watch(shouldHydrate, () => hydrate(), { once: true })
|
const unwatch = watch(() => props.hydrate, () => hydrate(), { once: true })
|
||||||
return () => unwatch()
|
return () => unwatch()
|
||||||
}
|
}
|
||||||
const comp = defineAsyncComponent({ loader, hydrate: strategy })
|
const comp = defineAsyncComponent({ loader, hydrate: strategy })
|
||||||
return () => h(comp, attrs)
|
return () => h(comp, merged)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -86,14 +116,21 @@ export const createLazyIfComponent = (loader: AsyncComponentLoader) => {
|
|||||||
export const createLazyTimeComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyTimeComponent = (loader: AsyncComponentLoader) => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
props: {
|
||||||
|
hydrate: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 2000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup (props, { attrs }) {
|
||||||
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
||||||
if (attrs.hydrate === 0) {
|
if (props.hydrate === 0) {
|
||||||
const comp = defineAsyncComponent(loader)
|
const comp = defineAsyncComponent(loader)
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
}
|
}
|
||||||
const strategy: HydrationStrategy = (hydrate) => {
|
const strategy: HydrationStrategy = (hydrate) => {
|
||||||
const id = setTimeout(hydrate, attrs.hydrate as number | undefined ?? 2000)
|
const id = setTimeout(hydrate, props.hydrate)
|
||||||
return () => clearTimeout(id)
|
return () => clearTimeout(id)
|
||||||
}
|
}
|
||||||
const comp = defineAsyncComponent({ loader, hydrate: strategy })
|
const comp = defineAsyncComponent({ loader, hydrate: strategy })
|
||||||
@ -107,17 +144,22 @@ export const createLazyTimeComponent = (loader: AsyncComponentLoader) => {
|
|||||||
export const createLazyPromiseComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyPromiseComponent = (loader: AsyncComponentLoader) => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
props: {
|
||||||
|
hydrate: {
|
||||||
|
type: Promise,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup (props, { attrs }) {
|
||||||
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
const merged = mergeProps(attrs, { 'data-allow-mismatch': '' })
|
||||||
// @ts-expect-error Attributes cannot be typed
|
if (!props.hydrate || typeof props.hydrate.then !== 'function') {
|
||||||
if (!attrs.hydrate || typeof attrs.hydrate.then !== 'function') {
|
|
||||||
const comp = defineAsyncComponent(loader)
|
const comp = defineAsyncComponent(loader)
|
||||||
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
// TODO: fix hydration mismatches on Vue's side. The data-allow-mismatch is ideally a temporary solution due to Vue's SSR limitation with hydrated content.
|
||||||
return () => h(comp, merged)
|
return () => h(comp, merged)
|
||||||
}
|
}
|
||||||
const strategy: HydrationStrategy = (hydrate) => {
|
const strategy: HydrationStrategy = (hydrate) => {
|
||||||
// @ts-expect-error Attributes cannot be typed
|
// @ts-expect-error TS does not see hydrate as non-null
|
||||||
attrs.hydrate.then(hydrate)
|
props.hydrate.then(hydrate)
|
||||||
return () => {}
|
return () => {}
|
||||||
}
|
}
|
||||||
const comp = defineAsyncComponent({ loader, hydrate: strategy })
|
const comp = defineAsyncComponent({ loader, hydrate: strategy })
|
||||||
|
Loading…
Reference in New Issue
Block a user