02_2025自考社区门户网站建设原型

93 阅读5分钟

自考社区门户网站 (Vue3 + Element Plus 实现)

下面是一个基于 Vue3 和 Element Plus 的自考社区门户网站的完整实现方案。这个实现包括首页、关于自考、公告栏目、自考政策、相关介绍、综合查询和便民服务等模块。

项目结构

self-exam-portal/
├── public/                # 静态资源
├── src/
│   ├── assets/            # 静态资源
│   ├── components/        # 公共组件
│   │   ├── Header.vue     # 头部导航
│   │   ├── Footer.vue     # 页脚
│   │   └── Sidebar.vue    # 侧边栏
│   ├── router/            # 路由配置
│   │   └── index.js
│   ├── store/             # Vuex 状态管理
│   │   └── index.js
│   ├── views/             # 页面组件
│   │   ├── Home.vue       # 首页
│   │   ├── About.vue      # 关于自考
│   │   ├── Notice.vue     # 公告栏目
│   │   ├── Policy.vue     # 自考政策
│   │   ├── Introduction.vue # 相关介绍
│   │   ├── Query.vue      # 综合查询
│   │   └── Service.vue    # 便民服务
│   ├── App.vue            # 根组件
│   └── main.js           # 入口文件
├── package.json
└── vite.config.js        # Vite 配置

1. 安装依赖

首先创建项目并安装所需依赖:

npm create vue@latest self-exam-portal
cd self-exam-portal
npm install element-plus axios vue-router pinia
npm install

2. 配置 Element Plus

main.js 中引入 Element Plus:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(ElementPlus)

app.mount('#app')

3. 路由配置 (router/index.js)

import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue')
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  },
  {
    path: '/notice',
    name: 'Notice',
    component: () => import('../views/Notice.vue')
  },
  {
    path: '/policy',
    name: 'Policy',
    component: () => import('../views/Policy.vue')
  },
  {
    path: '/introduction',
    name: 'Introduction',
    component: () => import('../views/Introduction.vue')
  },
  {
    path: '/query',
    name: 'Query',
    component: () => import('../views/Query.vue')
  },
  {
    path: '/service',
    name: 'Service',
    component: () => import('../views/Service.vue')
  }
]

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes
})

export default router

4. 公共组件

Header.vue (导航栏)

<template>
  <el-header class="header">
    <div class="logo">自考社区</div>
    <el-menu
      :default-active="activeIndex"
      class="el-menu-demo"
      mode="horizontal"
      @select="handleSelect"
      router
    >
      <el-menu-item index="/">首页</el-menu-item>
      <el-menu-item index="/about">关于自考</el-menu-item>
      <el-menu-item index="/notice">公告栏目</el-menu-item>
      <el-menu-item index="/policy">自考政策</el-menu-item>
      <el-menu-item index="/introduction">相关介绍</el-menu-item>
      <el-menu-item index="/query">综合查询</el-menu-item>
      <el-menu-item index="/service">便民服务</el-menu-item>
    </el-menu>
    <div class="user-info">
      <el-button type="text" @click="login">登录</el-button>
      <el-button type="text" @click="register">注册</el-button>
    </div>
  </el-header>
</template>

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'

const router = useRouter()
const activeIndex = ref('/')

const handleSelect = (key) => {
  activeIndex.value = key
}

const login = () => {
  router.push('/login')
}

const register = () => {
  router.push('/register')
}
</script>

<style scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #409EFF;
  color: white;
  padding: 0 20px;
}
.logo {
  font-size: 24px;
  font-weight: bold;
}
.el-menu-demo {
  flex: 1;
  background-color: transparent;
}
.el-menu-item {
  color: white !important;
}
.user-info {
  margin-left: 20px;
}
</style>

Footer.vue (页脚)

<template>
  <el-footer class="footer">
    <div class="footer-content">
      <div class="links">
        <a href="#">关于我们</a>
        <a href="#">联系我们</a>
        <a href="#">帮助中心</a>
        <a href="#">隐私政策</a>
      </div>
      <div class="copyright">
        © 2023 自考社区 版权所有
      </div>
    </div>
  </el-footer>
</template>

<style scoped>
.footer {
  background-color: #f5f7fa;
  color: #666;
  text-align: center;
  padding: 20px 0;
  margin-top: 20px;
}
.footer-content {
  max-width: 1200px;
  margin: 0 auto;
}
.links {
  margin-bottom: 10px;
}
.links a {
  margin: 0 15px;
  color: #666;
  text-decoration: none;
}
.links a:hover {
  color: #409EFF;
}
.copyright {
  font-size: 14px;
}
</style>

5. 页面组件示例

Home.vue (首页)

<template>
  <div class="home">
    <el-carousel height="400px">
      <el-carousel-item v-for="item in banners" :key="item.id">
        <img :src="item.image" :alt="item.title" class="banner-image">
      </el-carousel-item>
    </el-carousel>
    
    <div class="container">
      <el-row :gutter="20">
        <el-col :span="16">
          <div class="news-section">
            <h2 class="section-title">最新公告</h2>
            <el-card shadow="hover" v-for="notice in notices" :key="notice.id" class="notice-card">
              <div slot="header" class="clearfix">
                <span>{{ notice.title }}</span>
                <el-button style="float: right; padding: 3px 0" type="text">查看详情</el-button>
              </div>
              <div class="notice-content">{{ notice.content }}</div>
              <div class="notice-time">{{ notice.time }}</div>
            </el-card>
          </div>
        </el-col>
        <el-col :span="8">
          <div class="quick-links">
            <h2 class="section-title">快速通道</h2>
            <el-card shadow="hover">
              <el-button type="primary" class="quick-btn" @click="$router.push('/query')">成绩查询</el-button>
              <el-button type="primary" class="quick-btn" @click="$router.push('/query')">考试报名</el-button>
              <el-button type="primary" class="quick-btn" @click="$router.push('/policy')">政策解读</el-button>
              <el-button type="primary" class="quick-btn" @click="$router.push('/service')">常见问题</el-button>
            </el-card>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const banners = ref([
  { id: 1, title: '自考报名进行中', image: 'https://via.placeholder.com/1200x400' },
  { id: 2, title: '最新考试政策', image: 'https://via.placeholder.com/1200x400' },
  { id: 3, title: '自考学习资料', image: 'https://via.placeholder.com/1200x400' }
])

const notices = ref([
  {
    id: 1,
    title: '2023年下半年自考报名通知',
    content: '2023年下半年自考报名将于9月1日开始,请考生提前做好准备...',
    time: '2023-08-20'
  },
  {
    id: 2,
    title: '自考成绩查询系统开放',
    content: '2023年上半年自考成绩查询系统已开放,考生可登录查询...',
    time: '2023-08-15'
  },
  {
    id: 3,
    title: '自考教材更新通知',
    content: '部分专业教材有更新,请考生购买最新版教材进行复习...',
    time: '2023-08-10'
  }
])
</script>

<style scoped>
.home {
  min-height: calc(100vh - 120px);
}
.banner-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.container {
  max-width: 1200px;
  margin: 20px auto;
  padding: 0 20px;
}
.section-title {
  color: #409EFF;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
  margin-bottom: 20px;
}
.notice-card {
  margin-bottom: 15px;
}
.notice-content {
  color: #666;
  margin-bottom: 10px;
}
.notice-time {
  color: #999;
  font-size: 12px;
}
.quick-links {
  margin-bottom: 20px;
}
.quick-btn {
  width: 100%;
  margin-bottom: 10px;
}
</style>

Query.vue (综合查询)

<template>
  <div class="query">
    <div class="container">
      <h1 class="page-title">综合查询</h1>
      
      <el-tabs v-model="activeTab" class="query-tabs">
        <el-tab-pane label="成绩查询" name="score">
          <el-form :model="scoreForm" label-width="100px">
            <el-form-item label="准考证号">
              <el-input v-model="scoreForm.examNumber" placeholder="请输入准考证号"></el-input>
            </el-form-item>
            <el-form-item label="身份证号">
              <el-input v-model="scoreForm.idCard" placeholder="请输入身份证号"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="queryScore">查询</el-button>
            </el-form-item>
          </el-form>
          
          <el-table :data="scoreData" v-if="scoreData.length" border>
            <el-table-column prop="subject" label="科目"></el-table-column>
            <el-table-column prop="score" label="成绩"></el-table-column>
            <el-table-column prop="status" label="状态"></el-table-column>
          </el-table>
        </el-tab-pane>
        
        <el-tab-pane label="考试安排" name="schedule">
          <el-form :model="scheduleForm" label-width="100px">
            <el-form-item label="考试年份">
              <el-select v-model="scheduleForm.year" placeholder="请选择年份">
                <el-option label="2023年" value="2023"></el-option>
                <el-option label="2024年" value="2024"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="考试月份">
              <el-select v-model="scheduleForm.month" placeholder="请选择月份">
                <el-option label="4月" value="4"></el-option>
                <el-option label="10月" value="10"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="querySchedule">查询</el-button>
            </el-form-item>
          </el-form>
          
          <el-table :data="scheduleData" v-if="scheduleData.length" border>
            <el-table-column prop="date" label="日期" width="120"></el-table-column>
            <el-table-column prop="time" label="时间" width="120"></el-table-column>
            <el-table-column prop="subject" label="科目"></el-table-column>
            <el-table-column prop="location" label="考点"></el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const activeTab = ref('score')

const scoreForm = ref({
  examNumber: '',
  idCard: ''
})

const scheduleForm = ref({
  year: '',
  month: ''
})

const scoreData = ref([])
const scheduleData = ref([])

const queryScore = () => {
  // 模拟API调用
  scoreData.value = [
    { subject: '马克思主义基本原理概论', score: '85', status: '合格' },
    { subject: '中国近现代史纲要', score: '78', status: '合格' },
    { subject: '英语(二)', score: '62', status: '合格' }
  ]
}

const querySchedule = () => {
  // 模拟API调用
  scheduleData.value = [
    { date: '2023-10-21', time: '上午9:00-11:30', subject: '马克思主义基本原理概论', location: '第一中学' },
    { date: '2023-10-21', time: '下午14:30-17:00', subject: '中国近现代史纲要', location: '第一中学' },
    { date: '2023-10-22', time: '上午9:00-11:30', subject: '英语(二)', location: '第二中学' }
  ]
}
</script>

<style scoped>
.query {
  min-height: calc(100vh - 120px);
}
.container {
  max-width: 1200px;
  margin: 20px auto;
  padding: 0 20px;
}
.page-title {
  color: #409EFF;
  margin-bottom: 30px;
  text-align: center;
}
.query-tabs {
  background: #fff;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
</style>

6. App.vue (根组件)

<template>
  <div class="app">
    <Header />
    <router-view />
    <Footer />
  </div>
</template>

<script setup>
import Header from './components/Header.vue'
import Footer from './components/Footer.vue'
</script>

<style>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
</style>

7. 运行项目

npm run dev

功能扩展建议

  1. 用户系统:添加登录/注册功能,保存用户查询记录
  2. 数据API:连接后端服务获取真实数据
  3. 响应式设计:优化移动端显示
  4. 搜索功能:添加全局搜索框
  5. 收藏功能:允许用户收藏重要公告和政策

这个实现提供了自考社区门户网站的基本框架,您可以根据实际需求进一步扩展和完善各个功能模块。