Files
admin/www/app/components/section/layouts/LayoutTitleMedia.vue
T
2026-08-05 18:36:01 +08:00

54 lines
2.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import type { SectionBlock } from '~/types/site';
import { resolveAssetUrl } from '~/utils/resolveAssetUrl';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, content, mediaUrl, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
// 媒体视频(video_url 有值时优先渲染视频,支持 /uploads/... 相对路径)
const videoUrl = computed(() => resolveAssetUrl(props.section.video_url));
// 文案水平对齐(config.text_position 九宫格仅取水平方向):left 左对齐(默认)/ center 居中 / right 右对齐
const hAlign = computed(() => {
const col = (props.section.config as Record<string, string> | null)?.text_position?.split('_')[1] ?? 'left';
return ({
left: { wrap: 'items-start', text: 'text-left' },
center: { wrap: 'items-center', text: 'text-center' },
right: { wrap: 'items-end', text: 'text-right' }
} as Record<string, { wrap: string; text: string }>)[col] ?? { wrap: 'items-start', text: 'text-left' };
});
</script>
<template>
<div class="section-container py-[var(--sec-py,96px)] flex flex-col gap-48px" :class="hAlign.wrap">
<!-- 标题区 -->
<div class="flex flex-col gap-16px max-w-800px" :class="hAlign.text">
<p v-if="overline" class="text-14px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="font-bold leading-tight" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="text-lg md:text-xl" :class="isDark ? 'text-gray-300' : 'text-gray-600 dark:text-gray-300'" :style="bodyStyle">
{{ subtitle }}
</p>
<div v-if="content" class="rich-text text-15px leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle" v-html="content" />
</div>
<!-- 媒体视频优先其次图片填满内容容器宽度跟随内容区宽度配置),高度按素材比例自适应 -->
<div v-if="videoUrl || mediaUrl" class="w-full">
<video
v-if="videoUrl"
:src="videoUrl"
class="w-full rounded-16px object-cover shadow-lg"
autoplay
muted
loop
playsinline
/>
<img v-else :src="mediaUrl" :alt="title" class="w-full rounded-16px object-cover shadow-lg" />
</div>
</div>
</template>