根据 B 站黑马程序员视频所撰写的笔记

Vue 基础

  1. JavaScript 框架
  2. 简化 Dom 操作
  3. 响应式数据驱动

提示:以下代码都要导入 Vue.js 文件

1
2
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>

el: 挂载点

Vue 会管理 el 选项命中的元素及其内部的后代元素,建议使 id 选择器,可以使用其他双标签,但不能使用 html 和 body

data: 数据对象

1
2
3
4
5
6
7
8
9
<div id="app">{{message}}</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: "Harris",
},
});
</script>

methods: 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<div id="app">
<button @click="sub">-</button>
<span> {{num}} </span>
<button @click="add">+</button>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
num: 1,
},
methods: {
sub() {
if (this.num <= 0) {
alert("不能再减了嗷!");
} else {
this.num--;
}
},
add() {
if (this.num >= 6) {
alert("我的好大,要忍一下!");
} else {
this.num++;
}
},
},
});
</script>

v-text

绑定显示文字,直接覆盖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<h2 v-text="name">Wong</h2>
<h2 v-text="girlfriend+'!'">blabla</h2>
<h2>{{ name +'+'}} Wong</h2>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
name: "Harris",
girlfriend: "Wendy",
},
});
</script>

v-html

绑定显示文字/渲染代码

用途:将字符串 String 里的 HTML 代码渲染成网页

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<p v-text="content"></p>
<p v-html="content"></p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
content: '<a href="https://blog.harriswong.top">Harris\'s Blog</a>',
},
});
</script>

注意:在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html永远不要用在用户提交的内容上。

v-on | @

为元素绑定事件,指令可去掉v-on简写为@

语法:@事件="方法([参数])"

文档传送门:https://cn.vuejs.org/v2/api/#v-on

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="app">
<input type="button" value="v-on指令" @click="doIt" />
<input type="button" value="v-on简写" @click="doIt" />
<input type="button" value="双击事件" @dblclick="doIt" />
</div>
<script>
var app = new Vue({
el: "#app",
methods: {
doIt() {
alert("RNM,退钱!!!");
},
},
});
</script>

v-show

组件的显隐效果,其原理是修改元素的样式 display,指令后的内容最终都会被解析为布尔值

用法:v-show内可写truefalse,也可以写表达式

场景:频繁切换的元素用 v-show

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<div id="app">
<input type="button" value="切换显示状态" @click="changeIsShow" /><br />
<img v-show="isShow" src="./img/monkey.gif" alt="" /><br />
<input type="button" value="增龄" @click="addAge" />
{{age}}
<input type="button" value="减龄" @click="subAge" />(18🈲)<br />
<img v-show="age>=18" src="https://www.baidu.com/favicon.ico" alt="" />
</div>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: false,
age: 16,
},
methods: {
changeIsShow() {
this.isShow = !this.isShow;
},
addAge() {
this.age++;
},
subAge() {
this.age--;
},
},
});
</script>

v-if

根据表达式的真假,切换元素有无效果,其原理是操纵 dom 元素

用法:和v-show一毛一样

场景:不频繁切换的元素用v-if

频繁操作 dom 对性能消耗比较大

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
<input type="button" value="切换显示" @click="toggleIsShow" />
<p v-if="isShow">Harris - v-if修饰</p>
<p v-show="isShow">Harris - v-show修饰</p>
<h2 v-if="want>=80">不会吧,不会吧,不会真的有人在看俺滴Vue笔记吧?</h2>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: false,
want: 100,
},
methods: {
toggleIsShow: function () {
this.isShow = !this.isShow;
},
},
});
</script>

v-bind | :

为元素绑定属性(比如 :src,:title,:class),指令可去掉v-bind简写为:

语法:v-bind:属性名=表达式👉:属性名=表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<style>
.active {
border: 1px solid red;
}
</style>
<div id="app">
<img v-bind:src="imgSrc" alt="" />
<br />
<img
:src="imgSrc"
alt=""
:title="imgTitle+'!!!'"
:class="isActive?'active':''"
@click="toggleActive"
/>
<br />
<img
:src="imgSrc"
alt=""
:title="imgTitle+'!!!'"
:class="{active:isActive}"
@click="toggleActive"
/>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
imgSrc: "http://www.itheima.com/images/logo.png",
imgTitle: "Harris",
isActive: false,
},
methods: {
toggleActive: function () {
this.isActive = !this.isActive;
},
},
});
</script>

v-for

根据数据生成列表结构

语法:(item,index) in 数组

场景:数组经常和v-for结合使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div id="app">
<input type="button" value="添加数据" @click="add" />
<input type="button" value="移除数据" @click="remove" />
<ul>
<li v-for="(it,index) in people">{{ index+1 }}派对成员: {{ it }}</li>
</ul>
<h2 v-for="item in art" v-bind:title="item.name">{{ item.name }}</h2>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
people: ["Harris", "Wendy", "Sharon"],
art: [{ name: "krump" }, { name: "rap" }],
},
methods: {
add: function () {
this.art.push({ name: "rap" });
},
remove: function () {
this.art.shift();
},
},
});
</script>

v-model

获取和设置表单元素的值(双向数据绑定),绑定的数据会和表单元素值相关联

双向数据绑定可以实现数据双向更改,而不是只能 data 里数据改{{}}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<input type="button" value="修改name" @click="setN" />
<input type="text" v-model="name" @keyup.enter="getN" />
<h2>{{ name }}</h2>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
name: "Harris",
},
methods: {
getN() {
alert(this.name);
},
setN() {
this.name = "Wendy";
},
},
});
</script>

父组件传值给子组件

父传子主要通过在父组件 v-bind 绑定数据,在子组件进行用props进行数据的接收

父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div id="container">
<Child :msg="data"></Child>
</div>
</template>
<script>
import Child from "@/components/Child";
export default {
data() {
return {
data: "父组件的值",
};
},
methods: {},
components: {
Child,
},
};
</script>

子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div id="container">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
data() {
return {};
},
props: ["msg"],
};
</script>

网络应用

axios

功能强大的网络请求库

导入 html:写入<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

导入 vue3.x:运行npm i axios -S,在<script>里写入import axios from 'axios';

语法:

  • get 请求:axios.get(网址?key=value&key2=value1).then(function(response){},function(err){})

  • post 请求:axios.post(网址,{key:value,key2:value1}).then(function(response){},function(err){})

Get和Post的区别是什么?
  1. Get 是不安全的,因为在传输过程,数据被放在请求的 URL 中;Post 的所有操作对用户来说都是不可见的。
  2. Get 传送的数据量较小,这主要是因为受 URL 长度限制;Post 传送的数据量较大,一般被默认为不受限制。
  3. Get 限制 Form 表单的数据集的值必须为 ASCII 字符;而 Post 支持整个 ISO10646 字符集。
  4. Get 执行效率却比 Post 方法好。Get 是 form 提交的默认方法。

文档传送门:https://github.com/axios/axios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<input type="button" value="get请求" class="get" />
<input type="button" value="post请求" class="post" />
<script>
/*
接口1:随机笑话
请求地址:https://autumnfish.cn/api/joke/list
请求方法:get
请求参数:num(笑话条数,数字)
响应内容:随机笑话
*/
document.querySelector(".get").onclick = function () {
axios
.get("https://autumnfish.cn/api/joke/list?num=6")
// axios.get("https://autumnfish.cn/api/joke/list1234?num=6")
.then(
function (response) {
console.log(response);
},
function (err) {
console.log(err);
}
);
};
/*
接口2:用户注册
请求地址:https://autumnfish.cn/api/user/reg
请求方法:post
请求参数:username(用户名,字符串)
响应内容:注册成功或失败
*/
document.querySelector(".post").onclick = function () {
axios
.post("https://autumnfish.cn/api/user/reg", { username: "盐焗西兰花" })
.then(
function (response) {
console.log(response);
console.log(this.skill);
},
function (err) {
console.log(err);
}
);
};
</script>

ES6

什么是 ES6?

ECMAScript 6(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。Mozilla 公司将在这个标准的基础上,推出 JavaScript 2.0。ECMA Script,JavaScript 的语言标准。

优点:

提升 JS 编写大型的复杂应用程序的能力(这次升级加入了模块化的概念、细化和优化语法、封装了一些方法)

缺点:

对浏览器存在兼容性问题,可以使用 Bable:ES6->ES5(转换器)

let

和 var 关键字的用法基本一致,没有变量提升,建议用 let

变量提升就好比你先使用变量后定义,编译时会自动将变量定义那段代码上移

模板字符串

使用``包裹文本,在需要替换的位置使用${}占位,并填入内容即可

对象简化赋值

如果属性名和变量名相同,可以简写,方法可以省略 function 关键字

1
// 简写前 params:{ id:id } // 简写后 params:{ id }

箭头函数

function 省略掉,替换为 =>

参数只有一个时,可以省略 ()

函数体只有一行时,可以省略 {}

函数体只有一行,并且有返回值时,如果省略了{},必须省略 return

箭头函数的 this

创建时的 this 是谁,运行的时候 this 就是谁


单文件组件

后缀名是 .vue ,可以同时编写结构,逻辑和样式

template 标签中写结构,例如div

script 标签中写逻辑

style 标签中写样式


快速原型开发

环境配置

安装 Node.js 全部使用默认的设置,一路下一步即可

打开命令行工具,输入命令 node –v 以及 npm -v 检查是否安装成功

通过命令 npm install -g @vue/cli-service-global 安装一个小工具

基本使用

保证 环境配置 成功之后,在 .vue 文件所在的路径下打开终端 输入 vue serve <FileName>,等待解析,然后在浏览器访问出现的 地址 即可

注意:

  1. template 中必须有一个根节点,比如div

  2. script 中的 data 写成函数,内部返回一个对象

  3. 如果要使用写好的样式,直接 import 即可


vue-cli(脚手架)

帮你创建项目基本结构的工具,帮你整合了很多东西,我们不在需要自己一步一步的搭建这些了。

环境配置

保证 Node.js 安装成功的情况下,通过命令npm install -g @vue/cli安装一个小工具

如果失败了:

先输入npm install -g cnpm安装一个镜像下载工具(cnpm)

成功之后再输入cnpm install -g @vue/cli通过刚刚安装的工具 来安装 vue-cli

项目创建及运行

在想要创建项目的文件夹下输入 vue create 项目名,调整一下设置,然后回车。如果成功了,依次输入最后出现的 提示代码,稍等片刻,在浏览器中输入出现的 地址 即可访问。

如果有写好的项目,然后输入npm run serve命令运行即可

文件结构

public:内含网站 icon 图标,页面模板 index

src:用来放网站绝大多数资源

  • assets:静态资源,如:图片,CSS 文件
  • componets:页面组件
  • App.vue:顶级页面组件

vue-router

管理多个组件切换关系,用它可以做 SPA(Single Page Application 单页面应用)

安装

在项目的 根目录 打开终端,通过命令npm install vue-router下载

用法:在main.js

  1. 导入

  2. use 一下

  3. 创建路由

  4. 挂载到 Vue 实例上

1
2
3
4
import VueRouter from 'vue-router' Vue.use(VueRouter) import XXX from
'./XXX/XXX.vue' const router = new VueRouter({ routes: [ { path: '/XXX',
component: XXX }, ] }) new Vue({ render: h => h(App), // 挂载到Vue示例上 router
}).$mount('#app')

配置规则

通过routes属性配置地址和路由管理的组件关系

  1. 导入组件

  2. routes 属性中进行配置关系

  3. path:设置地址

  4. component:设置组件

  5. 可以配置多个

路由出口

希望匹配到的组件显示在哪里,就在哪里设置一个router-view标签

形如:<router-view></router-view>

声明式导航

通过 router-link 标签设置to属性为地址 可以实现点击切换

形如:<router-link to="/XXX"></router-link>

编程式导航

组件中通过this.$router.push(地址)可以通过代码实现切换,还可以this.$router.replace(地址)表示页面不可返回

也可以直接@click="$router.push('/XXX')"

路由传参

在地址的后面 写上?分隔

通过key=val1&key2=val2的方式添加参数

组件中通过 this.$route.query 访问对应的 key 即可获取数据


Element-UI (Vue 3.x)

饿了么前端推出的 Vue 组件库,很多常用的功能已经写好了,可直接用。Element-UI 官方文档

安装

  1. 在项目的 根目录 打开终端,通过命令下载npm install element-plus --save

  2. 更改main.js文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import { createApp } from "vue";
    import App from "./App.vue";
    import router from "./router";
    import store from "./store";

    // Element-UI
    import ElementPlus from "element-plus";
    import "element-plus/dist/index.css";

    createApp(App).use(store).use(router).use(ElementPlus).mount("#app");

其它命令,自行尝试,一般以上配置即可

vue add element-plus

cnpm install vue-cli-plugin-element-plus

介绍

  • el-container:构建整个⻚⾯框架。

  • el-aside:构建左侧菜单。

  • el-menu:左侧菜单内容,常⽤属性:

    :default-openeds:默认展开的菜单,通过菜单的 index 值来关联。

    :default-active:默认选中的菜单,通过菜单的 index 值来关联。

  • el-submenu:可展开的菜单,常⽤属性:

    index:菜单的下标,⽂本类型,不能是数值类型。

  • template:对应 el-submenu 的菜单名。

  • i:设置菜单图标,通过 class 属性实则。

    • el-icon-message
    • el-icon-menu
    • el-icon-setting
  • el-menu-item:菜单的⼦节点,不可再展开,常⽤属性:

    index:菜单的下标,⽂本类型,不能是数值类型。

表单数据校验

定义 rules 对象,在 rules 对象中设置表单各个选项的校验规则

1
2
rules: { name: [ { required: true, message: 'error', trigger: 'blur' }, { min:
3, max: 5, message: '⻓度在 3 到 5 个字符', trigger: 'blur' } ] }

required:'true', 是否为必填项

message:'error', 提示信息

trigger:'blur',触发事件


部署网站

GitHub

  1. 在 GitHub 上新建一个仓库

  2. 在<Root>下运行 cmd 并输入以下命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    git init  #初始化
    git add . #上传所有文件
    git commit -m "<Custom>" #提交时的注释,例如:"update"
    git remote add origin <RepoGit> #连接你仓库的Git地址,使Git Bash知道代码要上传至哪个仓库
    git branch -M <BranchName> #将默认master分支名改为你自己设置的,这里推荐分支名为"source"
    #若第一次提交要加上"-u"
    git push -u origin <BranchName>
    #若提交失败,显示:error: failed to push some refs to,则加上"-f"来强制提交
    git push [-u] origin <BranchName> -f

    若显示fatal: unable to access ...,只是网络问题,多提交几次

  3. 再输入npm run build打包 Vue 项目,此时项目目录下会多出一个dist目录

  4. Git 三连将 dist 推送到远程仓库(默认为 master 分支)

    通常 dist 目录会被 git 忽略,需要将 dist 从忽略文件.gitignore中删除,然后将 dist 目录推送到远程仓库

  5. 输入git subtree push --prefix dist origin gh-pagesdist目录推送到远程的gh-pages分支。(若远程没有gh-pages分支则会新建gh-pages分支然后再推送)

    备注:此处只能是gh-pages分支,才能使用GitHub pages功能

  6. 登录远程 GitHub 仓库,通过setting -> Pages -> Sourcegh-pages设置为GitHub pagessource

  7. 可以直接访问链接看网站了

注意:网站每次更新后,需要执行npm run build命令,再上传到仓库

Vercel

使用背景:

静态站点完成以后,需要部署到线上,如果使用传统的部署方式,每次代码更新都需要在本地重新打包构建,然后替换服务器上的代码包,这种方式对于更新不频繁的站点是可取的。一旦站点更新的频繁,这种方式就很繁琐,很费人力。这里采用Vercel + GitHub方式部署。

优势:

Vercel + GitHub部署,一旦GitHub上的代码更新了,会自动触发Vercel重新打包构建,从而保证线上线下功能同步,大大地简化部署流程。

  1. 确保已将本地代码上传到github仓库。
  2. 登录 Vercel 账号 👉 导入 GitHub 仓库 👉 点击部署等等一系列无脑操作,即可访问了

问题合集

记录了一些报错等等五花八门的问题

  1. 更改端口号(3.x)

    1. 在项目根目录新建文件vue.config.js

    2. 输入以下代码:

      1
      2
      3
      4
      5
      module.exports = {
      devServer: {
      port: 8080, // 启动端口号
      },
      };

    其中port为端口号,可自定义改

  2. Vue 版本更新

    先卸载 vue:npm uninstall vue-cli -g

    如果卸载不了就:where vue,通过文件路径将其手动删除

    再安装:cnpm install -g @vue/cli

  3. img 标签动态绑定 src 不显示本地图片

    用将图片路径放入require()中。

    1
    2
    3
    4
    5
    6
    7
    export default {
    data() {
    return {
    avatar: require(<img—src>),
    };
    },
    }

报错合集

  1. Module not found: Error: Can't resolve 'sass-loader'

    1
    2
    npm install sass-loader -D
    npm install node-sass -D

    sass-loader 的作用

    加载 SASS / SCSS 文件并将其编译为 CSS。

    使用 css-loader 或 raw-loader 将其转换为 JS 模块,然后使用 ExtractTextPlugin 将其提取到单独的文件中。

    node-sass 的作用

    用于 webpack 的节点加载项

    sass-loader 及 node-sass 的详细介绍情查看官方的中文文档,如下是其对应的官网地址。

  2. 访问图片 403 报错

在 HTML 代码的 head 中添加一句<meta name="referrer" content="no-referrer" />即可

原理分析

http 请求体的 header 中有一个 referrer 字段,用来表示发起 http 请求的源地址信息,这个 referrer 信息是可以省略但是不可修改的,就是说你只能设置是否带上这个 referrer 信息,不能定制 referrer 里面的值。

服务器端在拿到这个 referrer 值后就可以进行相关的处理,比如图片资源,可以通过 referrer 值判断请求是否来自本站,若不是则返回 403 或者重定向返回其他信息,从而实现图片的防盗链。上面出现 403 就是因为,请求的是别人服务器上的资源,但把自己的 referrer 信息带过去了,被对方服务器拦截返回了 403。

在前端可以通过 meta 来设置 referrer policy(来源策略),具体可以设置哪些值以及对应的结果参考这里。所以针对上面的 403 情况的解决方法,就是把 referrer 设置成no-referrer,这样发送请求不会带上 referrer 信息,对方服务器也就无法拦截了。

浏览器中 referrer 默认的值是no-referrer-when-downgrade,就是除了降级请求的情况以外都会带上 referrer 信息。降级请求是指 https 协议的地址去请求 http 协议,所以上面 403 的情况还有另一种解决方法就是,请求的图片地址换成 http 协议,自己的地址使用 http 协议,这样降级请求也不会带上 referrer。


技巧合集

可参考以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
html,
body {
margin: 0;
padding: 0;
}
#content {
margin: 100px auto;
padding: 25px;
width: 1330px;
min-height: calc(100vh - 300px);
}
#footer {
width: 100%;
height: 100px; /*脚部的高度*/
background: #eee;
clear: both; /*清除浮动*/
}

大概可以参考以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div v-for="link in links">
<router-link :to="link.address"> {{link.name}} </router-link>
</div>
</template>

<script>
export default {
data: () => ({
links: [
{
name: "首页",
address: "/",
},
{
name: "关于我们",
address: "/about",
},
],
}),
};
</script>

配置 404 页面

打开index.js文件,也就是配置路由的 JS 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Vue from "vue";
import Router from "vue-router";
import notfount from "@/components/404";
Vue.use(Router);

export default new Router({
routes: [
{
path: "*",
name: "404页面",
component: notfount,
},
],
});

或者(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);

const routes = [
{
path: "*",
name: "404页面丢失",
component: () => import("@/components/404"),
},
];

const router = new VueRouter({
routes,
});

如果是 Vue3.x 版本,则将path: "*"写成path: "/:pathMatch(.*)*"

解决跨域问题

  1. 更改/新建vue.config.js文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    module.exports = {
    devServer: {
    port: 8060, // 启动端口号
    proxy: {
    //设置代理,必须填
    "/api": {
    //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定
    target: "http://localhost:8888", //代理的目标地址
    changeOrigin: true, //是否设置同源,输入是的
    pathRewrite: {
    //路径重写
    "/api": "", //选择忽略拦截器里面的单词
    },
    },
    },
    },
    };
  2. 新建<Root>/src/utils/request.js文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import axios from "axios";

    const request = axios.create({
    baseURL: "/api", // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
    timeout: 5000,
    });

    // request 拦截器
    // 可以自请求发送前对请求做一些处理
    // 比如统一加token,对请求参数统一加密
    request.interceptors.request.use(
    (config) => {
    config.headers["Content-Type"] = "application/json;charset=utf-8";

    // config.headers['token'] = user.token; // 设置请求头
    return config;
    },
    (error) => {
    return Promise.reject(error);
    }
    );

    // response 拦截器
    // 可以在接口响应后统一处理结果
    request.interceptors.response.use(
    (response) => {
    let res = response.data;
    // 如果是返回的文件
    if (response.config.responseType === "blob") {
    return res;
    }
    // 兼容服务端返回的字符串数据
    if (typeof res === "string") {
    res = res ? JSON.parse(res) : res;
    }
    return res;
    },
    (error) => {
    console.log("err" + error); // for debug
    return Promise.reject(error);
    }
    );

    export default request;

设置每个页面的 Title

  1. src\router\index.js文件中添加:

    1
    2
    3
    4
    5
    6
    7
    const routes = [
    {
    path: "/login",
    name: "登录",
    component: () => import("../views/Login.vue"),
    },
    ];
  2. src\main.js文件中添加:

    1
    2
    3
    4
    5
    6
    7
    router.beforeEach((to, from, next) => {
    /* 路由发生变化修改页面title */
    if (to.name) {
    document.title = to.name + " | <Custom>";
    }
    next();
    });

Swiper 轮播图

鉴于 Element-Plus 里的走马灯 Carousel 组件渲染图片速度太慢,于是我选择用Swiper

可参考如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<template>
<!-- 导航栏 -->
<Header />
<div class="home">
<!-- 首页轮播图 Swiper -->
<div class="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="img in imgs">
<img :src="img.imgsrc" alt />
</div>
</div>
</div>
<!-- 分页器 Pagination -->
<div class="swiper-pagination"></div>
</template>

<script>
import request from "@/utils/request";
import Swiper from "../static/js/swiper-bundle.min.js"
export default {
name: "Home",
data() {
return {
imgs: {},
}
},
methods: {
showRotationMap() {
request.get('/rm').then(res => {
this.imgs = res.data
})
},
// 首页轮播图 Swiper
showSwiper() {
var swiper = new Swiper('.swiper', {
autoplay: true,
delay: 3000,
width: window.innerWidth,
direction: 'vertical',
grabCursor: true,
pagination: {
el: '.swiper-pagination',
},
});
},
},
created() {
this.showRotationMap()
},
mounted() {
this.showSwiper()
},
}
</script>

<style scoped>
/* 引入swipercss */
@import url("../../node_modules/swiper/swiper-bundle.css");
.swiper {
height: 510px;
overflow: hidden;
}
.swiper img {
object-fit: cover;
}
</style>

Echarts 插件

  1. 导入组件

    cnpm install --save echarts

  2. 单文件导入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    <template>
    <!-- 默认宽高为0,故需要设置 -->
    <div ref="mychart" id="echarts" />
    </template>

    <script>
    // 1.引用echarts
    import * as echarts from "echarts";
    export default {
    mounted() {
    // 2.初始化
    let myEcharts = echarts.init(this.$refs.mychart);
    // 3.设置数据
    let xData = ["2021", "2022", "2023"];
    let yData = [400, 600, 500];
    // 4.设置配置项
    let option = {
    title: {
    //标题
    text: "主标题",
    },
    xAxis: {
    //横坐标
    data: xData,
    },
    yAxis: {
    //纵坐标
    },
    series: [
    //系列 配置图表类型
    {
    name: "销量",
    type: "bar", //系列类名
    data: yData,
    },
    ],
    };
    // 5.设置图表、绘制图表
    myEcharts.setOption(option);
    },
    };
    </script>

    <style scoped>
    #echarts {
    height: 400px;
    width: 600px;
    }
    </style>

返回上一页面 | 刷新页面

1
this.$router.go(-1); this.$router.go(0);

参考资料

文档:

视频: