# Vue CLI

# 关于 Vue CLI

Vue CLI 是 Vue 官方推出的一个脚手架客户端工具,使用它可以快速的构建一个基于 Vue 的单页面应用。

# 安装 Node.js

下载 https://mirrors.tuna.tsinghua.edu.cn/nodejs-release/v16.14.2/node-v16.14.2-x64.msi 并安装,安装过程中没有特殊选项。

安装完成后,可以在命令提示符窗口或终端中执行 npm -v 检查是否安装成功:

1
npm -v

安装 Node.js 的主要目的就是为了使用 npm

npm = Node Package Manager

在使用 npm 之前,需要先将 npm 源配置为国内的某个 npm 源服务器

1
npm config set registry https://registry.npm.taobao.org

设置后,还可以通过 get 命令查看 npm 源:

1
npm config get registry

注意:以上命令并不能检查你的配置值是否正确!

# 安装 Vue CLI

需要安装 Vue CLI 以后,才可以通过它的命令来创建 Vue CLI 项目、启动项目等。

当安装了 npm 并配置 npm 源之后,安装 Vue CLI 的命令是:

1
npm install -g @vue/cli

安装过程中没有出现 Error 字样即为成功

安装过程中出现 Error 字样即为失败,可以:

  • 先通过 npm config get registry 检查 npm 源是否是: https://registry.npm.taobao.org/
  • 重新执行以上安装 Vue CLI 命令
  • 不要在 Power Shell 下执行命令(命令提示符前面为 PS 字样)
  • 如果使用 Mac OS(苹果操作系统),建议在命令前添加 sudo 以使用管理员权限来执行命令

如果安装过程中卡住长时间没有反应,可以按下 Ctrl + C 强制终止,然后再次执行命令进行尝试。

当安装完成之后,可以使用 vue -V 来查看 Vue CLI 版本,也可以用于检验刚才的安装是否成功:

1
vue -V

# 创建 Vue CLI 项目

通常,应该创建某个文件夹,用于存放项目,例如在 D 盘下创建 Vue-Workspace 文件夹,然后,在命令提示符窗口中进入此文件夹:

1
2
3
D:

cd D:\Vue-Workspace

接下,通过 vue create 项目名称 命令来创建 Vue CLI 项目:

1
vue create jsd2204-csmall-web-client-teacher

注意:敲完以后命令之后只能按 1 下回车键,即使卡住了,也不要反复按回车!

注意:如果接下来的操作过程中选错,按下 Ctrl + C 强制终止,再重新创建项目。

按 1 下回车后,稍微等待一会,会出现创建项目时的选项,需要选择:

1
Manually select features
1
2
3
Babel
Vuex
Router
1
2.x
1
直接回车
1
In package.json
1
直接回车

最后,看到 Successfully created project jsd2204-csmall-web-client-teacher 字样,即表示创建成功。

# 启动项目

通过 IntelliJ IDEA 打开项目,在 IntelliJ IDEA 的 Terminal 窗口中执行:

1
npm run serve

执行以上命令即可启动项目,启动成功后,即可看提示:

1
2
App running at:
- Local: http://localhost:8080/

提示:可能某些电脑上会显示多个网址,这并不重要。

打开浏览器,通过 http://localhost:8080/ 网址进行访问,即可看到默认的页面。

关于占用端口:通过 npm run serve 启动的 Vue CLI 会默认尝试占用 8080 端口,如果尝试占用的端口号已经被其它进程占用,则会自动顺延一位,即尝试占用 8081 端口,如果仍被占用,会继续顺延……

也可以显式的指定某个端口号,在 package.json 中修改 scriptsserve 属性,例如配置为:

1
"serve": "vue-cli-service serve --port 8888"

则当前项目启动时会占用 8888 端口。

# 停止服务

当项目启动后,在提示了启动成功的端口窗口中,按下 Ctrl + C 即可停止服务。

提示:有时按下 Ctrl + C 后没有响应,可能反复多按几次,或按了 Ctrl + C 后回车。

提示:其实,只要按下了 Ctrl + C ,当前服务就已经停止了,后续可能出现 终止批处理操作吗(Y/N)? 提示,无论选择 Y 还是 N ,都无所谓。

# 重启服务

没有此功能

# Vue CLI 项目结构

  • package.json :相当于 Maven 项目中的 pom.xml 文件,主要配置了当前项目的依赖项,如果不太熟悉此文件,不建议手动修改
  • package-lock.json :此文件是自动生成的,不建议手动修改
  • [node_modules] :当前项目中各依赖项对应的源文件,通常,此文件夹的内容较多,且共享项目时,通常不会包含此文件夹,例如 GIT 仓库中的项目文件通常不包含此文件夹的内容,执行 npm install 命令将根据 package.json 下载相关的依赖项到此文件夹中
  • [src/views] :是建议的存放 .vue 视图文件的文件夹
  • [src/router/index.js] :是项目的路由配置文件,它配置了各路径与 .vue 视图组件的对应关系
  • public/index.html :项目中唯一的 HTML 文件,其内部在页面设计中添加了 <div id="app"></div> 标签
  • src/App.vue :项目中默认的视图文件,是被 index.html 显示的

# 关于.vue 视图文件

是 Vue CLI 中用于设计页面的源文件,可以此文件中设计页面的元素、CSS 样式、JavaScript。

此文件可以有 3 个根节点(元素):

  • <template> :在其内部设计页面元素,且此节点(元素)必须有且仅有 1 个直接子节点(元素),通常,会在 <template> 下添加 <div> ,然后,在 <div> 内部再设计页面
  • <style> :在其内部配置 CSS 样式
  • <script> :在其内部编写 JavaScript 程序

提示:根据页面设计,某些 .vue 文件可能没有 <style> ,或可能没有 <script>

# 关于路由配置

src/router/index.js 中,使用了 routes 数组常量配置路由,主要是配置了各路径与视图组件的对应关系,所以,在数组中的各个元素值就是一个个的路由对象,每个路由对象至少要配置 pathcomponent 这 2 个属性。

提示:在路由对象中, name 属性不是必须的。

关于 component 属性,有 2 种配置方式,第 1 种是默认导入的,通常会在当前文件的顶部使用 import 语句导入并命名,然后,此 component 属性的值就是导入时取的名字,第 2 种是使用箭头函数 import 导入的,通常,在各项目中,只会有 1 个是默认导入的。

# 关于 router-view

.vue 文件中,可以添加 <router-view/> ,此标签本身是没有显示效果的,它表示 “此处将由另一个视图组件来完成显示,且,到底由哪个视图组件来显示,取决于路由配置与当前访问的 URL”。

# 嵌套路由

在开发实践中,必然存在某些页面是完全没有相同之处的,所以,通常,在 App.vue 的设计中,只保留一个 <router-view/> ,所以,具体的显示都由各个 .vue 文件来决定,默认并没有共同(复用)的部分!但是,也一定存在多个页面之间存在共同的部分,所以,在某个 .vue 中可能还需要再加一个 <router-view/> ,像这种本身显示在 App.vue 中的 <router-view/> 位置、自身内部也包含 <router-view/> 的,称之为 “嵌套路由”。

src/router/index.js 中,如果某个视图有 <router-view/> ,在配置时,应该通过 children 属性配置子级路由(被嵌套的那层路由),此 children 属性的写法与根级的 routes 完全相同,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const routes = [
{
path: '/home',
component: () => import('../views/HomeView.vue'),
children: [
{
path: '/brand-list',
component: () => import('../views/BrandListView.vue')
},
{
path: '/brand-add-new',
component: () => import('../views/BrandAddNewView.vue')
}
]
},

// 省略其它代码

}

一旦使用了嵌套路由,必须有某个 View 是不完整的(其内部有某个区域使用了 <router-view/> ,是由其它 View 来负责显示的),这样的 View 不应该能够被直接访问,所以,通常会配置上 redirect 属性,表示 “重定向” 的意思,一旦访问这个 View 对应的路径,就会自动跳转到重定向配置的路径上,例如:

1
2
3
4
5
6
7
const routes = [
{
path: '/sys-admin',
component: () => import('../views/HomeView.vue'),
redirect: '/sys-admin/index', // 重定向

// 其它代码

另外,在使用了嵌套路由时,通常,设计的子级路由中的 URL 会有共同的前缀,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const routes = [
{
path: '/sys-admin',
component: () => import('../views/HomeView.vue'),
redirect: '/sys-admin/index',
children: [
{
// 以下路径使用了 /sys-admin 作为前缀
path: '/sys-admin/temp/brand/list',
component: () => import('../views/sys-admin/temp/BrandListView.vue')
},
{
// 以下路径使用了 /sys-admin 作为前缀
path: '/sys-admin/temp/brand/add-new',
component: () => import('../views/sys-admin/temp/BrandAddNewView.vue')
},

则,在配置子级路径的 path 时,可以不使用 / 作为第 1 个字符,然后,配置值只需要写 /sys-admin 右侧的部分,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const routes = [
{
path: '/sys-admin',
component: () => import('../views/HomeView.vue'),
redirect: '/sys-admin/index',
children: [
{
// 实际路径是父级路由的path与当前path的组合:/sys-admin/temp/brand/list
path: 'temp/brand/list',
component: () => import('../views/sys-admin/temp/BrandListView.vue')
},
{
// 实际路径是父级路由的path与当前path的组合:/sys-admin/temp/brand/add-new
path: 'temp/brand/add-new',
component: () => import('../views/sys-admin/temp/BrandAddNewView.vue')
},

# 在 Vue CLI 中使用 Element UI

在终端中,需要先安装 Element UI(本质上是下载 Element UI 相关的文件到本项目的 node_modules 中)。

必须保证当前命令提示符是当前项目下(与执行 npm run serve 等命令的位置相同,必须保证当前位置下有 package.json 文件)!

安装的命令是:

1
npm i element-ui -S

注意:以上命令最后的 S 是大写的!

安装完成后,需要在 src/main.js 中进行配置:

1
2
3
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

在使用 Element UI 中的 <el-menu> 菜单时,可以在菜单上添加 router 属性,然后,各菜单项的 index 属性可配置为路径值,则点击菜单项时将跳转到此路径,例如:

1
2
3
4
5
6
7
8
9
10
11
12
<el-menu
router
default-active="2"
class="el-menu-vertical-demo"
background-color="#9ed3d7"
text-color="#fff"
active-text-color="#fff">
<el-menu-item index="/sys-admin/index">
<i class="el-icon-s-home"></i>
<span slot="title">首页</span>
</el-menu-item>
<!-- 剩余其它代码 -->

# 使用 Axios

在 Vue CLI 中,在使用 Axios 之前,需要先安装:

1
npm i axios -S

安装完成后,需要在 main.js 中添加配置:

1
2
import axios from 'axios';
Vue.prototype.axios = axios;

当使用 Axios 向其它远程服务器提交异步请求时,可能会出现 CORS 错误,即 “跨域” 的错误。

1
Access to XMLHttpRequest at 'http://localhost:8080/login' from origin 'http://localhost:8888' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

在 Spring MVC 项目中,当需要允许跨域访问时,需要在 Spring MVC 项目中自定义配置类,实现 WebMvcConfigurer 接口,重写其中的 addCorsMapping() 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedMethods("*")
.allowedOriginPatterns("*")
.maxAge(3600);
}

}

在 Vue CLI 项目中,当使用 Axios 时,需要使用 this 来引用 axios ,并且,在 then() 内部,只能使用箭头函数,不写使用匿名 function 函数,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
this.axios.post(url, this.ruleForm).then((response) => {
console.log('服务器端响应的结果:' + response);
console.log(response);
if (response.data == 1) {
console.log('登录成功');
this.$message({
message: '登录成功!',
type: 'success'
});
} else if (response.data == 2) {
console.log('登录失败,用户名错误!');
this.$notify.error({
title: '登录失败',
message: '用户名不存在!'
});
} else {
console.log('登录失败,密码错误!');
this.$notify.error({
title: '登录失败',
message: '密码错误!'
});
}
});