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

Vue CLI 快速搭建项目的完整流程与最佳实践

2024-03-113.0k 阅读

一、Vue CLI 简介

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,它提供了:

  1. 交互式的项目脚手架:通过命令行工具,以交互式的方式生成项目模板,大大简化了项目初始化的流程。
  2. 零配置的渐进式前端工作流:默认情况下,不需要复杂的配置就可以开始开发,同时也支持按需配置,让开发更加灵活。
  3. 插件化架构:可以方便地安装、使用和管理各种插件,拓展项目的功能,比如添加路由、状态管理等功能。

二、环境准备

在开始使用 Vue CLI 搭建项目之前,需要确保以下环境已经安装并配置好。

1. 安装 Node.js

Vue CLI 是基于 Node.js 运行的,所以首先需要安装 Node.js。可以从 Node.js 官方网站 下载适合自己操作系统的安装包进行安装。安装完成后,在命令行中输入 node -vnpm -v,如果能正确输出版本号,则说明安装成功。

2. 安装 Vue CLI

在全局环境中安装 Vue CLI,打开命令行工具,输入以下命令:

npm install -g @vue/cli
# 或者使用 yarn 安装
yarn global add @vue/cli

安装完成后,可以通过 vue --version 命令来检查 Vue CLI 是否安装成功。

三、使用 Vue CLI 快速搭建项目

1. 创建新项目

打开命令行工具,切换到你想要创建项目的目录,然后执行以下命令:

vue create my - project

这里 my - project 是你项目的名称,可以根据实际情况进行修改。执行该命令后,Vue CLI 会提供一系列的选项让你选择:

  • 选择预设
    • Default (Vue 3 Preview):默认选项,使用 Vue 3.x 版本进行快速搭建,适合初学者快速上手。
    • Default (Vue 2):使用 Vue 2.x 版本搭建项目。
    • Manually select features:手动选择项目所需的特性,这是一个更灵活的选项,可以选择需要的功能,如 Babel、TypeScript、Router、Vuex 等。

假设我们选择 Manually select features,回车后会进入特性选择界面:

? Please pick a preset: Manually select features
? Check the features needed for your project:
 (*) Choose Vue version
 ( ) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
 ( ) Router
 ( ) Vuex
 ( ) CSS Pre - processors
 ( ) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing

通过空格可以选择或取消选择相应的特性。例如,如果我们要使用 Vue 3、Babel、Router 和 Vuex,可以依次选择对应的选项:

? Please pick a preset: Manually select features
? Check the features needed for your project:
 (*) Choose Vue version
 (*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
 (*) Router
 (*) Vuex
 ( ) CSS Pre - processors
 ( ) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing

选择完成后回车。

2. 选择 Vue 版本

如果之前选择了 Choose Vue version,接下来会让你选择具体的 Vue 版本:

? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
> 3.x (Preview)
  2.x

这里我们选择 3.x (Preview) 回车。

3. 配置 Router

选择使用 Router 后,会询问是否使用 history 模式:

? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)

如果选择 Y,则使用 history 模式,这种模式下 URL 更加美观,但是需要在服务器端进行一些配置,以确保在生产环境中刷新页面等操作正常。如果选择 n,则使用 hash 模式,URL 中会带有 # 符号。这里我们选择 Y

4. 配置 Vuex

选择使用 Vuex 后,没有额外的配置选项,直接进入下一步。

5. 选择 CSS 预处理器

如果选择了 CSS Pre - processors,会列出可供选择的 CSS 预处理器:

? Pick a CSS pre - processor (PostCSS, Autoprefixer and CSS Modules are supported by default):
> Sass/SCSS (with dart - sass)
  Sass/SCSS (with node - sass)
  Less
  Stylus

例如我们选择 Sass/SCSS (with dart - sass),Dart Sass 是官方推荐的 Sass 实现,性能较好。

6. 选择 Linter / Formatter

如果选择了 Linter / Formatter,会列出可供选择的代码检查和格式化工具:

? Pick a linter / formatter config:
> ESLint with error prevention only
  ESLint + Airbnb config
  ESLint + Standard config
  ESLint + Prettier

例如我们选择 ESLint + Prettier,Prettier 是一个强大的代码格式化工具,与 ESLint 结合可以保持代码风格的一致性。

7. 选择何时进行代码检查

选择 ESLint + Prettier 后,会询问何时进行代码检查:

? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
> (*) Lint on save
 ( ) Lint and fix on commit

这里我们选择 Lint on save,即在保存文件时进行代码检查和格式化。

8. 配置单元测试

如果选择了 Unit Testing,会询问使用的测试框架和测试运行器:

? Pick a unit testing solution:
> Jest
  Mocha + Chai

Jest 是 Facebook 开发的一个 JavaScript 测试框架,非常适合用于 Vue 项目的单元测试,所以我们选择 Jest

9. 配置 E2E 测试

如果选择了 E2E Testing,会询问使用的 E2E 测试框架和测试运行器:

? Pick an E2E testing solution:
> Cypress (Chrome only)
  Nightwatch (Selenium - based)

Cypress 是一个现代化的端到端测试框架,使用起来非常方便,所以我们选择 Cypress (Chrome only)

10. 选择项目配置文件

最后会询问将项目配置保存为一个预设,以便后续使用:

? Save this as a preset for future projects? (y/N)

如果选择 y,会让你输入预设的名称,方便以后使用 vue create -p <preset - name> <project - name> 来创建项目,这里我们选择 N

完成以上所有配置后,Vue CLI 就会开始创建项目,等待一段时间,项目创建完成后,在命令行中会看到以下提示:

  Successfully created project my - project.
  Get started with the following commands:

 $ cd my - project
 $ npm run serve

四、项目结构解析

进入创建好的项目目录 my - project,项目的基本结构如下:

my - project
├── babel.config.js
├── public
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   └── HelloWorld.vue
│   ├── App.vue
│   ├── main.js
│   ├── router
│   │   └── index.js
│   └── store
│       └── index.js
├── tests
│   ├── unit
│   │   ├── HelloWorld.spec.js
│   │   └── jest.config.js
│   └── e2e
│       ├── cypress.json
│       └── fixtures
│           └── example.json
│       ├── integration
│       │   └── example.spec.js
│       └── support
│           ├── commands.js
│           └── index.js
├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── package - lock.json
├── package.json
├── README.md
  • public:该目录下的文件会直接复制到打包后的输出目录,index.html 是项目的入口 HTML 文件,favicon.ico 是网站的图标文件。
  • src:项目的源代码目录,是我们开发的主要工作目录。
    • assets:存放静态资源,如图片、字体等。
    • components:存放 Vue 组件,HelloWorld.vue 是一个示例组件。
    • App.vue:项目的根组件,整个应用从这里开始渲染。
    • main.js:项目的入口 JavaScript 文件,在这里导入 Vue 实例、根组件和路由等。
    • router:存放路由相关的配置文件,index.js 定义了项目的路由规则。
    • store:存放 Vuex 的状态管理相关文件,index.js 定义了 Vuex 的 store。
  • tests:存放测试相关的文件。
    • unit:单元测试目录,HelloWorld.spec.jsHelloWorld.vue 组件的单元测试文件,jest.config.js 是 Jest 的配置文件。
    • e2e:端到端测试目录,cypress.json 是 Cypress 的配置文件,fixtures 目录存放测试数据,integration 目录存放端到端测试用例,support 目录存放一些支持文件。
  • babel.config.js:Babel 的配置文件,用于将 ES6+ 的代码转换为低版本浏览器支持的代码。
  • .browserslistrc:定义了项目支持的浏览器版本范围,用于 Babel 和 Autoprefixer 等工具。
  • .eslintrc.js:ESLint 的配置文件,用于定义代码检查的规则。
  • .gitignore:指定了哪些文件和目录不需要被 Git 版本控制系统跟踪。
  • package - lock.json:记录了项目安装的所有依赖包的具体版本信息,保证团队成员安装的依赖版本一致。
  • package.json:项目的配置文件,记录了项目的基本信息、依赖包和脚本命令等。
  • README.md:项目的说明文档,用于介绍项目的功能、使用方法等。

五、运行项目

进入项目目录后,执行 npm run serve 命令(如果使用 yarn,执行 yarn serve),项目会在本地启动一个开发服务器,默认端口是 8080。在浏览器中访问 http://localhost:8080,就可以看到项目的运行效果。

六、最佳实践

1. 组件化开发

在 Vue 项目中,组件化是非常重要的开发模式。每个组件应该只负责一个单一的功能,这样可以提高代码的复用性和可维护性。例如,我们可以将导航栏、侧边栏、按钮等都封装成独立的组件。

创建一个简单的按钮组件 Button.vue

<template>
  <button :class="['custom - button', { 'is - disabled': disabled }]" @click="handleClick">
    {{ label }}
  </button>
</template>

<script>
export default {
  name: 'Button',
  props: {
    label: {
      type: String,
      default: 'Click me'
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    handleClick() {
      if (!this.disabled) {
        console.log('Button clicked');
      }
    }
  }
};
</script>

<style scoped>
.custom - button {
  padding: 10px 20px;
  background - color: #007bff;
  color: white;
  border: none;
  border - radius: 5px;
  cursor: pointer;
}

.is - disabled {
  background - color: #ccc;
  cursor: not - allowed;
}
</style>

在其他组件中使用这个按钮组件:

<template>
  <div>
    <Button label="Submit" :disabled="isLoading" />
  </div>
</template>

<script>
import Button from './components/Button.vue';

export default {
  name: 'App',
  components: {
    Button
  },
  data() {
    return {
      isLoading: false
    };
  }
};
</script>

2. 路由管理

在使用 Vue Router 时,合理规划路由结构非常重要。根据项目的功能模块来划分路由,例如一个电商项目可以有首页、商品列表页、商品详情页、购物车页、个人中心页等路由。

router/index.js 中定义路由:

import { createRouter, createWebHistory } from 'vue - router';
import Home from '../views/Home.vue';
import ProductList from '../views/ProductList.vue';
import ProductDetail from '../views/ProductDetail.vue';
import Cart from '../views/Cart.vue';
import UserCenter from '../views/UserCenter.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/products',
    name: 'ProductList',
    component: ProductList
  },
  {
    path: '/products/:id',
    name: 'ProductDetail',
    component: ProductDetail
  },
  {
    path: '/cart',
    name: 'Cart',
    component: Cart
  },
  {
    path: '/user - center',
    name: 'UserCenter',
    component: UserCenter
  }
];

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

export default router;

App.vue 中使用路由:

<template>
  <div id="app">
    <router - link to="/">Home</router - link>
    <router - link to="/products">Product List</router - link>
    <router - link to="/cart">Cart</router - link>
    <router - link to="/user - center">User Center</router - link>
    <router - view />
  </div>
</template>

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

<style>
#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>

3. Vuex 状态管理

当项目的状态变得复杂时,使用 Vuex 进行状态管理可以让代码更加清晰。合理划分 Vuex 的模块,例如在一个电商项目中,可以将用户信息、购物车信息等分别放在不同的模块中。

store/index.js 中定义 Vuex store:

import { createStore } from 'vuex';
import user from './modules/user';
import cart from './modules/cart';

const store = createStore({
  modules: {
    user,
    cart
  }
});

export default store;

store/modules/user.js 中定义用户模块:

const state = {
  userInfo: null
};

const mutations = {
  SET_USER_INFO(state, userInfo) {
    state.userInfo = userInfo;
  }
};

const actions = {
  async fetchUserInfo({ commit }) {
    // 模拟异步请求获取用户信息
    const response = await fetch('/api/user - info');
    const data = await response.json();
    commit('SET_USER_INFO', data);
  }
};

export default {
  namespaced: true,
  state,
  mutations,
  actions
};

在组件中使用 Vuex:

<template>
  <div>
    <button @click="fetchUserInfo">Fetch User Info</button>
    <div v - if="userInfo">
      <p>Name: {{ userInfo.name }}</p>
      <p>Email: {{ userInfo.email }}</p>
    </div>
  </div>
</template>

<script>
import { mapActions, mapState } from 'vuex';

export default {
  computed: {
  ...mapState('user', ['userInfo'])
  },
  methods: {
  ...mapActions('user', ['fetchUserInfo'])
  }
};
</script>

4. 代码规范与格式化

使用 ESLint 和 Prettier 来保持代码风格的一致性。在 .eslintrc.js 中定义 ESLint 的规则:

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: ['plugin:vue/vue3 - recommended', '@vue/prettier'],
  parserOptions: {
    parser: '@babel/eslint - parser'
  },
  rules: {
    'no - console': process.env.NODE_ENV === 'production'? 'warn' : 'off',
    'no - debugger': process.env.NODE_ENV === 'production'? 'warn' : 'off'
  }
};

.prettierrc.js 中定义 Prettier 的配置:

module.exports = {
  semi: true,
  singleQuote: true,
  trailingComma: 'es5'
};

这样在保存文件时,ESLint 和 Prettier 会自动检查和格式化代码,确保团队成员的代码风格一致。

5. 优化项目性能

  • 代码分割:在路由和组件中使用动态导入(import())来实现代码分割,这样可以将项目的代码按需加载,提高首屏加载速度。例如在路由中:
const routes = [
  {
    path: '/products',
    name: 'ProductList',
    component: () => import('../views/ProductList.vue')
  },
  {
    path: '/products/:id',
    name: 'ProductDetail',
    component: () => import('../views/ProductDetail.vue')
  }
];
  • 图片优化:对项目中的图片进行压缩处理,可以使用工具如 ImageOptim 等。同时,可以根据不同的设备分辨率,使用 srcset 属性来加载合适的图片。
<img
  src="small - image.jpg"
  srcset="small - image.jpg 1x, medium - image.jpg 2x, large - image.jpg 3x"
  alt="My Image"
/>
  • 懒加载:对于列表中的图片或组件,可以使用懒加载技术,只有当它们进入视口时才加载。在 Vue 中,可以使用 vue - lazyload 插件来实现图片的懒加载。

七、部署项目

项目开发完成后,需要进行部署。首先执行 npm run build 命令(如果使用 yarn,执行 yarn build),该命令会将项目进行打包,生成一个 dist 目录,里面包含了可以部署到服务器上的静态文件。

1. 部署到静态服务器

如果项目是一个静态网站,可以将 dist 目录中的文件上传到静态服务器,如 Nginx、Apache 等。以 Nginx 为例,在 Nginx 的配置文件中添加如下配置:

server {
  listen 80;
  server_name your - domain.com;

  location / {
    root /path/to/dist;
    index index.html;
    try_files $uri $uri/ /index.html;
  }
}

这样就可以通过 http://your - domain.com 访问项目了。

2. 部署到后端服务器

如果项目需要与后端服务器进行交互,可以将 dist 目录中的文件放在后端服务器的静态资源目录下,然后在后端服务器中配置反向代理,将前端请求转发到相应的接口。例如在 Node.js 的 Express 服务器中:

const express = require('express');
const app = express();
const path = require('path');

app.use(express.static(path.join(__dirname, 'dist')));

// 配置反向代理
app.use('/api', (req, res) => {
  // 这里可以将请求转发到真正的后端 API 服务器
  // 例如使用 http - proxy - middleware 进行转发
  res.send('API response');
});

const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

通过以上完整流程和最佳实践,你可以使用 Vue CLI 快速搭建一个高质量、可维护的前端项目,并进行有效的开发和部署。