MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Vue CLI 如何实现多页面应用的开发与部署

2021-08-112.2k 阅读

一、Vue CLI 基础介绍

Vue CLI 是 Vue.js 官方的脚手架工具,它可以快速搭建 Vue.js 项目的基础结构。通过简单的命令行操作,开发者就能创建一个具备现代化构建工具链的 Vue 项目,极大地提高了开发效率。它预设了许多常用的配置,例如 Babel、ESLint 等,同时也支持高度自定义。

Vue CLI 提供了交互式的项目脚手架创建方式,开发者可以根据项目需求选择不同的功能特性。例如,是否需要安装路由、状态管理库(如 Vuex)等。在创建项目时,Vue CLI 会自动生成项目的目录结构,其中包含了 src 目录用于存放源码,public 目录用于存放静态资源,以及 package.json 文件来管理项目的依赖和脚本。

二、多页面应用概述

多页面应用(MPA,Multi - Page Application)是指一个应用由多个页面组成,每个页面都有独立的 HTML、CSS 和 JavaScript。在传统的 Web 开发中,MPA 是非常常见的开发模式。与单页面应用(SPA,Single - Page Application)相比,MPA 的每个页面在加载时都需要完整地请求服务器资源,包括 HTML、CSS 和 JavaScript 文件。这种方式的优点在于每个页面相对独立,维护起来较为方便,搜索引擎优化(SEO)效果较好;缺点则是页面切换时会有明显的刷新感,并且首次加载可能较慢,因为每个页面都要重复加载一些公共资源。

在现代前端开发中,尽管 SPA 应用越来越流行,但在某些场景下,MPA 仍然具有独特的优势。例如,对于一些大型的企业级应用,其中部分页面需要良好的 SEO 支持,或者不同的业务模块之间相对独立,采用 MPA 可以更好地进行管理和开发。

三、Vue CLI 实现多页面应用开发

  1. 项目初始化 首先,确保你已经全局安装了 Vue CLI。如果没有安装,可以使用以下命令进行安装:
npm install -g @vue/cli

安装完成后,使用 Vue CLI 创建一个基础项目:

vue create multi - page - app

在创建过程中,你可以根据项目需求选择相应的特性,如 Babel、ESLint 等。

  1. 配置多页面结构 创建完基础项目后,需要对项目进行多页面配置。在项目根目录下创建一个 vue.config.js 文件,如果项目已经有该文件,则直接进行编辑。在 vue.config.js 文件中添加如下配置:
const path = require('path');

function resolve(dir) {
  return path.join(__dirname, dir);
}

module.exports = {
  pages: {
    index: {
      // 入口文件
      entry: resolve('src/pages/index/main.js'),
      // 模板文件
      template: resolve('public/index.html'),
      // 输出文件名
      filename: 'index.html',
      // 页面标题
      title: 'Index Page',
      // 提取的特定 chunk 名称
      chunks: ['chunk - vendor', 'chunk - manifest', 'index']
    },
    about: {
      entry: resolve('src/pages/about/main.js'),
      template: resolve('public/about.html'),
      filename: 'about.html',
      title: 'About Page',
      chunks: ['chunk - vendor', 'chunk - manifest', 'about']
    }
  },
  chainWebpack: (config) => {
    config.module
     .rule('html')
     .exclude.add(resolve('src/pages'))
     .end();
    config.module
     .rule('pages - html')
     .test(/\.html$/)
     .include.add(resolve('src/pages'))
     .end()
     .use('html - loader')
     .loader('html - loader')
     .options({
        attrs: false
      });
  }
};

上述配置中,pages 对象定义了多个页面。每个页面对象包含了入口文件 entry、模板文件 template、输出文件名 filename、页面标题 title 以及要包含的 chunkschainWebpack 配置部分主要是为了让 Webpack 正确处理页面中的 HTML 文件。

  1. 目录结构调整 为了更好地管理多页面应用,需要对项目的目录结构进行调整。在 src 目录下创建一个 pages 目录,然后在 pages 目录下分别创建 indexabout 目录(对应上述配置中的页面名称)。在每个页面目录下,再创建 main.js 文件作为入口文件,以及相关的 Vue 组件和样式文件。例如,src/pages/index/main.js 内容如下:
import Vue from 'vue';
import App from './App.vue';
import router from './router';

Vue.config.productionTip = false;

new Vue({
  router,
  render: (h) => h(App)
}).$mount('#app');

src/pages/index/App.vue 可以是一个普通的 Vue 组件:

<template>
  <div id="app">
    <h1>Index Page</h1>
    <router - view></router - view>
  </div>
</template>

<script>
export default {
  name: 'App'
};
</script>

<style scoped>
#app {
  font - family: Avenir, Helvetica, Arial, sans - serif;
  -webkit - font - smoothing: antialiased;
  -moz - osx - font - smoothing: grayscale;
  text - align: center;
  color: #2c3e50;
  margin - top: 60px;
}
</style>

同时,在 public 目录下创建 index.htmlabout.html 模板文件。public/index.html 示例如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf - 8">
  <meta http - equiv="X - UA - Compatible" content="IE=edge">
  <meta name="viewport" content="width=device - width,initial - scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <title><%= htmlWebpackPlugin.options.title %></title>
</head>

<body>
  <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
      Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
  <!-- built files will be auto injected -->
</body>

</html>
  1. 路由配置 对于多页面应用,每个页面可以有自己独立的路由。在每个页面的 main.js 文件中引入并配置路由。例如,src/pages/index/router.js
import Vue from 'vue';
import Router from 'vue - router';
import Home from './components/Home.vue';

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    }
  ]
});

src/pages/index/components/Home.vue

<template>
  <div>
    <h2>Home</h2>
  </div>
</template>

<script>
export default {
  name: 'Home'
};
</script>

<style scoped>
</style>

四、Vue CLI 多页面应用的样式处理

  1. 全局样式 在多页面应用中,可以在 src/assets 目录下创建一个 styles 目录,然后在其中创建全局样式文件,如 global.css。在 vue.config.js 中配置全局样式的引入:
module.exports = {
  // 其他配置...
  css: {
    loaderOptions: {
      css: {
        import: [
          {
            content: '@/assets/styles/global.css'
          }
        ]
      }
    }
  }
};

这样,所有页面都会应用该全局样式。

  1. 页面级样式 每个页面也可以有自己独立的样式文件。例如,在 src/pages/index 目录下创建 index.css 文件,在 App.vue 中引入:
<template>
  <div id="app">
    <h1>Index Page</h1>
    <router - view></router - view>
  </div>
</template>

<script>
import './index.css';
export default {
  name: 'App'
};
</script>

<style scoped>
#app {
  font - family: Avenir, Helvetica, Arial, sans - serif;
  -webkit - font - smoothing: antialiased;
  -moz - osx - font - smoothing: grayscale;
  text - align: center;
  color: #2c3e50;
  margin - top: 60px;
}
</style>

五、Vue CLI 多页面应用的资源管理

  1. 静态资源 静态资源如图片、字体等可以放在 public 目录下。在 HTML 模板中,可以使用相对路径引用这些资源。例如,在 public/index.html 中:
<img src="<%= BASE_URL %>logo.png" alt="logo">

在 Vue 组件中,也可以使用 requireimport 来引入静态资源。例如:

<template>
  <div>
    <img :src="logo" alt="logo">
  </div>
</template>

<script>
export default {
  data() {
    return {
      logo: require('@/assets/images/logo.png')
    };
  }
};
</script>

<style scoped>
</style>
  1. 组件复用 多页面应用中,可能会有一些组件在多个页面中复用。可以在 src/components 目录下创建这些复用组件,然后在各个页面的组件中按需引入。例如,创建一个 Button.vue 组件:
<template>
  <button>{{ text }}</button>
</template>

<script>
export default {
  data() {
    return {
      text: 'Click Me'
    };
  }
};
</script>

<style scoped>
button {
  padding: 10px 20px;
  background - color: #007BFF;
  color: white;
  border: none;
  border - radius: 5px;
}
</style>

src/pages/index/App.vue 中引入:

<template>
  <div id="app">
    <h1>Index Page</h1>
    <Button />
    <router - view></router - view>
  </div>
</template>

<script>
import Button from '@/components/Button.vue';
export default {
  components: {
    Button
  },
  name: 'App'
};
</script>

<style scoped>
#app {
  font - family: Avenir, Helvetica, Arial, sans - serif;
  -webkit - font - smoothing: antialiased;
  -moz - osx - font - smoothing: grayscale;
  text - align: center;
  color: #2c3e50;
  margin - top: 60px;
}
</style>

六、Vue CLI 多页面应用的构建与优化

  1. 构建命令 在项目根目录下,使用以下命令进行构建:
npm run build

构建完成后,会在 dist 目录下生成各个页面的 HTML、CSS 和 JavaScript 文件。

  1. 代码拆分与懒加载 为了优化加载性能,可以进行代码拆分和懒加载。在路由配置中,可以使用 import() 语法实现组件的懒加载。例如,src/pages/index/router.js
import Vue from 'vue';
import Router from 'vue - router';

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: () => import('./components/Home.vue')
    }
  ]
});

这样,当访问到 / 路径时,才会加载 Home.vue 组件对应的代码,从而提高首屏加载速度。

  1. 压缩与优化 Vue CLI 在构建过程中已经对代码进行了压缩。但是,还可以进一步优化,例如使用 image - webpack - loader 对图片进行压缩,配置如下: 首先安装 image - webpack - loader
npm install image - webpack - loader - - save - dev

然后在 vue.config.js 中配置:

module.exports = {
  chainWebpack: (config) => {
    config.module
     .rule('images')
     .use('image - webpack - loader')
     .loader('image - webpack - loader')
     .options({
        mozjpeg: {
          progressive: true,
          quality: 65
        },
        // optipng.enabled: false will disable optipng
        optipng: {
          enabled: false
        },
        pngquant: {
          quality: [0.65, 0.90],
          speed: 4
        },
        gifsicle: {
          interlaced: false
        },
        // the webp option will enable WEBP
        webp: {
          quality: 75
        }
      })
     .end();
  }
};

七、Vue CLI 多页面应用的部署

  1. 部署到静态服务器 构建完成后,dist 目录下的内容是可以直接部署到静态服务器上的。例如,可以使用 serve 工具进行本地预览部署: 首先安装 serve
npm install -g serve

然后在项目根目录下执行:

serve dist

这样就可以在本地通过浏览器访问部署的多页面应用了。如果要部署到正式服务器,可以将 dist 目录下的所有文件上传到服务器的相应目录,如 Nginx 或 Apache 的静态资源目录。

  1. 部署到服务器端渲染环境 如果项目需要服务器端渲染(SSR),可以使用 Nuxt.js 等工具。不过,对于简单的多页面应用,一般静态部署即可满足需求。如果要在服务器端渲染环境下部署,需要根据具体的 SSR 框架进行相应的配置和部署操作。例如,对于 Nuxt.js 应用,需要在服务器上安装 Node.js 环境,并运行相应的启动脚本。

八、常见问题及解决方法

  1. HTML 模板中变量无法替换 问题描述:在 HTML 模板中使用 <%= BASE_URL %> 等变量时,构建后变量没有被正确替换。 解决方法:确保 html - webpack - plugin 版本正确,并且在 vue.config.js 中对 HTML 处理的配置正确。检查 chainWebpack 中对 HTML 文件的规则配置是否与项目结构匹配。

  2. 页面样式冲突 问题描述:不同页面的样式相互影响,出现样式冲突。 解决方法:尽量使用局部作用域的样式,例如在 Vue 组件中使用 scoped 属性。对于全局样式,要谨慎命名,避免命名冲突。也可以使用 CSS Modules 来更细粒度地控制样式作用域。

  3. 资源路径错误 问题描述:在页面中引用静态资源时,出现 404 错误。 解决方法:检查资源路径是否正确,特别是在构建后。对于相对路径,要根据 HTML 文件的位置进行调整。在 Vue 组件中使用 requireimport 引入资源时,确保路径是相对于组件的正确路径。同时,在 vue.config.js 中对 publicPath 的配置要符合项目的部署环境。