Vue3项目开发专题精讲【左扬精讲】—— 企业网站系统(基于 Vue3 与 TypeScript 技术栈的企业网站系统开发实战)

企业网站系统(从 Vite 搭建 Vue3 与 TypeScript 企业网站系统开发实战)

https://github.com/zuoyangs/vue3-enterprise-website

https://vue3-enterprise-website.zuoyang.tech/

        在企业数字化浪潮中,官方网站不仅是品牌形象的 “数字名片”,更是业务拓展与用户沟通的核心渠道。对于追求开发效率与代码质量的团队而言,Vue3 的组合式 API、TypeScript 的类型安全,搭配 Vite 的极速构建能力,构成了企业网站开发的最优技术栈之一。本文将以 “从零搭建企业网站” 为目标,从环境准备、项目初始化,到核心模块实现与优化部署,完整拆解基于 Vite 的 Vue3+TS 开发全流程,即使是前端新手也能按步骤落地一套功能完善的企业网站系统。

一、开发前准备:搭建网站系统运行环境

工欲善其事,必先利其器。在启动项目前,需先搭建适配 Vue3+TS+Vite 的开发环境,确保后续开发过程中工具链稳定运行​

1.1、基础环境安装

1.1.1、Node.js 环境

Node.js(LTS v18+):作为前端项目的运行时环境,Node.js 内置的 npm 可用于基础依赖管理。

    • 下载 Node.js:前往 Node.js(https://nodejs.org/en)官方网站,选择 LTS 版本(如 v24.1.0)安装,安装完成后自动配置环境变量。

验证安装:执行以下命令,若正常输出版本号则说明安装成功:

# 检查Node.js版本(需≥v18,确保兼容Vite最新版)
node -v  # 示例输出:v20.15.0
# 检查npm版本(随Node.js自动安装,无需单独下载)
npm -v   # 示例输出:v10.7.0

1.1.2、代码编辑器与必备插件

推荐使用 VS Code,并安装以下插件提升开发效率:

      • Volar:Vue3 官方推荐插件,完美支持单文件组件(SFC)与 TypeScript 语法提示,替代旧版的 Vetur;
      • TypeScript Vue Plugin (Volar):增强 Vue 与 TS 的类型联动,解决组件 props、emit 的类型校验问题;
      • ESLint:自动检查代码语法错误与风格问题(如缩进、变量命名),确保代码规范;
      • Prettier:自动格式化代码,统一团队开发风格(可与 ESLint 配合,避免格式冲突);
      • Vite:VS Code 内置 Vite 插件,支持项目热更新与构建命令快捷执行。

二、项目初始化:用 Vite 快速搭建 Vue3+TS 骨架

npm init vite@latest 是 Vite 官方提供的项目初始化命令,无需全局安装 Vite,直接通过 npm 临时调用,一步生成 Vue3+TS 项目结构,比传统脚手架更轻量高效。

2.1、执行创建命令

1、打开终端,进入希望存放项目的文件夹(如D:/workspace),执行以下命令启动项目创建:

2、执行以下命令,启动 Vite 项目创建流程:

npm init vite@latest

2.2、交互式配置项目(适配企业网站需求)

执行命令后,终端会弹出三步交互式配置,按以下要求选择(关键选项已标注,确保贴合企业网站开发):

image

配置完成后,终端会提示 “Scaffolding project in 项目路径...”,片刻后显示创建成功,并给出后续操作指令(进入目录、安装依赖、启动服务)。

2.3、安装依赖并启动开发服务

按终端提示,执行以下命令完成依赖安装与服务启动:

# 1. 进入项目目录(与第一步输入的Project name一致)
cd enterprise-website

# 2. 用npm安装项目依赖(读取package.json中的基础依赖,自动下载)
npm install

# 3. 启动开发服务(Vite默认端口5173,端口被占用时会自动切换)
npm run dev

image

      • 启动成功标志:终端输出 “ VITE v7.1.3 ready in 516 ms”,并显示访问地址(如http://localhost:5173);
      • 验证效果:打开浏览器访问该地址,若看到 “Vite + Vue + TypeScript” 的默认页面(含计数器示例),则项目初始化成功。

2.4、目录结构

Vite 默认生成的目录较简洁,需删除冗余文件(如src/components/HelloWorld.vue、src/assets/vue.svg、public/vite.svg),新增业务目录,最终结构如下(覆盖 “首页、关于我们、核心业务、新闻动态、联系我们、在线咨询”):

## 📁 项目结构

vue3-enterprise-website/
├── src/                          # 源代码目录
│   ├── assets/                   # 静态资源(图片、全局样式、字体)
│   │   ├── images/               # 图片资源(分类存储)
│   │   │   ├── about/            # 关于我们页面图片
│   │   │   ├── business/         # 业务页面图片(图标、案例图)
│   │   │   ├── hero/             # 首页轮播图/英雄区图片
│   │   │   ├── news/             # 新闻页面图片
│   │   │   └── index.ts          # 图片资源导出管理
│   │   ├── styles/               # 全局样式文件
│   │   │   ├── fonts.css         # 字体样式(中文字体优化)
│   │   │   ├── reset.css         # CSS 重置样式
│   │   │   └── tailwind.css      # Tailwind CSS 扩展配置
│   │   └── vue.svg               # Vue 默认图标
│   ├── components/               # 公共组件(所有页面复用,减少重复开发)
│   │   ├── FaqItem.vue          # FAQ 折叠面板(在线咨询页复用)
│   │   ├── Footer.vue           # 页脚(全局底部,含企业信息、版权、备案号)
│   │   ├── Navbar.vue           # 导航栏(全局头部,支持PC/移动端适配)
│   │   └── Swiper.vue           # 轮播图组件(首页、业务页复用)
│   ├── router/                   # 路由配置(页面跳转、动态路由、路由守卫)
│   │   └── index.ts             # Vue Router 配置文件
│   ├── stores/                   # Pinia 状态管理(全局共享数据)
│   │   └── consultStore.ts      # 咨询表单数据存储示例
│   ├── types/                    # TypeScript 类型定义(统一接口,确保类型安全)
│   │   ├── business.ts          # 业务数据类型
│   │   ├── common.ts            # 通用数据类型
│   │   ├── consult.ts           # 咨询表单类型
│   │   ├── contact.ts           # 联系方式类型
│   │   ├── nav.ts               # 导航菜单类型
│   │   └── news.ts              # 新闻数据类型
│   ├── utils/                    # 工具函数(封装通用逻辑,避免重复代码)
│   │   ├── formatDate.ts        # 日期格式化(新闻发布时间、表单提交时间)
│   │   ├── formAutoFill.ts      # 表单自动填充工具
│   │   ├── request.ts           # 接口请求封装(基于Axios,解决跨域)
│   │   └── validate.ts          # 表单验证(手机号、邮箱格式校验)
│   ├── views/                    # 页面组件(对应六大功能模块,每个页面一个目录)
│   │   ├── About/               # 关于我们(企业概况、发展历程、团队介绍)
│   │   │   └── About.vue
│   │   ├── Business/            # 核心业务(业务分类、业务详情、客户案例)
│   │   │   └── Business.vue
│   │   ├── Consult/             # 在线咨询(咨询表单、FAQ列表、客服入口)
│   │   │   ├── Consult.vue      # 咨询表单页面
│   │   │   └── Contact.vue      # 联系表单组件
│   │   ├── Contact/             # 联系我们(联系信息、地图嵌入、留言表单)
│   │   │   └── Contact.vue
│   │   ├── Home/                # 首页(轮播图、企业简介、核心优势、案例预览)
│   │   │   └── Home.vue
│   │   └── News/                # 新闻动态(列表页、分类筛选、详情页)
│   │       ├── News.vue         # 新闻列表页
│   │       └── NewsDetail.vue   # 新闻详情页(动态路由传id)
│   ├── App.vue                  # 根组件(包裹所有页面,引入Navbar和Footer)
│   ├── main.ts                  # 入口文件(初始化Vue、路由、Pinia、全局样式)
│   ├── style.css                # 全局样式文件
│   └── vite-env.d.ts           # Vite 环境类型声明
├── public/                       # 公共静态资源(无需打包,直接访问)
│   └── vite.svg                 # Vite 默认图标
├── .git/                        # Git 版本控制目录
├── .vscode/                     # VS Code 编辑器配置
├── .gitignore                   # Git 忽略文件配置
├── .stylelintrc.json           # 样式代码规范配置
├── README.md                    # 项目说明文档
├── index.html                   # HTML 入口文件
├── package.json                 # 项目依赖与脚本配置(npm管理)
├── package-lock.json           # 依赖版本锁定文件
├── postcss.config.js           # PostCSS 配置文件
├── tailwind.config.js          # Tailwind CSS 配置文件
├── tsconfig.json               # TypeScript 配置文件
├── tsconfig.app.json           # 应用程序 TypeScript 配置
├── tsconfig.node.json          # Node.js TypeScript 配置
├── vite.config.ts              # Vite 配置文件(端口、代理、路径别名、构建优化)
├── 首页.png                     # 项目截图 - 首页
├── 关于我们.png                 # 项目截图 - 关于我们
├── 核心业务.png                 # 项目截图 - 核心业务
├── 新闻动态.png                 # 项目截图 - 新闻动态
├── 在线咨询.png                 # 项目截图 - 在线咨询
└── 联系我们.png                 # 项目截图 - 联系我们

 

三、核心依赖安装与配置:适配企业网站功能

通过 npm init vite@latest 创建的项目仅包含基础依赖,需额外安装路由、状态管理等核心工具,并配置 Vite 适配企业开发需求。

3.1、安装关键依赖(用 npm 命令)

执行以下 npm 命令,安装企业网站必需的依赖包:

# 1. 安装Vue Router(实现页面跳转,适配单页应用)
npm install vue-router@4  # Vue3需对应Vue Router 4.x版本

# 2. 安装Pinia(Vue3官方状态管理库,替代Vuex,原生支持TS)
npm install pinia

# 3. 安装Axios(处理接口请求,如咨询表单提交、新闻数据获取)
npm install axios

# 4. 安装Tailwind CSS(可选,快速实现响应式样式,减少手写CSS)
# 执行Tailwind初始化命令,自动生成配置文件
npx tailwindcss init -p

3.2、配置 Vite(vite.config.ts)

修改项目根目录的 vite.config.ts,优化路径别名、跨域代理与构建配置,确保开发效率与生产性能:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { fileURLToPath, URL } from 'node:url';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()], // 启用Vue插件,支持单文件组件解析
  // 路径别名:@指向src目录,简化文件引入(如@/components/Navbar.vue)
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  // 开发服务器配置:解决跨域、自定义端口
  server: {
    port: 8080, // 自定义端口(避免与其他项目冲突,默认5173)
    open: true, // 启动服务后自动打开浏览器
    proxy: {
      // 配置代理:解决企业网站对接后端接口的跨域问题
      '/api': {
        target: 'http://localhost:3000', // 后端接口地址(需替换为实际项目地址)
        changeOrigin: true, // 模拟浏览器同源请求,避免跨域拦截
        rewrite: (path) => path.replace(/^\/api/, '') // 移除请求路径中的/api前缀
      }
    }
  },
  // 生产构建配置:优化包体积,提升线上加载速度
  build: {
    outDir: 'dist', // 构建输出目录(默认dist,可自定义)
    assetsDir: 'static', // 静态资源(css、js、图片)存放目录
    sourcemap: false, // 生产环境不生成sourcemap(减少包体积,保护源码)
    rollupOptions: {
      // 代码分割:将第三方依赖(如vue、vue-router)单独打包,实现缓存复用
      output: {
        chunkFileNames: 'static/js/[name]-[hash].js', // 分包文件命名
        entryFileNames: 'static/js/[name]-[hash].js', // 入口文件命名
        assetFileNames: 'static/[ext]/[name]-[hash].[ext]' // 静态资源命名
      }
    }
  }
});

 

3.3、配置 Vue Router(路由管理)

在 Vite + TypeScript + Vue3 项目中执行 npm install vue-router@4 后,根目录下没有 router 文件夹,因为 npm install 只会只是安装依赖包,并不会自动创建路由配置文件或文件夹。
Vue Router 只是一个依赖包,安装后会存放在 node_modules 目录中,而路由相关的配置文件(如 router/index.ts)需要你手动创建。

 src/router/index.ts 中编写路由规则,实现六大页面的跳转与动态路由(新闻详情页):

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';
// 引入页面组件(使用懒加载,优化首屏加载速度)
const Home = () => import('@/views/Home/Home.vue');
const About = () => import('@/views/About/About.vue');
const Business = () => import('@/views/Business/Business.vue');
const News = () => import('@/views/News/News.vue');
const NewsDetail = () => import('@/views/News/NewsDetail.vue');
const Contact = () => import('@/views/Contact/Contact.vue');
const Consult = () => import('@/views/Consult/Consult.vue');

// 路由规则数组(TypeScript类型:RouteRecordRaw,确保配置规范)
const routes: RouteRecordRaw[] = [
  { path: '/', name: 'Home', component: Home }, // 首页
  { path: '/about', name: 'About', component: About }, // 关于我们
  { path: '/business', name: 'Business', component: Business }, // 核心业务
  { path: '/news', name: 'News', component: News }, // 新闻列表
  { 
    path: '/news/:id', // 新闻详情页:动态路由(通过id获取单条新闻数据)
    name: 'NewsDetail', 
    component: NewsDetail,
    props: true // 允许路由参数(如id)作为props传入组件,简化数据获取
  },
  { path: '/contact', name: 'Contact', component: Contact }, // 联系我们
  { path: '/consult', name: 'Consult', component: Consult }, // 在线咨询
  { path: '/:pathMatch(.*)*', redirect: '/' } // 404页面:重定向到首页
];

// 创建路由实例(HTML5历史模式,URL无#号,符合企业网站URL规范)
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes,
  // 滚动行为:跳转页面时自动回到顶部,提升用户体验
  scrollBehavior() {
    return { top: 0 };
  }
});

export default router;

 

image

这里有报错:

1、因为 src/views 目录不存在,但是路由文件中引用了这些视图组件。我需要创建缺失的视图组件。让我先创建 views 目录和所需的组件:

mkdir -p "d:\workspace\enterprise-website\src\views\About"
mkdir -p "d:\workspace\enterprise-website\src\views\Home"
mkdir -p "d:\workspace\enterprise-website\src\views\Business"
mkdir -p "d:\workspace\enterprise-website\src\views\News"
mkdir -p "d:\workspace\enterprise-website\src\views\Contact"
mkdir -p "d:\workspace\enterprise-website\src\views\Consult"

2、修复了 TypeScript 类型导入:RouteRecordRaw 改为 type RouteRecordRaw 以符合 TypeScript 的类型导入要求。

3、添加了 Vue 组件的类型声明:vite-env.d.ts 文件中添加了 *.vue 模块的类型声明

/// <reference types="vite/client" />

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

3.4、配置 Pinia(状态管理)

以“在线咨询表单”为例,在 src/stores/consultStore.ts 中编写状态管理逻辑,实现表单数据全局共享与提交:

1、先创建 src/types 目录,避免找不到 @/types/consult 模块:

mkdir -p src/types

2、增加路径别名 @ 指向 ./src,现在我们需要在 TypeScript 配置文件 tsconfig.app.json 中也添加相应的路径映射:

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}  

3、创建 src/stores/consultStore.ts 文件:

import { defineStore } from 'pinia';
import axios from 'axios';
// 引入表单类型定义(在src/types/consult.ts中提前定义,确保类型安全)
import type { ConsultForm } from '@/types/consult';

// 表单默认值(符合ConsultForm类型结构)
const defaultForm: ConsultForm = {
  name: '', // 用户姓名
  phone: '', // 手机号(需验证格式)
  type: 'product', // 咨询类型:product(产品)、service(服务)、other(其他)
  content: '' // 咨询内容
};

// 创建Pinia存储实例(命名为consult,全局唯一)
export const useConsultStore = defineStore('consult', {
  state: () => ({
    form: { ...defaultForm }, // 咨询表单数据(响应式)
    submitLoading: false // 提交按钮加载状态(避免重复提交)
  }),
  actions: {
    // 更新表单字段(key限定为ConsultForm的属性,确保类型正确)
    updateFormField<K extends keyof ConsultForm>(key: K, value: ConsultForm[K]) {
      this.form[key] = value;
    },
    // 重置表单(提交成功或取消时调用)
    resetForm() {
      this.form = { ...defaultForm };
    },
    // 提交表单(对接后端接口,返回提交结果)
    async submitForm() {
      this.submitLoading = true;
      try {
        // 调用后端接口(通过Vite proxy配置,自动转换为后端地址)
        await axios.post('/api/consult', this.form);
        // 提交成功:重置表单+关闭加载
        this.resetForm();
        this.submitLoading = false;
        return { success: true, message: '咨询提交成功,工作人员将尽快联系您' };
      } catch (error) {
        // 提交失败:关闭加载+返回错误信息
        this.submitLoading = false;
        return { success: false, message: '提交失败,请检查网络后重试' };
      }
    }
  }
});

 

4、遇到报错,发现需要创建 ConsultForm 类型定义文件(src\types\consult.ts)。根据 consultStore.ts 中的使用情况,我可以看到 ConsultForm 应该包含 name、phone、type 和 content 字段。

  • 创建了 src/types 目录
  • 创建了 src/types/consult.ts 文件,定义了:
    • ConsultForm 接口
    • ConsultType 类型
    • ConsultSubmitResult 接口

3.5、初始化入口文件(main.ts)

修改 src/main.ts,引入路由、Pinia 与全局样式,完成 Vue 实例初始化:

import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // 引入路由
import { createPinia } from 'pinia'; // 引入Pinia
import './assets/styles/fonts.css'; // 首先引入字体样式
import './assets/styles/reset.css'; // 引入全局重置样式
// 若使用Tailwind,需引入Tailwind样式文件(在src/assets/styles下创建)
import './assets/styles/tailwind.css';

const app = createApp(App);
// 挂载路由与Pinia
app.use(router);
app.use(createPinia());
// 挂载Vue实例到页面#app节点
app.mount('#app');

四、核心功能实现:公共组件与页面开发

基于上述配置,从“公共组件”到“业务页面”逐步实现企业网站功能,以导航栏、首页为例展示开发思路,其他页面可参考扩展。

4.1、公共组件:导航栏(Navbar.vue)

导航栏是企业网站的“全局入口”,需实现 PC 端多菜单展示、移动端折叠菜单、当前页面高亮 三大核心功能,同时通过 TypeScript 定义菜单类型确保数据规范。以下是完整实现代码(vue3-enterprise-website/src/components/Navbar.vue):

<template>
  <!-- 导航栏容器:固定顶部,适配移动端 -->
  <header class="navbar fixed top-0 left-0 w-full bg-white shadow-sm z-50">
    <div class="container mx-auto px-4 py-3 flex justify-between items-center">
      <!-- 1. Logo区域:点击跳转首页 -->
      <div 
        class="navbar-logo cursor-pointer flex items-center"
        @click="$router.push('/')"
      >
        <div class="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center">
          <span class="text-white font-bold text-xl">E</span>
        </div>
        <span class="ml-2 text-xl font-bold text-blue-700">企业网站</span>
      </div>

      <!-- 2. PC端导航菜单(屏幕≥768px显示) -->
      <nav class="hidden md:flex items-center space-x-8">
        <router-link
          v-for="item in navItems"
          :key="item.path"
          :to="item.path"
          class="nav-link"
          :class="{ 'nav-link-active': $route.path === item.path }"
        >
          {{ item.label }}
        </router-link>
        <!-- 咨询按钮:突出显示,跳转咨询页 -->
        <button
          class="btn btn-primary"
          @click="$router.push('/consult')"
        >
          在线咨询
        </button>
      </nav>

      <!-- 3. 移动端菜单按钮(屏幕<768px显示) -->
      <button 
        class="md:hidden text-gray-700 text-2xl p-2"
        @click="mobileMenuState.isOpen = !mobileMenuState.isOpen"
      >
        <span v-if="!mobileMenuState.isOpen">☰</span>
        <span v-else>×</span>
      </button>
    </div>

    <!-- 4. 移动端折叠菜单(默认隐藏,点击按钮展开) -->
    <div 
      class="md:hidden bg-white border-t border-gray-100 transition-all duration-300"
      :class="{ 'block': mobileMenuState.isOpen, 'hidden': !mobileMenuState.isOpen }"
    >
      <div class="container mx-auto px-4 py-2 flex flex-col space-y-3">
        <router-link
          v-for="item in navItems"
          :key="item.path"
          :to="item.path"
          class="py-2 text-gray-700 hover:text-blue-700 font-medium"
          :class="{ 'text-blue-700': $route.path === item.path }"
          @click="mobileMenuState.isOpen = false"
        >
          {{ item.label }}
        </router-link>
        <button
          class="btn btn-primary mt-2"
          @click="() => { $router.push('/consult'); mobileMenuState.isOpen = false }"
        >
          在线咨询
        </button>
      </div>
    </div>
  </header>
</template>

<script setup lang="ts">
import { reactive } from 'vue';
// import { useRoute } from 'vue-router'; // 暂时注释掉未使用的import
import type { NavItem, MobileMenuState } from '@/types/nav';

// 1. 响应式状态:控制移动端菜单展开/隐藏
const mobileMenuState = reactive<MobileMenuState>({
  isOpen: false,
  activeSubmenu: null
});

// 2. 获取当前路由信息(用于菜单高亮)
// const route = useRoute(); // 暂时注释掉未使用的变量

// 3. 导航菜单数据(符合NavItem类型,可后续从接口获取)
const navItems: NavItem[] = [
  { path: '/', label: '首页' },
  { path: '/about', label: '关于我们' },
  { path: '/business', label: '核心业务' },
  { path: '/news', label: '新闻动态' },
  { path: '/contact', label: '联系我们' },
];
</script>

<style scoped>
/* 导航栏滚动效果(可选) */
.navbar-scroll {
  background-color: rgba(255, 255, 255, 0.95);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

/* 导航链接过渡效果 - 确保中文字体 */
.nav-link {
  position: relative;
  transition: all 0.3s ease;
  font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'STHeiti', 'Helvetica Neue', Arial, sans-serif !important;
}

.nav-link::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 0;
  width: 0;
  height: 2px;
  background-color: #2563eb;
  transition: width 0.3s ease;
}

.nav-link:hover::after,
.nav-link-active::after {
  width: 100%;
}

/* 确保 Logo 和按钮也使用中文字体 */
.navbar-logo,
.btn {
  font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'STHeiti', 'Helvetica Neue', Arial, sans-serif !important;
}
</style>

4.2、公共组件:页脚(Footer.vue)

页脚作为企业网站的“全局收尾”组件,是传递企业基础信息、强化品牌信任度与提升用户体验的关键载体,需与导航栏形成功能互补,承担“信息补充 + 用户引导”的双重角色。从企业网站的实用性与合规性出发,该组件需实现三大核心功能:

      • 基础信息展示:统一呈现企业工商信息(如公司全称、注册资本、经营范围)、联系方式(固定电话、邮箱、总部地址)及备案信息(ICP 备案号、公安备案号),确保信息透明且符合互联网网站运营规范;​
      • 导航补充引导:针对用户在页面底部的操作需求,设置 “快速链接” 模块,包含 “隐私政策”“服务条款”“常见问题”“招聘信息” 等低频但必要的入口,同时可添加 “回到顶部” 按钮,优化长页面的浏览体验;​
      • 品牌形象延伸:集成企业社交媒体入口(微信公众号二维码、微博、LinkedIn 等图标链接),搭配企业 Slogan 与版权声明,强化品牌记忆点。
<template>
  <footer class="bg-gray-900 text-white">
    <!-- 主要内容区域 -->
    <div class="container mx-auto px-4 py-12">
      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
        <!-- 公司信息 -->
        <div class="space-y-4">
          <div class="flex items-center">
            <div class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center">
              <span class="text-white font-bold">E</span>
            </div>
            <span class="ml-2 text-lg font-bold">企业网站</span>
          </div>
          <p class="text-gray-300 text-sm leading-relaxed">
            专业的企业服务提供商,致力于为客户提供高质量的解决方案,助力企业数字化转型升级。
          </p>
          <div class="flex space-x-4">
            <a 
              v-for="social in socialLinks"
              :key="social.platform"
              :href="social.url"
              :title="social.label"
              class="text-gray-400 hover:text-white transition-colors duration-200"
              target="_blank"
              rel="noopener noreferrer"
            >
              <span class="text-xl">{{ social.icon }}</span>
            </a>
          </div>
        </div>

        <!-- 快速链接 -->
        <div class="space-y-4">
          <h3 class="text-lg font-semibold">快速链接</h3>
          <ul class="space-y-2">
            <li v-for="link in quickLinks" :key="link.path">
              <router-link 
                :to="link.path"
                class="text-gray-300 hover:text-white transition-colors duration-200 text-sm"
              >
                {{ link.label }}
              </router-link>
            </li>
          </ul>
        </div>

        <!-- 服务项目 -->
        <div class="space-y-4">
          <h3 class="text-lg font-semibold">服务项目</h3>
          <ul class="space-y-2">
            <li v-for="service in services" :key="service">
              <span class="text-gray-300 text-sm">{{ service }}</span>
            </li>
          </ul>
        </div>

        <!-- 联系信息 -->
        <div class="space-y-4">
          <h3 class="text-lg font-semibold">联系我们</h3>
          <div class="space-y-3">
            <div class="flex items-start space-x-3">
              <span class="text-blue-400 mt-1">📍</span>
              <div>
                <p class="text-gray-300 text-sm">{{ contactInfo.address }}</p>
              </div>
            </div>
            <div class="flex items-center space-x-3">
              <span class="text-blue-400">📞</span>
              <a 
                :href="`tel:${contactInfo.phone}`"
                class="text-gray-300 hover:text-white transition-colors duration-200 text-sm"
              >
                {{ contactInfo.phone }}
              </a>
            </div>
            <div class="flex items-center space-x-3">
              <span class="text-blue-400">📧</span>
              <a 
                :href="`mailto:${contactInfo.email}`"
                class="text-gray-300 hover:text-white transition-colors duration-200 text-sm"
              >
                {{ contactInfo.email }}
              </a>
            </div>
            <div class="flex items-center space-x-3">
              <span class="text-blue-400">⏰</span>
              <span class="text-gray-300 text-sm">{{ contactInfo.workingHours }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 版权信息 -->
    <div class="border-t border-gray-800">
      <div class="container mx-auto px-4 py-6">
        <div class="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
          <div class="text-gray-400 text-sm">
            <p>© {{ currentYear }} 企业网站. 保留所有权利.</p>
          </div>
          <div class="flex items-center space-x-6 text-sm">
            <a href="#" class="text-gray-400 hover:text-white transition-colors duration-200">
              隐私政策
            </a>
            <a href="#" class="text-gray-400 hover:text-white transition-colors duration-200">
              服务条款
            </a>
            <a href="#" class="text-gray-400 hover:text-white transition-colors duration-200">
              网站地图
            </a>
            <span class="text-gray-400">
              ICP备案号:沪ICP备2023037106号-1
            </span>
          </div>
        </div>
      </div>
    </div>
  </footer>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import type { NavItem } from '@/types/nav';
import type { ContactInfo, SocialMediaLink } from '@/types/contact';

// 当前年份
const currentYear = computed(() => new Date().getFullYear());

// 快速链接数据
const quickLinks: NavItem[] = [
  { path: '/', label: '首页' },
  { path: '/about', label: '关于我们' },
  { path: '/business', label: '核心业务' },
  { path: '/news', label: '新闻动态' },
  { path: '/contact', label: '联系我们' },
  { path: '/consult', label: '在线咨询' },
];

// 服务项目
const services: string[] = [
  '企业官网建设',
  '电商平台开发',
  '移动应用开发',
  '系统集成服务',
  '技术咨询服务',
  '运维支持服务',
];

// 社交媒体链接
const socialLinks: SocialMediaLink[] = [
  {
    platform: 'wechat',
    url: '#',
    icon: '💬',
    label: '微信'
  },
  {
    platform: 'weibo',
    url: '#',
    icon: '🐦',
    label: '微博'
  },
  {
    platform: 'linkedin',
    url: '#',
    icon: '💼',
    label: 'LinkedIn'
  },
  {
    platform: 'github',
    url: '#',
    icon: '🐙',
    label: 'GitHub'
  },
];

// 联系信息
const contactInfo: ContactInfo = {
  address: '北京市朝阳区建国门外大街1号',
  phone: '400-123-4567',
  email: 'support@zuoyangs.com',
  workingHours: '周一至周五 9:00-18:00',
  website: 'https://www.company.com',
  socialMedia: socialLinks
};
</script>

<style scoped>
/* 页脚链接悬停效果 */
footer a {
  position: relative;
}

footer a::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 1px;
  background-color: currentColor;
  transition: width 0.3s ease;
}

footer a:hover::after {
  width: 100%;
}
</style>

4.3、页面开发:关于我们页面(About.vue)

“关于我们”是企业传递品牌理念、建立用户信任的核心页面,需围绕 “用户想了解什么” 构建内容逻辑,避免单纯的 “企业自夸”。页面开发需聚焦三大核心模块,同时兼顾视觉设计与交互体验:

4.3.1、页面结构设计(核心模块)

      • 品牌故事模块:以“场景化叙事”替代“文字堆砌”,例如通过 “企业创立初衷→发展里程碑→核心价值观” 的逻辑,搭配时间轴组件(展示关键节点,如成立时间、重大合作、资质认证),让用户直观感知企业历程;可嵌入短视频或高清图片(如办公环境、团队风貌),增强内容感染力。​
      • 核心团队模块:针对 B 端客户或合作伙伴关注的“团队专业性”,展示核心管理层 / 技术团队的信息(姓名、职位、从业经验、擅长领域),搭配职业形象照,传递“专业可靠”的团队形象;若企业注重“人性化”,可添加团队成员的个人标签(如“技术控”“客户体验守护者”),拉近与用户的距离。​
      • 企业资质模块:以“可视化卡片”形式展示企业资质(如 ISO 认证、行业资质证书、专利证书),支持点击查看高清证书图片;同时列出企业获得的荣誉奖项(如“行业百强企业”“最佳服务奖”),增强品牌权威性。

4.3.2、技术实现要点

      • 数据管理:通过 Vue3 的reactive/ref管理页面动态数据(如团队成员列表、资质证书列表),若数据需从后端获取,可结合 Axios 发起请求,并添加加载状态(如骨架屏),避免页面空白导致的用户等待焦虑;​
      • 交互优化:为时间轴节点添加 “hover 高亮 + 详情弹窗” 效果,点击资质卡片时通过 “过渡动画” 展示高清证书;针对移动端,优化触摸交互(如增大点击区域、添加滑动切换效果);​
      • SEO 适配:在页面头部设置明确的title(如 “XX 企业 - 关于我们:专注 XX 领域的 XX 服务商”)与meta标签(description描述企业核心优势与定位),同时对核心内容(如企业价值观、关键资质)使用语义化标签(<h2>``<p>),提升搜索引擎收录效果。
<template>
  <div class="about-page">
    <!-- 页面头部 -->
    <section class="bg-gradient-primary text-white py-20">
      <div class="container text-center">
        <h1 class="page-title text-white mb-4">关于我们</h1>
        <p class="text-xl opacity-90 max-w-2xl mx-auto">
          专业的企业服务提供商,致力于为客户提供高质量的解决方案
        </p>
      </div>
    </section>

    <!-- 公司概况 -->
    <section class="py-16">
      <div class="container">
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
          <div class="space-y-6">
            <h2 class="section-title">公司概况</h2>
            <p class="text-gray-600 text-lg leading-relaxed">
              我们成立于{{ companyInfo.foundedYear }}年,是一家专注于企业数字化服务的高新技术企业。
              多年来,我们始终坚持"技术创新、客户至上"的服务理念,为数百家企业提供了专业的技术解决方案。
            </p>
            <p class="text-gray-600 leading-relaxed">
              公司拥有一支经验丰富的技术团队,涵盖软件开发、系统集成、项目管理等多个专业领域。
              我们深入理解各行业的业务特点,能够为客户量身定制最适合的解决方案。
            </p>
            <div class="grid grid-cols-2 gap-6">
              <div class="text-center p-6 bg-blue-50 rounded-lg">
                <div class="text-3xl font-bold text-blue-600 mb-2">{{ companyInfo.teamSize }}+</div>
                <div class="text-gray-600">团队成员</div>
              </div>
              <div class="text-center p-6 bg-green-50 rounded-lg">
                <div class="text-3xl font-bold text-green-600 mb-2">{{ companyInfo.projectCount }}+</div>
                <div class="text-gray-600">成功项目</div>
              </div>
            </div>
          </div>
          <div class="relative">
            <img
              :src="companyInfo.officeImage"
              alt="公司办公环境"
              class="rounded-lg shadow-lg w-full h-auto"
            />
            <div class="absolute inset-0 bg-blue-600 bg-opacity-10 rounded-lg"></div>
          </div>
        </div>
      </div>
    </section>

    <!-- 企业文化 -->
    <section class="py-16 bg-gray-50">
      <div class="container">
        <div class="text-center mb-12">
          <h2 class="section-title">企业文化</h2>
          <p class="text-gray-600 text-lg">我们的价值观与使命</p>
        </div>
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
          <div
            v-for="value in companyValues"
            :key="value.id"
            class="text-center group"
          >
            <div class="w-20 h-20 mx-auto mb-4 bg-blue-100 rounded-full flex items-center justify-center group-hover:bg-blue-200 transition-colors duration-300">
              <span class="text-3xl">{{ value.icon }}</span>
            </div>
            <h3 class="text-xl font-semibold mb-3">{{ value.title }}</h3>
            <p class="text-gray-600">{{ value.description }}</p>
          </div>
        </div>

        <!-- 使命愿景 -->
        <div class="mt-16 grid grid-cols-1 lg:grid-cols-2 gap-12">
          <div class="text-center lg:text-left">
            <h3 class="text-2xl font-semibold mb-4 text-blue-600">我们的使命</h3>
            <p class="text-gray-600 text-lg leading-relaxed">
              通过技术创新和专业服务,帮助企业实现数字化转型,
              提升运营效率,创造更大的商业价值。
            </p>
          </div>
          <div class="text-center lg:text-right">
            <h3 class="text-2xl font-semibold mb-4 text-blue-600">我们的愿景</h3>
            <p class="text-gray-600 text-lg leading-relaxed">
              成为行业领先的企业服务提供商,以卓越的技术和服务,
              成为客户最信赖的合作伙伴。
            </p>
          </div>
        </div>
      </div>
    </section>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { Images } from '@/assets/images';

// 公司信息
const companyInfo = ref({
  foundedYear: 2014,
  teamSize: 50,
  projectCount: 500,
  officeImage: Images.about.officeEnvironment
});

// 企业价值观
const companyValues = ref([
  {
    id: '1',
    title: '客户至上',
    description: '始终以客户需求为导向,提供最优质的服务',
    icon: '🎯'
  },
  {
    id: '2',
    title: '技术创新',
    description: '持续技术创新,为客户提供前沿的解决方案',
    icon: '💡'
  },
  {
    id: '3',
    title: '团队协作',
    description: '相互信任,协同合作,共同创造价值',
    icon: '🤝'
  },
  {
    id: '4',
    title: '追求卓越',
    description: '不断追求卓越,在每个细节上精益求精',
    icon: '⭐'
  }
]);
</script>

<style scoped>
/* 响应式适配 */
@media (max-width: 768px) {
  .values-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
</style>

4.4、页面开发:核心业务页面(Business.vue)

“核心业务”页面是企业向用户传递“能提供什么价值” 的关键载体,需以“用户需求为导向”,清晰展示业务范围、服务优势与应用场景,避免技术术语堆砌导致的理解门槛。页面开发需实现“信息清晰化 + 转化引导化”,核心设计思路如下:

4.4.1、页面结构设计(核心模块)

      • 业务分类导航:在页面顶部设置 “业务分类标签栏”(如 “智能制造解决方案”“企业数字化转型服务”“云平台技术支持”),支持点击切换对应业务内容;标签栏需实现 “当前业务高亮” 效果,且在移动端适配为 “横向滑动导航”,避免换行挤压。​
      • 业务详情模块:针对每个业务分类,采用 “‘价值主张 + 服务内容 + 应用案例’三位一体” 的结构设计:​
        • 价值主张:用 1-2 句话明确该业务能为用户解决的核心问题(如 “帮助制造企业降低 30% 生产能耗”“为中小企业提供零代码数字化转型工具”),直击用户痛点;​
        • 服务内容:以 “图标 + 文字” 的列表形式,拆解业务包含的具体服务(如 “需求调研→方案设计→部署实施→售后维护”),让用户清晰了解服务流程;​
        • 应用案例:嵌入 1-2 个典型客户案例(脱敏处理客户名称,如 “某头部汽车零部件企业”),搭配案例成果数据(如 “项目周期 2 个月,实现生产效率提升 25%”),增强业务说服力。​
      • 转化引导模块:在每个业务详情底部添加 “立即咨询”“获取方案” 按钮,点击跳转至 “联系我们” 页面或弹出咨询表单;同时可设置 “业务对比表”(若企业业务存在差异化定位),清晰展示不同业务的适用场景、核心优势与价格区间(或 “面议” 引导),帮助用户快速决策。

4.4.2、 技术实现要点

      • 组件复用:将 “业务详情卡片”“案例展示卡片” 封装为可复用子组件(如BusinessCard.vue、CaseCard.vue),通过 Props 传递不同业务数据,减少代码冗余;​
      • 动态交互:标签栏切换时添加 “内容过渡动画”(如淡入淡出、滑动切换),提升页面流畅度;案例卡片支持 “hover 放大 + 阴影效果”,增强视觉焦点;​
      • 响应式适配:PC 端采用 “2 列 / 3 列卡片布局” 展示业务,移动端自动切换为 “单列布局”,确保内容不挤压;同时优化表单交互(如移动端适配输入键盘、添加表单验证提示),降低用户转化门槛。
<template>
  <div class="business-page">
    <!-- 页面头部 -->
    <section class="bg-gradient-primary text-white py-20">
      <div class="container text-center">
        <h1 class="page-title text-white mb-4">核心业务</h1>
        <p class="text-xl opacity-90 max-w-2xl mx-auto">
          提供全方位的企业服务解决方案,助力企业数字化转型升级
        </p>
      </div>
    </section>

    <!-- 业务分类筛选 -->
    <section class="py-8 bg-white sticky top-16 z-40 shadow-sm">
      <div class="container">
        <div class="flex flex-wrap justify-center gap-4">
          <button
            v-for="category in businessCategories"
            :key="category.key"
            class="px-6 py-2 rounded-full transition-all duration-300"
            :class="[
              selectedCategory === category.key
                ? 'bg-blue-600 text-white'
                : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
            ]"
            @click="filterByCategory(category.key)"
          >
            {{ category.label }}
          </button>
          <button
            class="px-6 py-2 rounded-full transition-all duration-300"
            :class="[
              selectedCategory === null
                ? 'bg-blue-600 text-white'
                : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
            ]"
            @click="showAllServices"
          >
            全部服务
          </button>
        </div>
      </div>
    </section>

    <!-- 业务服务列表 -->
    <section class="py-16">
      <div class="container">
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-12">
          <div
            v-for="service in filteredServices"
            :key="service.id"
            class="service-card bg-white rounded-lg shadow-lg overflow-hidden hover:shadow-xl transition-all duration-300"
          >
            <div class="relative h-64">
              <img
                :src="service.imageUrl || getDefaultServiceImage(service.category)"
                :alt="service.title"
                class="w-full h-full object-cover"
              />
              <div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
              <div class="absolute bottom-4 left-4">
                <span 
                  class="px-3 py-1 rounded-full text-sm font-medium text-white"
                  :style="{ backgroundColor: getCategoryColor(service.category) }"
                >
                  {{ getCategoryLabel(service.category) }}
                </span>
              </div>
            </div>
            
            <div class="p-8">
              <div class="flex items-start justify-between mb-4">
                <div class="flex items-center">
                  <div 
                    class="w-12 h-12 rounded-lg flex items-center justify-center text-white text-xl mr-4"
                    :style="{ backgroundColor: getCategoryColor(service.category) }"
                  >
                    {{ service.iconUrl || getDefaultIcon(service.category) }}
                  </div>
                  <h3 class="text-2xl font-semibold text-gray-900">{{ service.title }}</h3>
                </div>
              </div>
              
              <p class="text-gray-600 mb-6 leading-relaxed">{{ service.description }}</p>
              
              <!-- 特色功能 -->
              <div v-if="service.features.length > 0" class="mb-6">
                <h4 class="font-semibold text-gray-900 mb-3">特色功能</h4>
                <ul class="space-y-2">
                  <li 
                    v-for="feature in service.features.slice(0, 3)"
                    :key="feature"
                    class="flex items-center text-sm text-gray-600"
                  >
                    <span class="w-1.5 h-1.5 bg-blue-600 rounded-full mr-3"></span>
                    {{ feature }}
                  </li>
                </ul>
                <button
                  v-if="service.features.length > 3"
                  class="text-blue-600 text-sm hover:text-blue-800 transition-colors duration-200 mt-2"
                  @click="toggleServiceDetails(service.id)"
                >
                  {{ expandedServices.includes(service.id) ? '收起' : `查看全部 ${service.features.length} 项功能` }}
                </button>
              </div>
              
              <!-- 展开的详细功能 -->
              <div 
                v-if="expandedServices.includes(service.id) && service.features.length > 3"
                class="mb-6 animate-fade-in"
              >
                <ul class="space-y-2">
                  <li 
                    v-for="feature in service.features.slice(3)"
                    :key="feature"
                    class="flex items-center text-sm text-gray-600"
                  >
                    <span class="w-1.5 h-1.5 bg-blue-600 rounded-full mr-3"></span>
                    {{ feature }}
                  </li>
                </ul>
              </div>
              
              <!-- 核心优势 -->
              <div v-if="service.advantages.length > 0" class="mb-6">
                <h4 class="font-semibold text-gray-900 mb-3">核心优势</h4>
                <div class="grid grid-cols-2 gap-3">
                  <div
                    v-for="advantage in service.advantages.slice(0, 4)"
                    :key="advantage"
                    class="bg-gray-50 rounded-lg p-3 text-center"
                  >
                    <span class="text-sm font-medium text-gray-700">{{ advantage }}</span>
                  </div>
                </div>
              </div>
              
              <!-- 操作按钮 -->
              <div class="flex space-x-4 pt-4 border-t border-gray-100">
                <button 
                  class="btn btn-primary flex-1"
                  @click="contactForService(service)"
                >
                  立即咨询
                </button>
                <button 
                  class="btn btn-outline flex-1"
                  @click="learnMore(service)"
                >
                  了解详情
                </button>
              </div>
            </div>
          </div>
        </div>

        <!-- 无结果提示 -->
        <div v-if="filteredServices.length === 0" class="text-center py-12">
          <div class="text-gray-400 text-6xl mb-4">🔍</div>
          <h3 class="text-xl font-medium text-gray-600 mb-2">暂无相关服务</h3>
          <p class="text-gray-500">请尝试选择其他分类或查看全部服务</p>
        </div>
      </div>
    </section>

    <!-- 客户案例 -->
    <section class="py-16 bg-gray-50">
      <div class="container">
        <div class="text-center mb-12">
          <h2 class="section-title">成功案例</h2>
          <p class="text-gray-600 text-lg">看看我们为客户创造的价值</p>
        </div>
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
          <div
            v-for="case_item in businessCases"
            :key="case_item.id"
            class="card hover:shadow-lg transition-shadow duration-300"
          >
            <div class="aspect-w-16 aspect-h-9">
              <img
                :src="case_item.imageUrl"
                :alt="case_item.title"
                class="w-full h-48 object-cover rounded-t-lg"
              />
            </div>
            <div class="card-body">
              <div class="flex items-center justify-between mb-3">
                <span 
                  class="tag"
                  :style="{ 
                    backgroundColor: getCategoryColor(case_item.serviceType) + '20',
                    color: getCategoryColor(case_item.serviceType)
                  }"
                >
                  {{ getCategoryLabel(case_item.serviceType) }}
                </span>
                <span class="text-sm text-gray-500">{{ case_item.projectDuration }}</span>
              </div>
              <h3 class="text-lg font-semibold mb-2">{{ case_item.title }}</h3>
              <p class="text-gray-600 text-sm mb-3">客户:{{ case_item.client }}</p>
              <p class="text-gray-600 text-sm mb-4 text-ellipsis-2">{{ case_item.description }}</p>
              <div class="space-y-2">
                <div class="text-sm">
                  <span class="font-medium text-gray-700">项目成果:</span>
                  <span class="text-gray-600">{{ case_item.result }}</span>
                </div>
                <div class="flex flex-wrap gap-1">
                  <span
                    v-for="tech in case_item.technologies.slice(0, 3)"
                    :key="tech"
                    class="tag tag-secondary text-xs"
                  >
                    {{ tech }}
                  </span>
                  <span
                    v-if="case_item.technologies.length > 3"
                    class="text-xs text-gray-500"
                  >
                    +{{ case_item.technologies.length - 3 }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- CTA区域 -->
    <section class="py-16 bg-gradient-primary text-white">
      <div class="container text-center">
        <h2 class="text-3xl font-bold mb-4">准备开始您的项目了吗?</h2>
        <p class="text-xl mb-8 opacity-90 max-w-2xl mx-auto">
          我们的专业团队将为您提供量身定制的解决方案,助力您的业务发展
        </p>
        <div class="space-x-4">
          <router-link 
            to="/consult" 
            class="btn bg-white text-blue-600 hover:bg-gray-100"
          >
            免费咨询
          </router-link>
          <router-link 
            to="/contact" 
            class="btn bg-white text-blue-600 hover:bg-gray-100"
          >
            联系我们
          </router-link>
        </div>
      </div>
    </section>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';
import type { BusinessService, BusinessCategory, BusinessCategoryConfig, BusinessCase } from '@/types/business';
import { getDefaultServiceImage, Images } from '@/assets/images';

const router = useRouter();

// 响应式数据
const selectedCategory = ref<BusinessCategory | null>(null);
const expandedServices = ref<string[]>([]);

// 业务分类配置
const businessCategories: BusinessCategoryConfig[] = [
  { key: 'consulting', label: '技术咨询', description: '专业的技术咨询服务', color: '#3b82f6' },
  { key: 'development', label: '软件开发', description: '定制化软件开发服务', color: '#10b981' },
  { key: 'maintenance', label: '运维支持', description: '系统运维和技术支持', color: '#f59e0b' },
  { key: 'training', label: '培训服务', description: '专业技术培训服务', color: '#8b5cf6' }
];

// 业务服务数据
const businessServices = ref<BusinessService[]>([
  {
    id: '1',
    title: '企业官网建设',
    description: '专业的企业官网设计与开发,提升企业形象和品牌价值。采用最新的前端技术,确保网站的性能和用户体验。',
    detailContent: '详细的企业官网建设服务介绍...',
    features: [
      '响应式设计,适配各种设备',
      'SEO优化,提升搜索排名',
      '内容管理系统,方便维护',
      '多语言支持',
      '高性能优化',
      '安全防护机制'
    ],
    advantages: [
      '专业设计团队',
      '技术领先',
      '服务完善',
      '性价比高'
    ],
    imageUrl: Images.business.websiteDevelopment,
    category: 'development',
    order: 1,
    isActive: true
  },
  {
    id: '2',
    title: '系统集成服务',
    description: '为企业提供完整的系统集成解决方案,优化业务流程,提升运营效率。整合各种业务系统,实现数据互通。',
    detailContent: '详细的系统集成服务介绍...',
    features: [
      '多系统整合',
      '数据同步',
      '流程优化',
      '接口开发',
      '性能监控',
      '故障诊断'
    ],
    advantages: [
      '经验丰富',
      '技术全面',
      '响应及时',
      '质量保证'
    ],
    imageUrl: Images.business.systemIntegration,
    category: 'consulting',
    order: 2,
    isActive: true
  },
  {
    id: '3',
    title: '移动应用开发',
    description: '专业的移动应用开发团队,打造优质的移动端体验。支持iOS和Android双平台,提供原生和混合开发方案。',
    detailContent: '详细的移动应用开发服务介绍...',
    features: [
      'iOS/Android双平台',
      '原生应用开发',
      '混合应用开发',
      'UI/UX设计',
      '性能优化',
      '应用商店上架'
    ],
    advantages: [
      '技术专业',
      '设计精美',
      '性能优异',
      '用户体验佳'
    ],
    imageUrl: Images.business.mobileDevelopment,
    category: 'development',
    order: 3,
    isActive: true
  },
  {
    id: '4',
    title: '云平台服务',
    description: '基于云计算的企业服务平台,提供弹性、可扩展的云解决方案。支持公有云、私有云和混合云部署。',
    detailContent: '详细的云平台服务介绍...',
    features: [
      '多云支持',
      '弹性扩容',
      '数据备份',
      '监控告警',
      '自动运维',
      '安全防护'
    ],
    advantages: [
      '成本降低',
      '高可用性',
      '快速部署',
      '专业运维'
    ],
    imageUrl: Images.hero.carousel1,
    category: 'maintenance',
    order: 4,
    isActive: true
  },
  {
    id: '5',
    title: '技术培训服务',
    description: '提供专业的技术培训服务,提升团队技术能力。涵盖前端、后端、DevOps等多个技术领域。',
    detailContent: '详细的技术培训服务介绍...',
    features: [
      '定制化课程',
      '实战项目',
      '专家授课',
      '在线学习',
      '考核认证',
      '后续支持'
    ],
    advantages: [
      '课程丰富',
      '师资优秀',
      '实用性强',
      '效果显著'
    ],
    imageUrl: Images.business.trainingService,
    category: 'training',
    order: 5,
    isActive: true
  },
  {
    id: '6',
    title: '数据分析服务',
    description: '专业的数据分析和商业智能服务,帮助企业从数据中发现商业价值,做出更明智的决策。',
    detailContent: '详细的数据分析服务介绍...',
    features: [
      '数据采集',
      '数据清洗',
      '分析建模',
      '可视化展示',
      '报表生成',
      '决策支持'
    ],
    advantages: [
      '专业团队',
      '先进工具',
      '深度洞察',
      '决策支持'
    ],
    imageUrl: Images.news.industryNews,
    category: 'consulting',
    order: 6,
    isActive: true
  }
]);

// 客户案例数据
const businessCases = ref<BusinessCase[]>([
  {
    id: '1',
    title: '某大型制造企业ERP系统',
    client: '某制造集团',
    description: '为大型制造企业定制开发ERP系统,整合生产、销售、财务等各个业务模块',
    serviceType: 'development',
    imageUrl: Images.business.caseManufacturing,
    projectDuration: '8个月',
    result: '提升运营效率35%,降低成本20%',
    technologies: ['Vue.js', 'Spring Boot', 'MySQL', 'Redis', 'Docker']
  },
  {
    id: '2',
    title: '金融机构数字化转型',
    client: '某城市银行',
    description: '协助金融机构进行数字化转型,升级核心业务系统,提升客户服务质量',
    serviceType: 'consulting',
    imageUrl: Images.news.awardNews,
    projectDuration: '12个月',
    result: '客户满意度提升40%,处理效率提升50%',
    technologies: ['微服务架构', '区块链', '大数据', 'AI算法']
  },
  {
    id: '3',
    title: '电商平台运维服务',
    client: '某电商公司',
    description: '为电商平台提供7x24小时运维服务,确保系统稳定运行',
    serviceType: 'maintenance',
    imageUrl: Images.news.eventNews,
    projectDuration: '持续服务',
    result: '系统可用性达到99.9%,故障响应时间缩短70%',
    technologies: ['Kubernetes', 'Prometheus', 'ELK Stack', 'Jenkins']
  }
]);

// 计算属性
const filteredServices = computed(() => {
  if (selectedCategory.value === null) {
    return businessServices.value.filter(service => service.isActive);
  }
  return businessServices.value.filter(
    service => service.isActive && service.category === selectedCategory.value
  );
});

// 方法
const filterByCategory = (category: BusinessCategory) => {
  selectedCategory.value = category;
};

const showAllServices = () => {
  selectedCategory.value = null;
};

const toggleServiceDetails = (serviceId: string) => {
  const index = expandedServices.value.indexOf(serviceId);
  if (index > -1) {
    expandedServices.value.splice(index, 1);
  } else {
    expandedServices.value.push(serviceId);
  }
};

const getCategoryLabel = (category: BusinessCategory): string => {
  const config = businessCategories.find(c => c.key === category);
  return config?.label || '其他';
};

const getCategoryColor = (category: BusinessCategory): string => {
  const config = businessCategories.find(c => c.key === category);
  return config?.color || '#6b7280';
};

const getDefaultIcon = (category: BusinessCategory): string => {
  const icons = {
    consulting: '💡',
    development: '💻',
    maintenance: '🛠️',
    training: '📚'
  };
  return icons[category] || '⚙️';
};

const contactForService = (service: BusinessService) => {
  router.push({
    path: '/consult',
    query: {
      service: service.id,
      type: 'service'
    }
  });
};

const learnMore = (service: BusinessService) => {
  // 这里可以导航到服务详情页,或者显示详情模态框
  console.log('了解更多:', service.title);
};
</script>

<style scoped>
/* 特别针对 Business 页面的字体设置 - 解决 CTA 区域字体问题 */
.business-page router-link,
.business-page a[href],
.business-page .btn,
.business-page .btn-outline,
.business-page .border-white,
.business-page .text-white {
  font-family: 'Microsoft YaHei' !important;
  font-display: block !important;
}

/* 最高优先级:针对多层 class 组合选择器 */
.btn-outline.border-white.text-white,
.btn.btn-outline.border-white.text-white,
a.btn.btn-outline.border-white.text-white,
router-link.btn.btn-outline.border-white.text-white {
  font-family: 'Microsoft YaHei' !important;
  font-display: block !important;
}

/* Vue 组件数据属性选择器 */
[data-v-e345e995].btn,
[data-v-e345e995].btn-outline,
[data-v-e345e995] .btn,
[data-v-e345e995] .btn-outline {
  font-family: 'Microsoft YaHei' !important;
  font-display: block !important;
}

/* 强制中文字体设置 - 确保所有元素都显示中文字体 */
.business-page,
.business-page *,
.business-page h1,
.business-page h2,
.business-page h3,
.business-page h4,
.business-page h5,
.business-page h6,
.business-page p,
.business-page span,
.business-page a,
.business-page button,
.business-page .btn {
  font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'STHeiti', 'Helvetica Neue', Arial, sans-serif !important;
  font-display: swap !important;
}

/* 服务卡片样式 */
.service-card {
  transition: all 0.3s ease;
}

.service-card:hover {
  transform: translateY(-5px);
}

/* 动画效果 */
@keyframes fadeIn {
  from { 
    opacity: 0; 
    transform: translateY(10px); 
  }
  to { 
    opacity: 1; 
    transform: translateY(0); 
  }
}

.animate-fade-in {
  animation: fadeIn 0.3s ease-out;
}

/* 粘性导航样式 */
.sticky {
  backdrop-filter: blur(10px);
}

/* 分类按钮样式 */
.category-btn {
  transition: all 0.3s ease;
}

.category-btn:hover {
  transform: translateY(-1px);
}

/* 响应式适配 */
@media (max-width: 1024px) {
  .business-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .service-card {
    margin-bottom: 1.5rem;
  }
  
  .category-filters {
    flex-direction: column;
    gap: 0.5rem;
  }
  
  .category-btn {
    width: 100%;
    justify-content: center;
  }
}
</style>
posted @ 2025-09-10 13:25  左扬  阅读(32)  评论(0)    收藏  举报