Skip to content

第12章:企业级进阶实战(综合应用)

实战 3:企业官网

1. 项目架构设计(布局拆分、组件规划)

项目初始化

bash
# 使用 npx nuxi init 命令创建项目
npx nuxi init enterprise-website

# 进入项目目录
cd enterprise-website

# 安装依赖
npm install

# 启动开发服务器
npm run dev

目录结构设计

enterprise-website/
├── assets/            # 静态资源
│   ├── css/           # 样式文件
│   ├── images/        # 图片资源
│   └── fonts/         # 字体文件
├── components/        # 组件
│   ├── ui/            # 通用 UI 组件
│   ├── layout/        # 布局组件
│   └── sections/      # 页面区块组件
├── composables/       # 组合式函数
├── layouts/           # 布局
├── pages/             # 页面
├── public/            # 公共静态资源
├── server/            # 服务器端代码
├── utils/             # 工具函数
├── nuxt.config.ts     # 配置文件
└── package.json       # 项目配置

布局拆分

  • 默认布局:包含导航栏和页脚
  • 首页布局:包含英雄区、产品展示、客户案例等区块
  • 产品页布局:包含产品列表和详情
  • 关于页布局:包含公司介绍、团队成员等
  • 联系页布局:包含联系表单和地图

组件规划

  • UI 组件:按钮、卡片、表单、导航栏、页脚等
  • 布局组件:容器、网格、分隔符等
  • 区块组件:英雄区、产品展示、客户案例、团队介绍、联系表单等

2. 核心功能实现(导航栏、轮播图、产品展示、新闻动态)

创建导航栏组件

vue
<!-- components/layout/Navbar.vue -->
<template>
  <nav class="navbar" :class="{ 'scrolled': scrolled }">
    <div class="container">
      <div class="navbar-brand">
        <NuxtLink to="/" class="logo">
          <img src="/logo.png" alt="Company Logo" />
        </NuxtLink>
      </div>
      <div class="navbar-menu">
        <ul class="navbar-links">
          <li><NuxtLink to="/" class="navbar-link">首页</NuxtLink></li>
          <li><NuxtLink to="/products" class="navbar-link">产品</NuxtLink></li>
          <li><NuxtLink to="/about" class="navbar-link">关于我们</NuxtLink></li>
          <li><NuxtLink to="/news" class="navbar-link">新闻动态</NuxtLink></li>
          <li><NuxtLink to="/contact" class="navbar-link">联系我们</NuxtLink></li>
        </ul>
        <button class="navbar-button">
          免费咨询
        </button>
      </div>
      <button class="navbar-toggle" @click="toggleMenu">
        <span></span>
        <span></span>
        <span></span>
      </button>
    </div>
    <div class="mobile-menu" v-if="menuOpen">
      <ul class="mobile-links">
        <li><NuxtLink to="/" class="mobile-link" @click="menuOpen = false">首页</NuxtLink></li>
        <li><NuxtLink to="/products" class="mobile-link" @click="menuOpen = false">产品</NuxtLink></li>
        <li><NuxtLink to="/about" class="mobile-link" @click="menuOpen = false">关于我们</NuxtLink></li>
        <li><NuxtLink to="/news" class="mobile-link" @click="menuOpen = false">新闻动态</NuxtLink></li>
        <li><NuxtLink to="/contact" class="mobile-link" @click="menuOpen = false">联系我们</NuxtLink></li>
        <li><button class="mobile-button">免费咨询</button></li>
      </ul>
    </div>
  </nav>
</template>

<script setup>
const scrolled = ref(false)
const menuOpen = ref(false)

function toggleMenu() {
  menuOpen.value = !menuOpen.value
}

function handleScroll() {
  scrolled.value = window.scrollY > 50
}

onMounted(() => {
  window.addEventListener('scroll', handleScroll)
})

onUnmounted(() => {
  window.removeEventListener('scroll', handleScroll)
})
</script>

<style scoped>
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 1000;
  transition: all 0.3s ease;
  padding: 1rem 0;
}

.navbar.scrolled {
  background-color: white;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  padding: 0.5rem 0;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.navbar-brand .logo img {
  height: 40px;
}

.navbar-menu {
  display: flex;
  align-items: center;
  gap: 2rem;
}

.navbar-links {
  display: flex;
  gap: 2rem;
  list-style: none;
}

.navbar-link {
  color: #333;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.3s ease;
}

.navbar-link:hover {
  color: #007bff;
}

.navbar-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.navbar-button:hover {
  background-color: #0056b3;
}

.navbar-toggle {
  display: none;
  flex-direction: column;
  gap: 0.3rem;
  background: none;
  border: none;
  cursor: pointer;
}

.navbar-toggle span {
  width: 24px;
  height: 2px;
  background-color: #333;
  transition: all 0.3s ease;
}

.mobile-menu {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  background-color: white;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
  padding: 1rem 0;
  animation: slideDown 0.3s ease;
}

.mobile-links {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 0 1rem;
}

.mobile-link {
  color: #333;
  text-decoration: none;
  font-weight: 500;
  padding: 0.5rem 0;
  transition: color 0.3s ease;
}

.mobile-link:hover {
  color: #007bff;
}

.mobile-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.3s ease;
  width: 100%;
  margin-top: 0.5rem;
}

.mobile-button:hover {
  background-color: #0056b3;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (max-width: 768px) {
  .navbar-menu {
    display: none;
  }
  
  .navbar-toggle {
    display: flex;
  }
}
</style>

创建轮播图组件

vue
<!-- components/sections/HeroSlider.vue -->
<template>
  <div class="hero-slider">
    <div class="slider-container" ref="sliderContainer">
      <div 
        v-for="(slide, index) in slides" 
        :key="index"
        class="slide"
        :class="{ active: currentSlide === index }"
        :style="{ transform: `translateX(-${currentSlide * 100}%)` }"
      >
        <div class="slide-content">
          <h1>{{ slide.title }}</h1>
          <p>{{ slide.description }}</p>
          <button class="cta-button">{{ slide.buttonText }}</button>
        </div>
        <div class="slide-image">
          <img :src="slide.image" :alt="slide.title" />
        </div>
      </div>
    </div>
    <div class="slider-controls">
      <button 
        class="control-button prev" 
        @click="prevSlide"
      >
        <span>&lt;</span>
      </button>
      <button 
        class="control-button next" 
        @click="nextSlide"
      >
        <span>&gt;</span>
      </button>
    </div>
    <div class="slider-indicators">
      <button 
        v-for="(slide, index) in slides" 
        :key="index"
        class="indicator" 
        :class="{ active: currentSlide === index }"
        @click="currentSlide = index"
      ></button>
    </div>
  </div>
</template>

<script setup>
const sliderContainer = ref(null)
const currentSlide = ref(0)
const slides = ref([
  {
    title: '创新科技解决方案',
    description: '为企业提供全方位的技术支持和创新解决方案,助力企业数字化转型',
    buttonText: '了解更多',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=modern%20technology%20solution%20business%20hero%20image&image_size=landscape_16_9'
  },
  {
    title: '专业服务团队',
    description: '拥有一支经验丰富的专业团队,为客户提供高质量的服务和支持',
    buttonText: '联系我们',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=professional%20team%20working%20together%20business%20setting&image_size=landscape_16_9'
  },
  {
    title: '客户成功案例',
    description: '已为众多企业提供解决方案,帮助客户实现业务增长和数字化转型',
    buttonText: '查看案例',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=business%20success%20case%20data%20visualization&image_size=landscape_16_9'
  }
])

function nextSlide() {
  currentSlide.value = (currentSlide.value + 1) % slides.value.length
}

function prevSlide() {
  currentSlide.value = (currentSlide.value - 1 + slides.value.length) % slides.value.length
}

// 自动轮播
let interval = null

onMounted(() => {
  interval = setInterval(nextSlide, 5000)
})

onUnmounted(() => {
  if (interval) {
    clearInterval(interval)
  }
})
</script>

<style scoped>
.hero-slider {
  position: relative;
  height: 100vh;
  overflow: hidden;
}

.slider-container {
  display: flex;
  height: 100%;
  transition: transform 0.5s ease;
}

.slide {
  flex: 0 0 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2rem;
  background-color: #f8f9fa;
}

.slide-content {
  flex: 0 0 50%;
  padding: 2rem;
}

.slide-content h1 {
  font-size: 3rem;
  font-weight: 700;
  margin-bottom: 1rem;
  color: #333;
}

.slide-content p {
  font-size: 1.2rem;
  margin-bottom: 2rem;
  color: #666;
}

.cta-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 1rem 2rem;
  border-radius: 4px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.cta-button:hover {
  background-color: #0056b3;
}

.slide-image {
  flex: 0 0 50%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.slide-image img {
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
}

.slider-controls {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  transform: translateY(-50%);
  padding: 0 2rem;
}

.control-button {
  background-color: rgba(255, 255, 255, 0.8);
  border: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
}

.control-button:hover {
  background-color: white;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

.slider-indicators {
  position: absolute;
  bottom: 2rem;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 0.5rem;
}

.indicator {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.5);
  border: none;
  cursor: pointer;
  transition: all 0.3s ease;
}

.indicator.active {
  background-color: white;
  width: 30px;
  border-radius: 5px;
}

@media (max-width: 768px) {
  .slide {
    flex-direction: column;
    text-align: center;
    padding: 2rem 1rem;
  }
  
  .slide-content {
    flex: 0 0 100%;
    padding: 1rem;
  }
  
  .slide-content h1 {
    font-size: 2rem;
  }
  
  .slide-image {
    flex: 0 0 100%;
    height: 50%;
  }
}
</style>

创建产品展示组件

vue
<!-- components/sections/ProductShowcase.vue -->
<template>
  <section class="product-showcase">
    <div class="container">
      <div class="section-header">
        <h2>Our Products</h2>
        <p>Discover our range of innovative solutions designed to meet your business needs</p>
      </div>
      <div class="products-grid">
        <div v-for="product in products" :key="product.id" class="product-card">
          <div class="product-image">
            <img :src="product.image" :alt="product.name" />
          </div>
          <div class="product-content">
            <h3>{{ product.name }}</h3>
            <p>{{ product.description }}</p>
            <button class="product-button">Learn More</button>
          </div>
        </div>
      </div>
    </div>
  </section>
</template>

<script setup>
const products = ref([
  {
    id: 1,
    name: 'Cloud Solutions',
    description: 'Scalable cloud infrastructure and services for businesses of all sizes',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=cloud%20computing%20technology%20abstract%20concept&image_size=square'
  },
  {
    id: 2,
    name: 'Data Analytics',
    description: 'Advanced data analytics tools to gain insights and make informed decisions',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=data%20analytics%20dashboard%20visualization&image_size=square'
  },
  {
    id: 3,
    name: 'Cybersecurity',
    description: 'Comprehensive security solutions to protect your business from threats',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=cybersecurity%20digital%20protection%20shield&image_size=square'
  },
  {
    id: 4,
    name: 'AI Services',
    description: 'Artificial intelligence solutions to automate and optimize business processes',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=artificial%20intelligence%20technology%20concept&image_size=square'
  }
])
</script>

<style scoped>
.product-showcase {
  padding: 4rem 0;
  background-color: #f8f9fa;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem;
}

.section-header {
  text-align: center;
  margin-bottom: 3rem;
}

.section-header h2 {
  font-size: 2.5rem;
  font-weight: 700;
  margin-bottom: 1rem;
  color: #333;
}

.section-header p {
  font-size: 1.2rem;
  color: #666;
  max-width: 600px;
  margin: 0 auto;
}

.products-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 2rem;
}

.product-card {
  background-color: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.product-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15);
}

.product-image {
  height: 200px;
  overflow: hidden;
}

.product-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.product-card:hover .product-image img {
  transform: scale(1.05);
}

.product-content {
  padding: 1.5rem;
}

.product-content h3 {
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 1rem;
  color: #333;
}

.product-content p {
  color: #666;
  margin-bottom: 1.5rem;
  line-height: 1.6;
}

.product-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.product-button:hover {
  background-color: #0056b3;
}

@media (max-width: 768px) {
  .section-header h2 {
    font-size: 2rem;
  }
  
  .products-grid {
    grid-template-columns: 1fr;
  }
}
</style>

创建新闻动态组件

vue
<!-- components/sections/NewsSection.vue -->
<template>
  <section class="news-section">
    <div class="container">
      <div class="section-header">
        <h2>Latest News</h2>
        <p>Stay updated with our latest news and events</p>
      </div>
      <div class="news-grid">
        <div v-for="news in newsItems" :key="news.id" class="news-card">
          <div class="news-image">
            <img :src="news.image" :alt="news.title" />
          </div>
          <div class="news-content">
            <span class="news-date">{{ news.date }}</span>
            <h3>{{ news.title }}</h3>
            <p>{{ news.excerpt }}</p>
            <NuxtLink to="/news" class="news-link">Read More</NuxtLink>
          </div>
        </div>
      </div>
      <div class="section-footer">
        <NuxtLink to="/news" class="view-all-button">View All News</NuxtLink>
      </div>
    </div>
  </section>
</template>

<script setup>
const newsItems = ref([
  {
    id: 1,
    title: 'Company Wins Innovation Award',
    excerpt: 'Our company has been recognized for its innovative approach to technology solutions',
    date: '2024-01-15',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=business%20award%20ceremony%20celebration&image_size=landscape_4_3'
  },
  {
    id: 2,
    title: 'New Product Launch',
    excerpt: 'We are excited to announce the launch of our new cloud-based solution',
    date: '2024-01-10',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=product%20launch%20event%20technology&image_size=landscape_4_3'
  },
  {
    id: 3,
    title: 'Partnership with Global Tech Giant',
    excerpt: 'We have formed a strategic partnership with a leading global technology company',
    date: '2024-01-05',
    image: 'https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=business%20partnership%20agreement%20handshake&image_size=landscape_4_3'
  }
])
</script>

<style scoped>
.news-section {
  padding: 4rem 0;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem;
}

.section-header {
  text-align: center;
  margin-bottom: 3rem;
}

.section-header h2 {
  font-size: 2.5rem;
  font-weight: 700;
  margin-bottom: 1rem;
  color: #333;
}

.section-header p {
  font-size: 1.2rem;
  color: #666;
  max-width: 600px;
  margin: 0 auto;
}

.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  margin-bottom: 2rem;
}

.news-card {
  background-color: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.news-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15);
}

.news-image {
  height: 200px;
  overflow: hidden;
}

.news-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.news-card:hover .news-image img {
  transform: scale(1.05);
}

.news-content {
  padding: 1.5rem;
}

.news-date {
  display: block;
  font-size: 0.9rem;
  color: #999;
  margin-bottom: 1rem;
}

.news-content h3 {
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 1rem;
  color: #333;
}

.news-content p {
  color: #666;
  margin-bottom: 1.5rem;
  line-height: 1.6;
}

.news-link {
  color: #007bff;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.3s ease;
}

.news-link:hover {
  color: #0056b3;
  text-decoration: underline;
}

.section-footer {
  text-align: center;
  margin-top: 2rem;
}

.view-all-button {
  display: inline-block;
  background-color: #007bff;
  color: white;
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.3s ease;
}

.view-all-button:hover {
  background-color: #0056b3;
}

@media (max-width: 768px) {
  .section-header h2 {
    font-size: 2rem;
  }
  
  .news-grid {
    grid-template-columns: 1fr;
  }
}
</style>

3. SEO 优化(元标签配置、SSR 渲染、结构化数据)

使用 useHead 配置元标签

vue
<!-- pages/index.vue -->
<template>
  <div>
    <HeroSlider />
    <ProductShowcase />
    <NewsSection />
  </div>
</template>

<script setup>
useHead({
  title: '企业官网 - 创新科技解决方案',
  meta: [
    { name: 'description', content: '为企业提供全方位的技术支持和创新解决方案,助力企业数字化转型' },
    { name: 'keywords', content: '科技,解决方案,数字化转型,企业服务' },
    { name: 'robots', content: 'index, follow' },
    { property: 'og:title', content: '企业官网 - 创新科技解决方案' },
    { property: 'og:description', content: '为企业提供全方位的技术支持和创新解决方案,助力企业数字化转型' },
    { property: 'og:type', content: 'website' },
    { property: 'og:url', content: 'https://example.com' },
    { property: 'og:image', content: 'https://example.com/og-image.jpg' }
  ],
  link: [
    { rel: 'canonical', href: 'https://example.com' }
  ]
})
</script>

添加结构化数据

vue
<!-- components/layout/StructuredData.vue -->
<template>
  <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Organization",
      "name": "Company Name",
      "url": "https://example.com",
      "logo": "https://example.com/logo.png",
      "contactPoint": {
        "@type": "ContactPoint",
        "telephone": "+86-123-4567-8910",
        "contactType": "customer service"
      },
      "sameAs": [
        "https://www.facebook.com/company",
        "https://twitter.com/company",
        "https://www.linkedin.com/company/company"
      ]
    }
  </script>
</template>

<script setup>
// 内容
</script>

在布局中使用

vue
<!-- layouts/default.vue -->
<template>
  <div>
    <Navbar />
    <StructuredData />
    <main>
      <slot />
    </main>
    <Footer />
  </div>
</template>

<script setup>
// 内容
</script>

4. 性能优化(图片懒加载、组件懒加载、资源压缩)

图片懒加载

vue
<template>
  <img 
    v-lazy="imageUrl" 
    :alt="altText"
    class="lazy-image"
  />
</template>

<script setup>
defineProps({
  imageUrl: {
    type: String,
    required: true
  },
  altText: {
    type: String,
    default: ''
  }
})
</script>

<style scoped>
.lazy-image {
  width: 100%;
  height: auto;
  transition: opacity 0.3s ease;
}

.lazy-image:not([src]) {
  opacity: 0;
}
</style>

组件懒加载

vue
<template>
  <div>
    <h2>Our Team</h2>
    <LazyTeamMembers />
  </div>
</template>

<script setup>
const LazyTeamMembers = defineAsyncComponent(() => import('~/components/sections/TeamMembers.vue'))
</script>

资源压缩

nuxt.config.ts 中配置

typescript
export default defineNuxtConfig({
  build: {
    terser: {
      compress: {
        drop_console: process.env.NODE_ENV === 'production'
      }
    }
  },
  vite: {
    build: {
      minify: 'terser',
      cssCodeSplit: true,
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['vue'],
            'nuxt-core': ['@nuxt/kit', '@nuxt/schema'],
            'nuxt-utils': ['@nuxt/utils']
          }
        }
      }
    }
  }
})

5. 部署上线(服务器部署、静态站点部署、CDN 配置)

服务器部署

  1. 构建项目

    bash
    npm run build
  2. 部署到服务器

    • dist 目录上传到服务器
    • 使用 PM2 管理进程:
      bash
      npm install -g pm2
      pm2 start npm --name "enterprise-website" -- run start
  3. Nginx 配置

    nginx
    server {
      listen 80;
      server_name example.com;
      
      location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
      }
    }

静态站点部署

  1. 生成静态站点

    bash
    npm run generate
  2. 部署到 GitHub Pages

    • dist 目录推送到 GitHub 仓库的 gh-pages 分支
    • 在 GitHub 仓库设置中启用 GitHub Pages
  3. 部署到 Netlify

    • 连接 GitHub 仓库
    • 配置构建命令:npm run generate
    • 配置发布目录:dist

CDN 配置

  1. 使用 Cloudflare CDN

    • 将域名的 DNS 解析指向 Cloudflare
    • 在 Cloudflare 控制面板中启用 CDN
  2. 配置缓存策略

    nginx
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
      expires 30d;
      add_header Cache-Control "public, max-age=2592000";
    }

小结

本章介绍了企业官网的实战案例,包括项目架构设计、核心功能实现、SEO 优化、性能优化和部署上线等内容。通过这个实战项目,你应该已经掌握了如何使用 Nuxt.js 构建企业级应用,包括:

  1. 项目架构设计:合理的目录结构和组件规划
  2. 核心功能实现:导航栏、轮播图、产品展示、新闻动态等
  3. SEO 优化:元标签配置、SSR 渲染、结构化数据
  4. 性能优化:图片懒加载、组件懒加载、资源压缩
  5. 部署上线:服务器部署、静态站点部署、CDN 配置

这些内容涵盖了企业级应用开发的各个方面,通过实践,你应该能够更深入地理解和使用 Nuxt.js 构建各种类型的企业应用。

在接下来的章节中,我们将学习 Nuxt.js 的进阶配置与优化、部署与上线、常见问题与面试题等内容,帮助你进一步提升 Nuxt.js 开发技能。

© 2026 编程马·菜鸟教程 版权所有