72 lines
1.8 KiB
Vue
72 lines
1.8 KiB
Vue
<script setup lang="ts">
|
|
import { templateRegistry } from '#layers/registry'
|
|
import type {
|
|
PageDataValue,
|
|
PageDataTemplate,
|
|
PageDataComponent,
|
|
PageDataMetaTag,
|
|
} from '#layers/types/api/pageData'
|
|
|
|
interface Props {
|
|
pageData: PageDataValue
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
// 템플릿 레지스트리 타입 캐스팅
|
|
const registry = templateRegistry as unknown as Record<
|
|
string,
|
|
{ component: PageDataComponent }
|
|
>
|
|
|
|
// 개별 메타 태그 표시 여부 확인
|
|
const shouldShowMetaTag = computed(() => props.pageData.meta_tag_type === 2)
|
|
|
|
// 템플릿 표시 여부 확인
|
|
const isTemplateVisible = (template: PageDataTemplate): boolean => {
|
|
return Boolean(
|
|
template?.components && Object.keys(template.components).length > 0
|
|
)
|
|
}
|
|
|
|
// 템플릿 목록 계산
|
|
const visibleTemplates = computed(() =>
|
|
Object.values(props.pageData.templates).filter(isTemplateVisible)
|
|
)
|
|
|
|
// SEO 메타 태그 설정
|
|
const setupSeoMeta = (metaTag: PageDataMetaTag) => {
|
|
useSeoMeta({
|
|
title: metaTag.page_title ?? '',
|
|
description: metaTag.page_desc ?? '',
|
|
ogTitle: metaTag.og_title ?? '',
|
|
ogDescription: metaTag.og_desc ?? '',
|
|
ogImage: metaTag.og_image ?? '',
|
|
twitterTitle: metaTag.x_title ?? '',
|
|
twitterImage: metaTag.x_image ?? '',
|
|
twitterDescription: metaTag.x_desc ?? '',
|
|
})
|
|
}
|
|
|
|
// 메타 태그 설정 감시
|
|
watchEffect(() => {
|
|
if (shouldShowMetaTag.value && props.pageData.meta_tag) {
|
|
setupSeoMeta(props.pageData.meta_tag)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<main>
|
|
<template
|
|
v-for="(template, index) in visibleTemplates"
|
|
:key="template.template_code ?? index"
|
|
>
|
|
<component
|
|
:is="registry[template.template_code]?.component"
|
|
:components="template.components"
|
|
/>
|
|
</template>
|
|
</main>
|
|
</template>
|