Vue从零开始,手把手教学( 附送250套精选项目源码)

vue简介

一、简介

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架(部分使用,不是全家桶)。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。vue是一款简单的mvvm(model-view-viewmodel)框架

它的中心思想就是数据驱动,不像jQuery是结构驱动,

  • 结构驱动:先获取HTML的结构,然后再修改数据更新结构
  • 数据驱动:简单的理解就是直接将数据同步到结构上,视图管理抽象为数据管理,而不是管理dom结构

Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能模拟的 ECMAScript 5 特性。Vue.js 支持所有兼容 ECMAScript 5 的浏览器。

二、MVVM模式

1、什么是MVVM

Model-View-ViewModel的简写。即模型-视图-视图模型

  • M 指的是后端传递的数据
  • V 指的是所看到的页面。
  • VM MVVM模式的核心,它是连接view和model的桥梁

它有两个作用:

  • 将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。
  • 将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。

如果这两个方向都实现的,我们称之为数据的双向绑定

2、 为什么会有MVVM框架?

HTML5 最大的亮点是它为移动设备提供了一些非常有用的功能,使得 HTML5 具备了开发App的能力, HTML5开发App 最大的好处就是跨平台、快速迭代和上线,节省人力成本和提高效率,因此很多企业开始对传统的App进行改造,逐渐用H5代替原生App开发,到目前为止,市场上大多数App 或多或少嵌入都了H5 的页面。

既然要用H5 来构建 App, 那View 层所做的事,就不仅仅是简单的数据展示了,它不仅要管理复杂的数据状态,还要处理移动设备上各种操作行为等等。因此,前端就需要工程化,也需要一个类似于Web端MVC 的框架来管理这些复杂的逻辑,使开发更加高效。

在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。 ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

3、结构示意图

三、什么是渐进式

  1. 如果你已经有一个现成的服务端应用,你可以将vue 作为该应用的一部分嵌入其中,带来更加丰富的交互体验;

  2. 如果你希望将更多业务逻辑放到前端来实现,那么Vue的核心库及其生态系统也可以满足你的各式需求(core+vuex+vue-route)。和其它前端框架一样,Vue允许你将一个网页分割成可复用的组件,每个组件都包含属于自己的HTML、CSS、JAVASCRIPT以用来渲染网页中相应的地方。

  3. 如果我们构建一个大型的应用,在这一点上,我们可能需要将东西分割成为各自的组件和文件,vue有一个命令行工具,使快速初始化一个真实的工程变得非常简单(vue init webpack my-project)。我们可以使用VUE的单文件组件,它包含了各自的HTML、JAVASCRIPT以及带作用域的CSS或SCSS。以上这三个例子,是一步步递进的,也就是说对VUE的使用可大可小,它都会有相应的方式来整合到你的项目中。所以说它是一个渐进式的框架。

正式开发:

第一步 Vue2 使用 Vue 脚手架 Vue CLI 搭建一个 Vue.js 前端项目框架

Vue CLI 是一个用于快速搭建 Vue.js 项目的脚手架工具。它集成了开发所需的各种工具和常见配置,让你可以专注于编写代码而不用为构建过程烦恼。本教程将介绍如何使用 Vue CLI 来搭建一个基本的 Vue.js 项目。

步骤 1:安装 Node.js

在开始之前,请确保你的计算机已经安装了 Node.js。你可以从 https://nodejs.org/ 下载并安装 Node.js 的最新版本。
当前版本 v16.14.2
可通过 node -v 查看对应版本

步骤 2:安装 Vue CLI

在命令行中运行以下命令来安装 Vue CLI:

npm install -g @vue/cli

这将全局安装 Vue CLI,以便你可以在任何目录下使用 vue 命令。

当前版本 8.5.0
可通过 npm @vue/cli -v 查看对应版本

步骤 3:创建新的 Vue 项目

在命令行中,进入你想要创建项目的目录,然后运行以下命令来创建一个新的 Vue 项目:

vue create my-vue2

这将创建名为 my-vue2 的新项目。在创建过程中,根据步骤选择你喜欢的选项,然后等待项目创建完成即可。

// 选择一个预设配置
? Please pick a preset: 
 Default ([Vue 3] babel, eslint) // Vue3 
 Default ([Vue 2] babel, eslint) // Vue2 当前选择了这个
 Manually select features // 手动选择所需特性,例如适用于单页面应用 (SPA) 或多页面应用 (MPA) 的路由,状态管理等。

// 安装依赖项时使用的包管理器
? Pick the package manager to use when installing dependencies: (Use arrow keys)   Use Yarn
  Use NPM // 当前选择了这个

注意: 如果在创建项目时遇到问题,可能是因为你的网络环境无法访问 NPM 源。你可以尝试使用如下命令切换到淘宝镜像:

npm install -g cnpm --registry=https://registry.npm.taobao.org

这将安装淘宝镜像的命令行工具 cnpm。然后,你可以使用 cnpm 命令替代 npm 来安装依赖和运行其他 npm 命令。

步骤 4:运行开发服务器

项目创建完成后,使用以下命令进入项目目录:

cd my-vue2

然后运行以下命令来启动开发服务器:

npm run serve

这将编译项目并启动一个开发服务器。在控制台中会显示你的项目的本地访问地址。打开该地址,你将看到一个基础的 Vue 应用程序。

恭喜!你已经成功地使用 Vue CLI 搭建了一个 Vue.js 项目。现在你可以开始开发你自己的 Vue 应用程序了。尽情发挥创造力吧!

目录结构

my-vue2
├─ public // 公共静态资源。等同于`static`目录
│  ├─ favicon.ico // 网站标志,
│  └─ index.html // 入口
├─ src // 源码目录
│  ├─ assets // 资源
│  ├─ components // 组件
│  ├─ router // 路由
│  ├─ App.vue // 根组件
│  └─ main.js // 人口js
├─ babel.config.js // bable编译参数
├─ jsconfig.json // 编辑器支持和模块解析
├─ package.json // 项目基本信息
└─ vue.config.js // Vue配置文件

package.json 说明

  • package.json文件配置了项目的基本信息、依赖项、脚本和配置。下面是对每个字段的解释:
  • name 项目的名称,这里是 my-vue2
  • version 项目的版本号,这里是 0.1.0
  • private 设置为 true,表示该项目是私有的,不应该被发布到公共的软件注册表中。
  • scripts 定义了一些命令脚本。这里有三个脚本命令:
    serve 用于运行项目的开发服务器。
    build 用于构建项目的生产版本。
    lint 用于运行 ESLint 进行代码检查。
  • dependencies 列出了项目在运行时所依赖的库。
  • devDependencies: 列出了项目在开发过程中所依赖的开发工具和库。
  • eslintConfig 配置了 ESLint 的规则。
  • browserslist 配置了项目所支持的目标浏览器和 Node.js 版本:
    > 1% 要求目标浏览器的使用量占全球使用率大于 1%。
    last 2 versions 要求目标浏览器的最近两个版本。
    not dead 排除已被官方宣布不再支持的浏览器版本。

第二步 Vue2 vue.config.js 基础配置,路径别名alias

vue.config.js 是一个用于 Vue 项目的配置文件,用于自定义项目的构建配置。在这个文件中,你可以修改 webpack 相关的选项,以满足你的项目需求。
webpack当前版本 @5.88.2

在你的项目根目录下,找到或创建一个名为 vue.config.js 的文件,根据以下内容进行修改:

配置静态资源访问路径

module.exports = {
  // 静态资源访问路径,默认 '/'
  publicPath: './'
}

配置输出目录

module.exports = {
  // 指定构建后的输出目录,默认 'dist'
  outputDir: 'dist'
}

配置开发服务器启动时是否自动打开和端口号

module.exports = {
   // 配置开发服务器选项
  devServer: {
    // 开发服务器启动时是否自动打开浏览器
    open: true,
    // 端口号
    port: 3000
  },
}

自定义 webpack 配置:

module.exports = {
  // webpack 的配置对象
  configureWebpack: {
    // 在这里添加或修改 webpack 的配置
  },
}

配置路径别名alias

找到 src/assets 文件夹,新建 imagesscriptsstyles 文件夹
src/assets 文件夹中 logo.png 文件放入 images 文件夹
vue.config.js 配置中中添加以下两部分代码:

const path = require('path')

configureWebpack: {
  // 配置Webpack模块解析的方式,使得你可以通过模块名字而不是相对路径来引入模块
  resolve: {
    // 设置路径别名
    alias: {
      '@': path.resolve('src'),
      '@public': path.resolve('public'),
      '@img': path.resolve('src/assets/images'),
      '@js': path.resolve('src/assets/scripts'),
      '@css': path.resolve('src/assets/styles')
    }
  }
}

上述代码使用 Node.js 的 path 模块来处理文件路径。__dirname 表示当前文件所在的目录。

resolve.alias 下添加你需要的路径别名。例如,'@' 被配置为指向 src 目录,表示你可以使用 @ 作为 src 目录的别名。

配置文件改动后需要重新启动开发服务器,这样才能让修改生效。

现在,你可以在你的 Vue 项目中使用路径别名了。例如,你可以使用 @img 来引用 src/assets/images 目录下的图片。

1.找到 src/App.vue
2.将logo图片路径改为以下内容后:

<img alt="Vue logo" src="@img/logo.png">

3.将组件引入路径改为以下内容:

import HelloWorld from '@/components/HelloWorld.vue'
  1. 查看效果。

vue.config.js 修改完成后的文件内容如下:

const path = require('path')

module.exports = {
  // 静态资源访问路径
  publicPath: './',
  // 指定构建后的输出目录,默认是 'dist'
  outputDir: 'dist',
  // 配置开发服务器选项
  devServer: {
    // 开发服务器启动时是否自动打开浏览器
    open: true,
    // 端口号
    port: 3000
  },
  // webpack 的配置对象
  configureWebpack: {
    // 配置Webpack模块解析的方式,使得你可以通过模块名字而不是相对路径来引入模块
    resolve: {
      // 设置路径别名
      alias: {
        '@': path.resolve('src'),
        '@public': path.resolve('public'),
        '@img': path.resolve('src/assets/images'),
        '@js': path.resolve('src/assets/scripts'),
        '@css': path.resolve('src/assets/styles')
      }
    }
  }
}
还可以使用其它的选项来自定义构建行为,具体可以参考 Vue CLI 官方文档中的 vue.config.js 配置参考

第三步 Vue2 vue.config.js 集成 Less 配置 sourceMap+全局变量

安装

项目根目录下打开终端或命令行工具,运行以下命令来安装相关依赖包:

npm install less-loader less --save-dev

这会将 Less 和 Less loader 作为开发依赖项安装到你的项目中。
如果没有其他需求,安装好就已经可以在项目中直接使用了。

在项目中使用

1. Vue文件中使用

找到 src/App.vue 文件中 <style> 代码块,添加 lang="less"scoped:

<style lang="less" scoped>
</style>

lang="less" 表示该<style>标签中的代码将使用 Less 语法编写。
scoped 是一个特殊的属性,它告诉Vue要对该组件的样式进行作用域限制。当你使用scoped属性时,组件中的样式只会应用到该组件内部,不会影响其他组件。

2. 引入独立less样式文件

src/assets/styles 文件夹下新建一个,名为index.less的通用样式文件,并添加自己习惯的通用样式,可参考以下内容:

body, html {
  min-height: 100%;
  font-size: 16px;
  color: #333;
}
* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
body, ul, div, img, h5, h4, h3, h2, h1, p, span, table, figure, i, em, tt, li {
  list-style: none;
  margin: 0;
  padding: 0;
}
body > * {
  margin: auto;
}
a {
  cursor: pointer;
  text-decoration: none;
}
i {
  font-style: normal;
}
textarea {
  font-family: inherit;
}
.fl {
  float: left;
}
.fr {
  float: right;
}
.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}
.none {
  position: absolute;
  height: 0;
  width: 0;
  padding: 0;
  margin: 0;
  border: none;
}
.cursor-p {
  cursor: pointer;
}
.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

然后在src/main.js中引入:

import '@css/index.less'

修改后的代码如下:

import Vue from 'vue'
import App from './App.vue'
import '@css/index.less'

// 禁用生产环境提示
Vue.config.productionTip = false

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

@css 是上一章配置的路径别名

Less具体语法可参考 Less官方文档

配置 sourceMap

在你的项目根目录下,找到 vue.config.js 文件,根据以下内容进行修改:

module.exports = {
  // 配置css相关选项
  css: {
    // 开启 source map
    sourceMap: true
  },
}

Source Map 开启后启动开发环境和生产环境都启用了 Source Map,显然不符合我们的预期。
正常情况下,我们需要在开发环境下启用Source Map,在生产环境下禁用Source Map。

可以通过环境来设置是否开启此功能,代码如下:

css: {
  sourceMap: process.env.NODE_ENV == 'development'
}

一般来说,process.env.NODE_ENV 会在开发环境中被设置为 'development',在生产环境中被设置为'production'。我们通过三目运算判断是否是开发环境,如果是开启反之则关闭即可。

vue.config.js 修改后的完整内容:

const path = require('path')

module.exports = {
  // 静态资源访问路径
  publicPath: './',
  // 指定构建后的输出目录,默认是 'dist'
  outputDir: 'dist',
  // 配置开发服务器选项
  devServer: {
    // 开发服务器启动时是否自动打开浏览器
    open: true,
    // 端口号
    port: 3000
  },
  // 配置css相关选项
  css: {
    // 开启 source map
    sourceMap: process.env.NODE_ENV == 'development'
  },
  // webpack 的配置对象
  configureWebpack: {
    // 配置Webpack模块解析的方式,使得你可以通过模块名字而不是相对路径来引入模块
    resolve: {
      // 设置路径别名
      alias: {
        '@': path.resolve('src'),
        '@public': path.resolve('public'),
        '@img': path.resolve('src/assets/images'),
        '@js': path.resolve('src/assets/scripts'),
        '@css': path.resolve('src/assets/styles')
      }
    }
  }
}

配置完成后,重新启动开发服务器就能看到效果了。

配置 Less 全局变量

在你的项目根目录下,找到 vue.config.js 文件,根据以下内容进行修改:

module.exports = {
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          // 配置全局变量
          globalVars: {
            'logoName': 'logo'
          }
        }
      }
    }
  }
}

在less中使用配置的变量

.classname {
  background: url('@img/@{logoName}.png');
}

第四步 Vue2 配置ESLint

ESLint 是一个广泛使用的 JavaScript 代码检查工具,可以帮助开发者在编写代码时发现并修复潜在的问题和错误。

第一步 创建工程 时虽然已经选择了包含 ESLint 预设配置,但还需要做一些调整,让我们使用起来能够更加的丝滑。

vue.config.js 检测开关和模式

module.exports = {
  // 是否每次保存时 lint 代码,可选值 (boolean | 'warning' | 'default' | 'error') 默认 'default'
  lintOnSave: 'default'
}

如不想使用 ESLint 将值设置为false即可。

具体可以参考 Vue CLI 官方文档中的 vue.config.js lintOnSave 配置参考

配置方式1

1.1 package.json 中 eslintConfig 模块说明:

在你的项目根目录下,找到一个名为 package.json 的文件,并找到文件中 eslintConfig 模块块,当前版本内容如下所示:

"eslintConfig": {
  "root": true,
  "env": {
    "node": true
  },
  "extends": [
    "plugin:vue/essential",
    "eslint:recommended"
  ],
  "parserOptions": {
    "parser": "@babel/eslint-parser"
  },
  "rules": {}
}

这个部分配置定义了一些ESLint的基本配置选项:

  • "root": true 指定此配置文件为根配置文件,即停止在父级目录中寻找其他配置文件。
  • "env": {"node": true} 指定代码的环境为 Node.js 环境,在 Node.js 项目中使用 ESLint 时需要设置。
  • "extends": ["plugin:vue/essential", "eslint:recommended"] 继承的 ESLint 配置。在此配置中,继承了 Vue 的插件 plugin:vue/essential 和 ESLint 的推荐配置 eslint:recommended 。plugin:vue/essential 提供了一组用于 Vue.js 项目的 ESLint 规则,eslint:recommended 提供了一组广泛认可的通用规则。
  • "parserOptions": {"parser": "@babel/eslint-parser"} 指定 ESLint 解析代码的解析器。在这个例子中,使用了@babel/eslint-parser,它是一个基于 Babel 的解析器,可用于支持 ES6+ 语法特性。
  • "rules": {} 可以用于设置和自定义 ESLint 的规则。您可以在这里添加和修改规则以符合您的代码风格和要求。
1.2 配置忽略检测

eslintConfig 模块中添加以下内容:

"eslintConfig": {
  "ignorePatterns": [
     "/node_modules/",
     "/dist/",
     "/public/",
     "*.config.js"
  ]
}

通过这个配置,您可以告诉 ESLint 忽略这些文件和文件夹,避免对不需要进行 ESLint 检查的文件进行无用的检查,提高检查效率。

以下是一些.eslintignore文件的示例规则:

**/*.js 忽略所有的.js文件
/node_modules/ 忽略特定的目录及其所有子目录
filename.js 忽略特定的文件
path/to/filename.js 忽略某个具体路径的文件
更多的细节和示例可以在 ESLint官方文档 中找到.eslintignore的文档

1.3 配置验证规则

eslintConfig 模块中 找到 rules 模块,添加自己想要的规则:

"rules": {
  "no-console": 1
}

规则配置用于定义代码中的规则或约定,帮助开发者编写更具可读性和可维护性的代码。在这里, no-console 规则用于检测代码中是否使用了 console 对象的方法

对于规则的值,ESLint使用以下三种不同类型的配置:
"off" 或 0 表示关闭该规则,不会对代码进行检查。
"warn" 或 1 表示开启该规则,并将违反规则的地方报告为警告,但不会阻止代码的执行。
"error" 或 2 表示开启该规则,并将违反规则的地方报告为错误,会阻止代码的执行。

配置方式2(当前deom采用的方式)

2.1 配置忽略检测

在根目录下创建 .eslintignore 文件

.eslintignore文件是用来配置ESLint忽略特定文件或目录的配置文件。当ESLint对代码进行静态分析时,它会检查项目中的所有文件,包括代码中的所有目录和文件。但是,有时候我们可能希望ESLint忽略某些文件或目录,以避免对它们进行规范检查。

.eslintignore文件基本上是一个包含忽略规则的文本文件。每一行表示一个忽略规则,规则可以是通配符模式或具体的文件路径。

以下是当前demo工程的.eslintignore文件中的配置内容,可作为参考:

/node_modules/
/dist/
/public/
*.config.js

以下是一些.eslintignore文件的示例规则:
**/*.js 忽略所有的.js文件
/node_modules/ 忽略特定的目录及其所有子目录
filename.js 忽略特定的文件
path/to/filename.js 忽略某个具体路径的文件
更多的细节和示例可以在 ESLint官方文档 中找到.eslintignore的文档

无论是使用.eslintignore文件还是在eslintConfig中配置ignorePatterns,都可以指定要忽略的文件或目录的路径。这样,ESLint 将不会对这些文件进行任何检查。

请注意,.eslintignore文件优先于eslintConfig中的ignorePatterns,即如果两者都存在,ESLint将优先考虑.eslintignore文件中的配置。

2.2 配置验证规则

在根目录新建 .eslintrc.js 文件,添加以下代码:

module.exports = {
  // 指定此配置文件为根配置文件,即停止在父级目录中寻找其他配置文件。
  root: true,
  // 指定代码的环境为 Node.js 环境,在 Node.js 项目中使用 ESLint 时需要设置。
  env: {
    node: true,
  },
  // 继承的 ESLint 配置。在此配置中,继承了 Vue 的插件 plugin:vue/essential。它提供了一组用于 Vue.js 项目的 ESLint 规则。
  extends: [
    'plugin:vue/essential'
  ],
  // 指定全局变量,以告诉 ESLint 在验证过程中这些变量已经定义,从而避免产生未定义变量的警告
  globals: {},
  // 指定 ESLint 解析代码的解析器
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: "module",
  },
  // 可以用于设置和自定义 ESLint 的规则。您可以在这里添加和修改规则以符合您的代码风格和要求
  rules: {
  }
}

以下是当前demo中的 .eslintrc.js 完整配置代码,以供参考:

const msgType = process.env.NODE_ENV == "development" ? 1 : 2 // 规则提示类型

module.exports = {
  // 指定此配置文件为根配置文件,即停止在父级目录中寻找其他配置文件。
  root: true,
  // 指定代码的环境为 Node.js 环境,在 Node.js 项目中使用 ESLint 时需要设置。
  env: {
    node: true,
  },
  // 继承的 ESLint 配置。在此配置中,继承了 Vue 的插件 plugin:vue/essential。它提供了一组用于 Vue.js 项目的 ESLint 规则。
  extends: [
    "plugin:vue/essential"
  ],
  // 指定全局变量,以告诉 ESLint 在验证过程中这些变量已经定义,从而避免产生未定义变量的警告
  globals: {},
  // 指定 ESLint 解析代码的解析器
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: "module",
  },
  // 可以用于设置和自定义 ESLint 的规则。您可以在这里添加和修改规则以符合您的代码风格和要求
  rules: {
    "vue/multi-word-component-names": 0, // 组件件名称是否以驼峰格式命名
    "strict": 2, // 使用严格模式
    "no-alert": 2, // 禁止使用alert confirm prompt
    "no-console": [process.env.ENV_KEY === "development" ? 0 : 1, { allow: ["warn", "error"] }], // 禁止使用console, 只能使用console.warn console.error
    "no-debugger": process.env.NODE_ENV === "development" ? 0 : 2, // 禁止使用debugger
    "prefer-arrow-callback": msgType, // 首选箭头函数
    "prefer-const": msgType, // 首选const
    "prefer-spread": msgType, // 首选展开运算
    "prefer-template": msgType, // 首选模板字符串
    "quotes": [msgType, "single"], // 引号类型 `` "" ''
    // "quote-props": [msgType, "always"], // 对象字面量中的属性名是否强制双引号
    "jsx-quotes": [msgType, "prefer-double"], // 强制在 JSX 属性中一致使用双引号或单引号
    "no-useless-concat": msgType, // 不允许两个字符串连接在一起
    "no-multi-str": msgType, // 字符串不能用\换行
    "no-new": msgType, // 禁止在使用new构造一个实例后不赋值
    "no-new-func": msgType, // 禁止使用new Function
    "no-new-object": msgType, // 禁止使用new Object()
    "no-new-require": msgType, // 禁止使用new require
    "no-new-wrappers": msgType, // 禁止使用new创建包装实例,new String new Boolean new Number
    "no-array-constructor": msgType, // 不允许使用Array构造函数
    "semi": [msgType, "never"], // 语句强制分号结尾
    "semi-spacing": [msgType, { "before": false, "after": true }], // 分号前后空格
    "no-extra-semi": msgType, // 禁止多余的分号
    "func-style": [msgType, "expression"], // 使用函数表达式
    "no-underscore-dangle": msgType, // 标识符不能以_开头或结尾
    "no-await-in-loop": msgType, // 不允许await在循环体内使用
    "no-bitwise": msgType, // 不允许按位运算符
    "no-buffer-constructor": msgType, // 不允许调用和构造Buffer()构造函数
    "no-caller": msgType, // 阻止使用已弃用和次优代码
    "no-catch-shadow": msgType, // 禁止catch子句参数与外部作用域变量同名
    "no-cond-assign": msgType, // 禁止在条件表达式中使用赋值语句
    "no-confusing-arrow": msgType, // 不在可能与比较运算符混淆的地方使用箭头函数语法
    "no-const-assign": msgType, // 禁止修改const声明的常量
    "no-constant-condition": msgType, // 禁止在条件中使用常量表达式 if(true) if(1)
    "no-continue": msgType, // 禁止使用continue
    "no-control-regex": msgType, // 禁止在正则表达式中使用控制字符
    "no-delete-var": msgType, // 不能对var声明的变量使用delete操作符
    "no-div-regex": msgType, // 不能使用看起来像除法的正则表达式/=foo/
    "no-dupe-args": msgType, // 函数参数不能重复
    "no-dupe-class-members": msgType, // 类成员中不能有相同名称的声明
    "no-dupe-keys": msgType, // 在创建对象字面量时不允许键重复 {a:1,a:1}
    "no-duplicate-case": msgType, // switch中的case标签不能重复
    "no-duplicate-imports": msgType, // 从单个模块进行的所有导入都以单一import语句存在
    "no-empty": msgType, // 块语句中的内容不能为空
    "no-empty-character-class": msgType, // 正则表达式中的[]内容不能为空
    "no-eq-null": 0, // 禁止对null使用==或!=运算符
    "no-eval": msgType, // 禁止使用eval
    "no-ex-assign": msgType, // 禁止给catch语句中的异常参数赋值
    "no-extend-native": msgType, // 禁止扩展native对象
    "no-extra-bind": msgType, // 禁止不必要的函数绑定
    "no-extra-boolean-cast": msgType, // 禁止不必要的boolean转换
    "no-extra-label": msgType, // 消除不必要的标签
    "no-extra-parens": msgType, // 禁止非必要的括号
    "no-fallthrough": msgType, // 禁止switch穿透
    "no-floating-decimal": msgType, // 禁止省略浮点数中的0 .5 3.
    "no-func-assign": msgType, // 禁止重复的函数声明
    "no-global-assign": msgType, // 不允许修改只读全局变量
    "no-implicit-coercion": msgType, // 禁止隐式转换
    "no-implied-eval": msgType, // 禁止使用隐式eval
    "no-inner-declarations": [msgType, "functions"], // 禁止在块语句中使用声明(变量或函数)
    "no-invalid-regexp": msgType, // 禁止无效的正则表达式
    "no-invalid-this": msgType, // 禁止无效的this,只能用在构造器,类,对象字面量
    "no-irregular-whitespace": msgType, // 不能有不规则的空格
    "no-iterator": msgType, // 禁止使用__iterator__ 属性
    "no-label-var": msgType, // label名不能与var声明的变量名相同
    "no-labels": msgType, // 禁止标签声明
    "no-lone-blocks": msgType, // 禁止不必要的嵌套块
    "no-lonely-if": 0, // 将if语句作为else块中的唯一语句
    "no-mixed-operators": [msgType, {"groups": [["==","!=","===","!==",">",">=","<","<="], ["&&","||"]]}], // 复杂的表达式使用括号
    "no-mixed-spaces-and-tabs": msgType, // 禁止混用tab和空格
    "no-multi-spaces": msgType, // 不能用多余的空格
    "no-multiple-empty-lines": [msgType, { "max": 1 }], // 空行最多不能超过1行
    "no-negated-condition": msgType, // 禁止不必要的否定条件
    "no-negated-in-lhs": msgType, // in 操作符的左边不能有!
    "no-nested-ternary": msgType, // 禁止使用嵌套的三目运算
    "no-obj-calls": msgType, // 不能调用内置的全局对象,比如Math() JSON()
    "no-octal": msgType, // 禁止使用八进制数字
    "no-octal-escape": msgType, // 禁止使用八进制转义序列
    "no-param-reassign": msgType, // 禁止给参数重新赋值
    "no-process-exit": msgType, // 禁止使用process.exit()
    "no-proto": msgType, // 禁止使用__proto__属性
    "no-redeclare": msgType, // 禁止重复声明变量
    "no-regex-spaces": msgType, // 禁止在正则表达式字面量中使用多个空格 /foo bar/
    "no-return-assign": msgType, // return 语句中不能有赋值表达式
    "no-script-url": msgType, // 禁止使用javascript:void(0)
    "no-self-compare": msgType, // 不能比较自身
    "no-sequences": msgType, // 禁止使用逗号运算符
    "no-shadow": msgType, // 外部作用域中的变量不能与它所包含的作用域中的变量或参数同名
    "no-shadow-restricted-names": msgType, // 严格模式中规定的限制标识符不能作为声明时的变量名使用
    "no-spaced-func": msgType, // 函数调用时 函数名与()之间不能有空格
    "no-sparse-arrays": msgType, // 禁止稀疏数组, [1,,2]
    "no-trailing-spaces": msgType, // 一行结束后面不要有空格
    "no-throw-literal": msgType, // 禁止抛出字面量错误 throw "error";
    "no-undef": msgType, // 不能有未定义的变量
    "no-undef-init": msgType, // 变量初始化时不能直接给它赋值为undefined
    "no-undefined": msgType, // 不能使用undefined
    "no-unexpected-multiline": msgType, // 避免多行表达式
    "no-unneeded-ternary": msgType, // 禁止不必要的嵌套 var isYes = answer === 1 ? true : false;
    "no-unreachable": msgType, // 不能有无法执行的代码
    "no-unused-expressions": msgType, // 禁止无用的表达式
    "no-unused-vars": [msgType, { "vars": "all", "args": "none" }], // 不能有声明后未被使用的变量或参数
    "no-use-before-define": msgType, // 未定义前不能使用
    "no-useless-call": msgType, // 禁止不必要的call和apply
    "no-void": msgType, // 禁用void操作符
    "no-var": msgType, // 禁用var,用let和const代替
    "no-with": msgType, // 禁用with
    "array-bracket-spacing": [msgType, "never"], // 是否允许非空数组里面有多余的空格
    "arrow-parens": [msgType, "always"], // 箭头函数用小括号括起来
    "arrow-spacing": [msgType, { "before": true, "after": true }], // =>的前/后括号
    "block-scoped-var": msgType, // 块语句中使用var
    "brace-style": [msgType, "1tbs"], // 大括号风格
    "camelcase": msgType, // 强制驼峰法命名
    "comma-dangle": [msgType, "never"], // 对象字面量项尾不能有逗号
    "comma-spacing": [msgType, { "before": false, "after": true }], // 逗号前后的空格
    "comma-style": [msgType, "last"], // 逗号风格,换行时在行首还是行尾
    "consistent-this": [msgType, "self"], // this别名
    "curly": [msgType, "all"], // 必须使用 if(){} 中的{}
    "default-case": msgType, // switch语句最后必须有default
    "dot-location": [msgType, "object"], // 对象访问符的位置,换行的时候在行首还是行尾
    "eqeqeq": 0, // 必须使用全等
    "func-names": [msgType, "never"], // 函数表达式必须有名字
    "indent": [msgType, 2], // 缩进风格
    "init-declarations": [msgType, "always"], // 声明时必须赋初值
    "key-spacing": [msgType, { "beforeColon": false, "afterColon": true }], // 对象字面量中冒号的前后空格
    "max-depth": [msgType, 5], // 嵌套块深度
    "max-nested-callbacks": [msgType, 3], // 回调嵌套深度
    "max-params": [msgType, 5], // 函数最多只能有几个参数
    "object-curly-spacing": [msgType, "always"], // 大括号内是否允许不必要的空格
    "object-shorthand": msgType, // 强制对象字面量缩写语法
    "one-var": [msgType, "never"], // 连续声明
    "operator-assignment": [msgType, "never"], // 赋值运算符 += -=什么的
    "operator-linebreak": [msgType, "after"], // 换行时运算符在行尾还是行首
    "padded-blocks": [msgType, "never"], // 块语句内行首行尾是否要空行
    "radix": msgType, // parseInt必须指定第二个参数
    "space-before-blocks": [msgType, "always"], // 不以新行开始的块{前面要不要有空格
    "space-before-function-paren": [msgType, "never"], // 函数定义时括号前面要不要有空格
    "space-in-parens": [msgType, "never"], // 小括号里面要不要有空格
    "space-unary-ops": [msgType, { "words": true, "nonwords": false }], // 一元运算符的前/后要不要加空格
    "use-isnan": msgType, // 禁止比较时使用NaN,只能用isNaN()
    "spaced-comment": [msgType, "always"], // 注释一致性
    "no-path-concat": 0, // node中不能使用__dirname或__filename做路径拼接
    "no-process-env": 0, // 禁止使用process.env
    "no-restricted-modules": 0, // 禁用指定node.js模块,使用就会报错
    "no-sync": 0, // nodejs 禁止同步方法
    "newline-after-var": 0, // 变量声明后是否需要空一行
  }
}
最终根据当前deom的最终配置可删除以下内容,避免无用代码导致维护成本增加:
  • package.json@babel/eslint-parser 开发依赖。
  • package.jsoneslintConfig 代码块 。
  • 如果 .eslintignore 文件存在便删除。

代码中的忽略检测

/* eslint-disable */ 在文件开头禁用 eslint 检查
/* eslint-disable no-alert, quotes */ 在文件开头禁用 eslint 指定规则检查
// eslint-disable-line 单行禁用eslint检查
// eslint-disable-line no-alert, quotes 单行禁用指定规则检查
// eslint-disable-next-line 禁用下一行eslint检查
// eslint-disable-next-line no-alert, quotes 下一行禁用指定规则检查

第五步 Vue2 vue.config.js 使用image-minimizer-webpack-plugin配置图片压缩

项目根目录下打开终端或命令行工具,运行以下命令来安装相关依赖包:

npm install image-minimizer-webpack-plugin imagemin imagemin-pngquant --save-dev

当前版本 image-minimizer-webpack-plugin@3.8.3 imagemin@8.0.1 imagemin-pngquant@9.0.2
如果安装后配置后编译时报错无法正常压缩图片,设置版本为当前版本即可。

使用

在你的项目根目录下,找到 vue.config.js 文件,根据以下内容进行修改:

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin') // 压缩图片插件

module.exports = {
  configureWebpack: {
    // 配置需要使用的 webpack 插件
    plugins: [
      // 压缩图片
      new ImageMinimizerPlugin({
        minimizer: {
          // 指定了采用哪种图片压缩实现方式
          implementation: ImageMinimizerPlugin.imageminGenerate,
          // 压缩插件选项
          options: {
            plugins: ['pngquant']  // 用于对 PNG 图片进行压缩
          }
        }
      })
    ]
  }
}

通过以上配置,当项目构建时,image-minimizer-webpack-plugin 插件会对项目中的图片进行压缩,并使用指定的配置项来优化不同格式的图片。上述代码中只用到了 pngquant 插件压缩PNG格式的图片。你可以根据需要调整插件选项。

配置完成后,Webpack 将在打包过程中将会自动进行图片压缩。

更多压缩插件选项请参考 mage-minimizer-webpack-plugin GitHub 仓库

vue.config.js 修改完成后的文件内容如下:

const path = require('path')
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin') // 压缩图片插件

module.exports = {
  // 静态资源访问路径, 默认是 '/'
  publicPath: './',
  // 指定构建后的输出目录,默认是 'dist'
  outputDir: 'dist',
  // 是否每次保存时 lint 代码,可选值 (boolean | 'warning' | 'default' | 'error') 默认 'default'
  lintOnSave: 'default',
  // 配置开发服务器选项
  devServer: {
    // 开发服务器启动时是否自动打开浏览器
    open: false,
    // 端口号
    port: 3000
  },
  // 配置css相关选项
  css: {
    // 开启 source map
    sourceMap: process.env.NODE_ENV == 'development'
  },
  // webpack 的配置对象
  configureWebpack: {
    // 配置需要使用的 webpack 插件
    plugins: [
      // 压缩图片
      new ImageMinimizerPlugin({
        minimizer: {
          // 指定了采用哪种图片压缩实现方式
          implementation: ImageMinimizerPlugin.imageminGenerate,
          // 压缩插件选项
          options: {
            plugins: ['pngquant'] // 用于对 PNG 图片进行压缩
          }
        }
      })
    ],
    // 配置Webpack模块解析的方式,使得你可以通过模块名字而不是相对路径来引入模块
    resolve: {
      // 设置路径别名
      alias: {
        '@': path.resolve('src'),
        '@public': path.resolve('public'),
        '@img': path.resolve('src/assets/images'),
        '@js': path.resolve('src/assets/scripts'),
        '@css': path.resolve('src/assets/styles')
      }
    }
  }
}

第六步 Vue2 集成全家桶 vue-router vuex axios 和 element-ui

  • Vue Router
    是Vue.js官方提供的路由管理库,用于实现前端应用的路由功能。它可以将前端路由映射到Vue组件,实现页面的切换和导航等功能。Vue Router支持嵌套路由、路由参数、路由守卫等高级功能,能够满足各种复杂的路由需求。

  • Vuex
    是Vue.js官方提供的状态管理库,用于集中管理应用程序中的状态。它将应用程序中的数据存储在一个全局的store中,并提供了一些API来改变状态和获取状态。Vuex的核心概念包括state(存储应用程序的状态)、mutations(用于改变状态的方法)、actions(用于异步操作和提交mutations的方法)等。通过Vuex,可以实现状态在组件间的共享和管理,提供了更好地组织和协调组件间的通信和数据流动。

  • Axios
    是一个基于Promise的HTTP客户端库,用于在浏览器和Node.js中发起HTTP请求。它提供了一系列的API来发送请求、拦截请求和响应、处理错误等。Axios支持浏览器的XMLHttpRequest和Node.js的http模块,提供了更简洁、易用和可配置的接口。在Vue.js开发中,Axios通常用于与后端API进行通信,发送异步请求获取数据。

  • Element UI
    是一套基于 Vue.js 的桌面端 UI 组件库,它提供了丰富的可复用组件,方便开发者快速构建现代化、美观的 Web 应用程序。

安装

项目根目录下打开终端或命令行工具,运行以下命令来安装相关依赖包:

npm install vue-router@3.0.1 vuex@3.0.1 axios element-ui --save

vue-router

1. 在 src/ 目录下新建 views 目录。在此目录中新建一个名为 404.vue 的文件,并添加以下内容:

<template>
  <div class="error">
    <div class="imgWrapper">
      <img src="@img/errorPages/404.png" alt="404">
    </div>
  </div>
</template>

<style lang="less" scoped>
  .error {
    display: grid;
    place-items: center;
    height: 100vh;
  }
</style>

404.png 图片如果未添加会编译报错,找一张图片放上去或者删除图片放入自己的文字即可。

2. 在 src/ 目录下找到并打开 App.vue 文件,用以下内容直接覆盖现有内容:

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

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

<router-view> 是 Vue Router 提供的组件,用于在 Vue 应用中展示当前路由对应的组件内容。它作用类似于一个占位符,它定义了一个容器,在路由切换时,会根据不同的路由匹配,动态渲染对应的组件内容。

3. 在 src/ 目录下新建 router 目录。在此目录中新建一个名为 index.js 的文件,并添加以下内容:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const pages = [
  {
    path: '/home',
    component: (resolve) => require(['@/components/HelloWorld.vue'], resolve)
  },
  {
    path: '/errorPage/404',
    component: (resolve) => require(['@/views/404.vue'], resolve)
  }
]

const router = new VueRouter({
  routes: [
    // 默认路由
    {
      path: '/',
      redirect: '/home'
    },
    // 页面路由
    ...pages,
    // 没有匹配的路由重定向到404页面
    {
      path: '*',
      redirect: '/errorPage/404'
    }
  ]
})

// 路由跳转前
router.beforeEach((to, from, next) => {
  // 可用于拦截导航并执行一些操作,例如验证用户身份、权限控制等。
  next()
})

// 路由跳转后
router.afterEach((to, from) => {
  window.scrollTo(0, 0) // 每次路由改变滚动条都回到顶部
})

export default router

这段代码是一个基于Vue Router的路由配置。

以下是对代码的解释:

  • Vue.use(VueRouter) 是通过Vue.use()方法来全局注册 Vue Router 插件,使得我们可以在 Vue 实例中使用 Vue Router 的功能。

  • const pages = [... ] 定义了一个数组变量pages,用于存储页面路由配置。每个页面路由配置以对象表示,对象中包括一个路由路径path和对应的组件component
    这里使用了一个按需加载的方式,可以在需要时异步加载组件:
    (resolve) => require(['xxx.vue'], resolve) 表示在路由激活时动态加载组件,并将解析后的组件传递给resolve回调函数。换言之,当访问对应的路由路径时,路由系统会动态加载组件并渲染到匹配的路由视图中。

  • const router = new VueRouter({...}) 是创建一个 Vue Router 实例,并配置其中的路由。在这里,路由配置包含三部分:
    默认路由:将根路径/重定向到/home路径。
    页面路由:使用展开运算符...pages数组中的页面路由配置添加到路由配置中。
    没有匹配的路由重定向到404页面:当用户访问不存在的路径时,将自动重定向到/errorPage/404路径。

  • router.beforeEach((to, from, next) => {...}) 是路由跳转前的钩子函数。在其中可以执行一些操作,例如验证用户身份、权限控制等。在这段代码中,钩子函数逻辑为空,即不执行任何操作。

  • router.afterEach((to, from) => {...}) 是路由跳转后的钩子函数。在这里,使用window.scrollTo(0, 0)将滚动条位置重置为顶部,以确保每次路由改变时都会回到顶部。

4. 打开 src/main.js 文件,挂载到Vue实例:

import router from './router'

new Vue({
  router
})

修改后的代码如下:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import '@css/index.less'

// 禁用生产环境提示
Vue.config.productionTip = false

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

vuex

1. 在 src/ 目录下新建 store 目录。在此目录中新建一个名为 index.js 的文件,并添加以下内容:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 本地存储-修改
const storageSet = (key, value) => {
  localStorage.setItem(key, JSON.stringify(value))
}

// 本地存储-获取
const storageGet = (key) => {
  return JSON.parse(localStorage.getItem(key))
}

export default new Vuex.Store({
  // 数据源 使用:this.$store.state.xxx
  state: {
    user: {} // 用户信息
  },
  // 派生数据 使用:this.$store.getters.xxx
  getters: {
    // 获取当前-用户对象
    GET_USER(state) {
      state.user = storageGet('STORE_USER') || {}
      return state.user
    }
  },
  // 更改数据-同步 使用:this.$store.commit('xxx', data)
  mutations: {
    // 保存当前-用户对象
    SET_USER(state, data) {
      state.user = data
      storageSet('STORE_USER', data)
    }
  },
  // mutations装饰器-异步
  actions: {
  }
})

这段代码是一个基于 Vue 和 Vuex 的状态管理工具的配置。以下是对代码的解释:

  • Vue.use(Vuex) 是通过Vue.use()方法来全局注册 Vuex 插件,使得我们可以在 Vue 实例中使用 Vuex 的功能。

  • const storageSet = (key, value) => {...} 和 const storageGet = (key) => {...} 是两个辅助函数,用于将数据存储在本地的localStorage中,并且可以在需要时获取该数据。

  • new Vuex.Store({...}) 是创建一个 Vuex 的 Store 实例。这个实例将包含 Vuex 的核心架构和一些选项来定义应用程序的状态管理。

  • state 属性用于定义仓库store的初始状态,其中user是一个空对象,用于存储用户信息。

  • getters 属性是派生状态的计算属性,允许我们从仓库的数据中获取一些衍生状态。GET_USER getter用于获取当前用户对象。

  • mutations 属性定义了一些同步方法,用来修改仓库的状态。在这里,只有一个SET_USER mutation方法用于保存当前用户对象,并同时将其存储在本地localStorage中。

  • actions 属性中可以定义一些异步方法,在需要时执行异步操作,并最终调用mutations中的方法来修改状态。

2. 打开 src/main.js 文件,挂载到Vue实例:

import store from './store'

new Vue({
  store
})

修改后的代码如下:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@css/index.less'

// 禁用生产环境提示
Vue.config.productionTip = false

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

axios

src/目录下新建 api 目录。在此目录中新建一个名为 index.js 的文件,并添加以下内容:

import Vue from 'vue'
import axios from 'axios'

// 设置超时时长
axios.defaults.timeout = '60000'

// request拦截器
axios.interceptors.request.use((config) => {
  return config
}, (error) => {
  return Promise.reject(error)
})

// responese拦截器
axios.interceptors.response.use((res) => {
  return res
}, (error) => {
  return Promise.reject(error)
})

/**
 * 设置请求header
 * @param {Object} headers
 */
const setHeader = (headers) => {
  for (const key in headers) {
    axios.defaults.headers[key] = headers[key]
  }
}

/**
 * POST请求
 * @param {String} url 地址
 * @param {Object} params 参数
 * @param {Object} headers headers
 */
export const methodPost = (url, params, headers = {}) => {
  return new Promise((resolve, reject) => {
    setHeader(headers)
    axios.post(url, params).then((response) => {
      resolve(response.data)
    }).catch((error) => {
      reject(error)
    })
  })
}

/**
 * 文件上传
 * @param {String} url 地址
 * @param {File} file 文件
 */
export const methodUpload = (url, file) => {
  return new Promise((resolve, reject) => {
    const formData = new FormData()
    formData.append('file', file)
    formData.append('currentDate', Date.now())
    axios.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    }).then((response) => {
      resolve(response.data)
    }).catch((error) => {
      reject(error)
    })
  })
}

这段代码是一个配置了axios 网络请求库的请求拦截器和响应拦截器,以及一些封装的请求方法。
以下是对代码的解释:

  • axios.defaults.timeout = '60000' 设置了axios的默认超时时长为60秒。

  • axios.interceptors.request.use((config) => {...}, (error) => {...}) 是请求拦截器,用于在发送请求之前对请求进行一些处理。在这里,通过config来获取请求配置,可以对请求进行一些修改或处理,然后返回修改后的请求配置。如果在请求发送过程中发生错误,将会被catch到并返回一个rejected状态的Promise

  • axios.interceptors.response.use((res) => {...}, (error) => {...}) 是响应拦截器,用于在接收到响应后对响应进行一些处理。在这里,通过res来获取响应数据,可以对响应进行一些修改或处理,然后返回修改后的响应数据。如果在响应过程中发生错误,将会被catch到并返回一个rejected状态的Promise

  • const setHeader = (headers) => {...} 是一个工具函数,用于设置请求的header。将传入的header参数遍历,并将其设置到axios的默认headers中。

  • export const methodPost = (url, params, headers = {}) => {...} 是一个封装的POST请求方法。该方法接收一个url、一个params对象和一个可选的headers对象作为参数,使用axios.post方法发送POST请求,并返回一个Promise对象。如果请求成功,将会将响应数据作为resolved状态返回;如果请求失败,将会将错误作为rejected状态返回。

  • export const methodUpload = (url, file) => {...} 是一个文件上传方法。该方法接收一个url和一个file对象作为参数,使用FormDatafile对象附加到请求体中,并将请求发送到指定的url。同样,该方法也返回一个Promise对象,在上传成功时将响应数据作为resolved状态返回,失败时将错误作为rejected状态返回。

这些封装的请求方法可以方便地在应用中进行网络请求,并对请求和响应进行统一的处理。

通过下面的方式便可引入调用:

import { methodPost } from '@/api'

methodPost('接口地址', {}).then((res) => {
  // 请求成功
}).catch((err) => {
  // 请求失败
})

element-ui

1. 打开 src/main.js 文件,挂载到Vue实例:

import Element from 'element-ui'
import "element-ui/lib/theme-chalk/index.css"

// Element挂载到Vue
Vue.$message = Element.Message
Vue.use(Element)

修改后的代码如下:

import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import App from './App.vue'
import router from './router'
import store from './store'
import '@css/index.less'

// 禁用生产环境提示
Vue.config.productionTip = false

// Element挂载到Vue
Vue.$message = Element.Message
Vue.use(Element)

new Vue({
  router,
  store,
  render: (h) => h(App)
}).$mount('#app')
2. 打开之前创建的 src/api/index.js 文件,找到以下代码块:

// responese拦截器
axios.interceptors.response.use((res) => {
  return res
}, (error) => {
  return Promise.reject(error)
})

在添加 Vue.$message.error(error.toString())代码, 如下:

// responese拦截器
axios.interceptors.response.use((res) => {
  return res
}, (error) => {
  Vue.$message.error(error.toString())
  return Promise.reject(error)
})

这样响应时的错误信息就能通过 Element 的 Message 组件来显示了。

更多组件的使用方式,可到 element-ui 官方文档 中查看。

第七步 Webpack 配置多环境和全局变量 cross-env 和 webpack.DefinePlugin

一般情况下我们需要多个环境如:开发dev 测试test 预发布release 正式build,每个环境有自己的独立api接口请求地址。
此时我们就需要使用cross-env命令设置环境变量。

1 安装 cross-env

项目根目录下打开终端或命令行工具,运行以下命令来安装相关依赖包:

npm install cross-env --save-dev

2 使用 cross-env

在你的项目根目录下,找到 package.json 文件,根据以下内容进行修改:

"scripts": {
  "dev": "cross-env ENV_KEY=dev vue-cli-service serve",
  "test": "cross-env ENV_KEY=test vue-cli-service build",
  "release": "cross-env ENV_KEY=release vue-cli-service build",
  "build": "cross-env ENV_KEY=build vue-cli-service build"
}

3 多环境基本内容配置

package.json 文件中添加各环境的配置,如下:

"envConfig": {
  "dev": {
    "API": "http://dev"
  },
  "test": {
    "API": "http://test"
  },
  "release": {
    "API": "http://release"
  },
  "build": {
    "API": "http://build"
  }
}

如需要配置其他内容,和API同级即可。

package.json 修改后的完整内容如下:

{
  "name": "my-vue2",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "cross-env ENV_KEY=dev vue-cli-service serve",
    "test": "cross-env ENV_KEY=test vue-cli-service build",
    "release": "cross-env ENV_KEY=release vue-cli-service build",
    "build": "cross-env ENV_KEY=build vue-cli-service build"
  },
  "envConfig": {
    "dev": {
      "API": "http://dev"
    },
    "test": {
      "API": "http://test"
    },
    "release": {
      "API": "http://release"
    },
    "build": {
      "API": "http://build"
    }
  },
  "dependencies": {
    "axios": "^1.4.0",
    "core-js": "^3.8.3",
    "element-ui": "^2.15.13",
    "vue": "^2.6.14",
    "vue-router": "^3.0.1",
    "vuex": "^3.0.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "cross-env": "^7.0.3",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "image-minimizer-webpack-plugin": "^3.8.3",
    "imagemin": "^8.0.1",
    "imagemin-pngquant": "^9.0.2",
    "less": "^4.2.0",
    "less-loader": "^11.1.3",
    "vue-template-compiler": "^2.6.14"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

4 vue.config.js 配置 Webpack 打包时分配对应环境配置

通过使用cross-env工具配置了环境变量ENV_KEY后,我们可以在vue.config.js文件中使用process.env.ENV_KEY来获取该环境变量的值。接着,可以根据获取到的值从package.json文件中获取对应的配置内容,并将其存储在全局变量中,从而实现多环境的配置。

webpack.DefinePlugin是 Webpack 插件之一,用于在构建过程中创建全局变量。它允许在代码中使用这些全局变量,可以在构建时将它们替换为具体的值。

在你的项目根目录下,找到 vue.config.js 文件,根据以下内容进行修改:

const webpack = require('webpack')
const packageConfig = require('./package.json')

const ENV_CONFIG = packageConfig.envConfig[process.env.ENV_KEY]

plugins: [
  // 环境配置全局变量
  new webpack.DefinePlugin({ 'process.env.config': JSON.stringify(ENV_CONFIG) })
]

vue.config.js 修改后的完整内容如下:

const path = require('path')
const webpack = require('webpack')
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin') // 压缩图片插件
const packageConfig = require('./package.json')

const ENV_CONFIG = packageConfig.envConfig[process.env.ENV_KEY]

module.exports = {
  // 静态资源访问路径, 默认是 '/'
  publicPath: './',
  // 指定构建后的输出目录,默认是 'dist'
  outputDir: 'dist',
  // 是否每次保存时 lint 代码,可选值 (boolean | 'warning' | 'default' | 'error') 默认 'default'
  lintOnSave: 'default',
  // 配置开发服务器选项
  devServer: {
    // 开发服务器启动时是否自动打开浏览器
    open: false,
    // 端口号
    port: 3000
  },
  // 配置css相关选项
  css: {
    // 开启 source map
    sourceMap: process.env.NODE_ENV == 'development'
  },
  // webpack 的配置对象
  configureWebpack: {
    // 配置需要使用的 webpack 插件
    plugins: [
      // 环境配置全局变量
      new webpack.DefinePlugin({
        'process.env.config': JSON.stringify(ENV_CONFIG)
      }),
      // 压缩图片
      new ImageMinimizerPlugin({
        minimizer: {
          // 指定了采用哪种图片压缩实现方式
          implementation: ImageMinimizerPlugin.imageminGenerate,
          // 压缩插件选项
          options: {
            plugins: ['pngquant'] // 用于对 PNG 图片进行压缩
          }
        }
      })
    ],
    // 配置Webpack模块解析的方式,使得你可以通过模块名字而不是相对路径来引入模块
    resolve: {
      // 设置路径别名
      alias: {
        '@': path.resolve('src'),
        '@public': path.resolve('public'),
        '@img': path.resolve('src/assets/images'),
        '@js': path.resolve('src/assets/scripts'),
        '@css': path.resolve('src/assets/styles')
      }
    }
  }
}

在完成配置后,便可以在代码中使用 process.env.config 来获取对应的配置项内容。这样,根据之前的配置和设置的环境变量,可以轻松地在代码中访问和使用配置项的值。这种方式非常方便,可以根据不同的环境动态获取相应的配置内容,使得代码在不同的环境中更具灵活性和可配置性。


 

 附送250套精选项目源码

源码截图

源码获取:关注公众号「码农园区」,回复 【源码】,即可获取全套源码下载链接

 

最近更新

  1. TCP协议是安全的吗?

    2024-03-29 14:26:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-29 14:26:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-29 14:26:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-29 14:26:03       18 阅读

热门阅读

  1. 四、分治算法

    2024-03-29 14:26:03       18 阅读
  2. 2024蓝桥杯每日一题(背包)

    2024-03-29 14:26:03       21 阅读
  3. Vue3 实现基于token 用户登录

    2024-03-29 14:26:03       18 阅读
  4. 前端Vue开发技术总结

    2024-03-29 14:26:03       20 阅读
  5. day72Html

    day72Html

    2024-03-29 14:26:03      25 阅读
  6. 微信小程序监听用户经纬度变化

    2024-03-29 14:26:03       17 阅读
  7. 2024.3.25 ARM

    2024-03-29 14:26:03       17 阅读
  8. ArcGis Pro Python工具箱教程 03 工具箱中工具自定义

    2024-03-29 14:26:03       17 阅读
  9. silk-v3-decoder将sil转为mp3

    2024-03-29 14:26:03       29 阅读