# 使用 Vue 3 + Element Plus 从头开始写一个数据库网站 - 08 - 使用动态配置编写组件:以页脚美化为例

由于 PrismJS 尚不支持 Vue 的语法高亮,因此 Vue 代码块均先使用 HTML 的高亮

2024-09-23

在前面,我们为了方便,在根组件 ADDB/src/App.vue 中简单写了一个页脚

<el-footer class="footer">
    <p>&copy; 2024 Alzheimer's Disease Biomarker Database. All rights reserved.</p>
</el-footer>

现在,我们来美化这个页脚

布局上,我们仍然参考 PubChem 的多列布局,第一列包含组织 Logo、地点、版权声明等信息,其他列包含关于、导航、联系等信息,并为每列添加小标题

# 编写页脚组件

为了方便以后复用,我们以组件的形式来编写一个 PageFooter.vue 文件

新建 ADDB/src/components/PageFooter.vue 文件

<template>
    <el-footer class="footer">
        <div class="footer-container">
            <!-- 第一列:组织信息 -->
            <div class="footer-column">
                <img src="/gdph.png" alt="Organization Logo" class="footer-logo" />
                <p>Address: No. 106, Zhongshan 2nd Road, Guangzhou</p>
                <p>&copy; 2024 ADDB. ALL RIGHTS RESERVED</p>
            </div>
            <!-- 第二列:关于 -->
            <div class="footer-column">
                <h3>About</h3>
                <ul>
                    <li><a href="/about">Our Mission</a></li>
                    <li><a href="/about/team">Our Team</a></li>
                    <li><a href="/about/careers">Careers</a></li>
                </ul>
            </div>
            <!-- 第三列:导航 -->
            <div class="footer-column">
                <h3>Navigation</h3>
                <ul>
                    <li><a href="/">Home</a></li>
                    <li><a href="/biomarkers">Biomarkers</a></li>
                    <li><a href="/test">Test</a></li>
                </ul>
            </div>
            <!-- 第四列:联系 -->
            <div class="footer-column">
                <h3>Contact</h3>
                <p>Email: <a href="mailto:support@addb.com">support@addb.com</a></p>
                <p>Phone: +1 (234) 567-890</p>
                <p>Twitter: <a href="https://twitter.com" target="_blank">@addb</a></p>
            </div>
        </div>
    </el-footer>
</template>
<script setup>
// 引入所需资源(如图标库或其他样式可在此引入)
</script>
<style scoped>
.footer {
    background-color: #333;
    color: #fff;
    padding: 40px 20px;
    height: auto;
}
.footer-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    max-width: 1200px;
    margin: 0 auto;
}
.footer-column {
    flex: 1;
    min-width: 200px;
    /* 最小列宽,方便响应式 */
    margin: 0 20px;
}
.footer-column h3 {
    margin-bottom: 15px;
    font-size: 18px;
    font-weight: bold;
    color: #f1f1f1;
}
.footer-column ul {
    list-style: none;
    padding: 0;
    margin: 0;
}
.footer-column ul li {
    margin-bottom: 10px;
}
.footer-column ul li a {
    color: #ddd;
    text-decoration: none;
}
.footer-column ul li a:hover {
    text-decoration: underline;
}
.footer-logo {
    height: 55px;
    margin-bottom: 10px;
}
@media (max-width: 768px) {
    .footer-container {
        flex-direction: column;
        text-align: center;
    }
    .footer-column {
        margin-bottom: 30px;
    }
}
</style>

# 实现细节

  1. 列划分:
    • 使用 flex 布局, flex: 1 让每列平均分布。
    • 设置 min-width: 200px 确保在小屏幕时列不会太窄。
  2. 第一列:组织信息
    • 包括 Logo 图片、地址、版权声明。
    • Logo 样式通过 .footer-logo 控制。
  3. 其他列:关于、导航、联系
    • 每列用 h3 标题表示功能区名称。
    • 链接用 <ul><li><a></a></li></ul> 结构实现,易于扩展。
  4. 样式优化:
    • 在桌面端,列均分排列;在移动端,通过 @media 查询切换为垂直布局。
  5. 响应式设计:
    • 在小屏幕(宽度 <768px)下,列堆叠显示,保证可读性。

# 使用组件

在根组件 ADDB/src/App.vue 中的 <script setup> 中添加

import PageFooter from '@/components/PageFooter.vue';

或者

import PageFooter from './components/PageFooter.vue';

@ 表示别名,通常指向项目的 src 目录。在我们项目的 vite.config.js 中通过 resolve.alias 定义:

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        vue(),
    ],
    resolve: {
        alias: {
            '@': fileURLToPath(new URL('./src', import.meta.url))
        }
    },
})

这样做的优点是,即使文件被深层嵌套,不需要写长长的相对路径(如 ../../../ )。此外,当路径修改时,可以避免维护复杂的相对路径。

然后将原来的页脚

<el-footer class="footer">
    <p>&copy; 2024 Alzheimer's Disease Biomarker Database. All rights reserved.</p>
</el-footer>

替换为

<PageFooter />

并删去原来的页脚样式,即可看到我们新编写的页脚

# 动态配置形式的实现

除了第一列,我们的页脚格式都是相似的,因此对于后几列,我们可以共用一个模板,然后通过传入数据来填充

首先修改 PageFooter.vue 文件

<template>
    <el-footer class="footer">
        <div class="footer-container">
            <!-- 静态列 -->
            <div class="footer-column">
                <img src="/gdph.png" alt="Organization Logo" class="footer-logo" />
                <p>Address: No. 106, Zhongshan 2nd Road, Guangzhou</p>
                <p>&copy; 2024 ADDB. ALL RIGHTS RESERVED</p>
            </div>
            <!-- 动态生成列 -->
            <div v-for="column in props.columns" :key="column.title" class="footer-column">
                <!-- 动态渲染标题 -->
                <h3 v-if="column.title">{{ column.title }}</h3>
                <!-- 动态渲染内容 -->
                <template v-if="column.type === 'text'">
                    <p v-for="(text, idx) in column.content" :key="idx">{{ text }}</p>
                </template>
                <template v-else-if="column.type === 'links'">
                    <ul>
                        <li v-for="(link, idx) in column.content" :key="idx">
                            <a :href="link.href" :target="link.target || '_self'"></a>
                        </li>
                    </ul>
                </template>
                <template v-else-if="column.type === 'image'">
                    <img :src="column.content.src" :alt="column.content.alt" class="footer-logo" />
                </template>
            </div>
        </div>
    </el-footer>
</template>

<script setup> 中定义列的类型

<script setup>
import { defineProps } from "vue";
// 定义列的默认类型
const props = defineProps({
    columns: {
        type: Array,
        required: true,
    },
});
</script>

在根组件 App.vue 中,我们在 <script setup> 中传入数据

const footerColumns = [
    {
        title: "About",
        type: "links",
        content: [
            { text: "Our Mission", href: "/about" },
            { text: "Our Team", href: "/about/team" },
            { text: "Careers", href: "/about/careers" },
        ],
    },
    {
        title: "Navigation",
        type: "links",
        content: [
            { text: "Home", href: "/" },
            { text: "Biomarkers", href: "/biomarkers" },
            { text: "Test", href: "/test" },
        ],
    },
    {
        title: "Contact",
        type: "text",
        content: [
            "Email: support@addb.com",
            "Phone: +1 (234) 567-890",
            "Twitter: @addb",
        ],
    },
];

至此,我们已经完成了一个数据库网站的框架。

🌸完结撒花🌸