一、vue

Vue 是一套用于构建用户界面的渐进式框架

vue 是一款友好的,多途径且高性能的 JavaScript 框架,可维护和测试更强的代码

Vue.js 是一个轻巧、高性能、可组件化的 MVVM 库,同时拥有非常容易上手的 API

二、MVVM 模式

MVVM 是 Model-View-ViewModel 的简写。它本质上就是 MVC 的改进版。MVVM 就是将其中的 View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开

MVVM 模式和 MVC 模式一样,主要目的是分离视图(View)和模型(Model)

MVVM 是前端视图层的分层开发思想,主要是把每个页面,分成了 M , V 和 VM

其中,VM 是 MVVM 思想核心;

因为 VM 是 M 和 V 之间的调度者

MVVM 模式是视图和模型的双向数据绑定,通过 ViewModel 实现。

当 View 发生变化,Model 变化;当 Model 变化,View 也相应的变化

三、开始

引入 Vue

1
2
3
4
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 或者生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

页面显示 Hello world

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello world</title>
<!--引入js包-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<!--表示view-->
<div id="app">{{msg}}</div>
</body>
<script type="text/javascript">
// 创建vue对象
var vm = new Vue({
// el:表示vue里面的固定语法,使用vue接管上面的区域
el: '#app',
// data:用于定义模型,固定的语法,data表示数据
data: {
// msg:表示变量 String msg= "Hello world";
msg: 'Hello world',
},
})
</script>
</html>

插值表达式

数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值,Mustache 标签将会被替代为对应数据对象上属性的值。无论何时,绑定的数据对象上属性发生了改变,插值处的内容都会更新。

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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
<!-- {{}} :用来显示数据(View) -->
<p>{{msg1}}</p>
<p>{{msg2}}</p>
<p>{{msg + 10}}</p>
<p>{{msg>5?"大于5的数字":"小于5的数字"}}</p>
</div>
</body>
<script type="text/javascript">
new Vue({
el: '#app',
// data用来定义模型(Model)
data: {
// json语法
msg1: 'Hello world',
msg2: 'Hello Vue',
msg: 10,
},
})
</script>
</html>

最后 ViewModel (VM) 用来将模型 (Model) 的数据显示到视图 (View)上。

四、VueJS 常用系统指令

  • v-on:监听 DOM 事件,并在触发时运行一些 JavaScript 代码

  • v-text 与 v-html:v-text 输出文本内容,不会解析 html 元素;v-html:输出文本内容,会解析 html 元素

  • v-bind:为元素绑定属性

  • v-model:实现表单元素和数据的双向绑定。监听用户的输入,然后更新数据

  • v-for:遍历循环数据

  • v-if 与 v-show:判断展示

v-on

v-on(等同于@)

v-on:click(等同于@click)

测试:点击按钮事件,改变 message 的值

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
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-on:click单击事件</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
{{message}}
<br />
<!-- 等同于<button @click="funMsg('Hello Vue')">点我</button> -->
<button v-on:click="funMsg('Hello Vue')">点我</button>
</div>
</body>

<script>
//view model
var vm = new Vue({
el: '#app',
data: {
message: 'Hello world', //model表示模型,封装数据
},
methods: {
funMsg: function (msg) {
// this代表的是vue对象,或者使用vm
// vm.message = msg;
this.message = msg
},
},
})
</script>
</html>

v-text 与 v-html

测试输出带有<h1>标签的文本内容

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-text与v-html</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<!-- 输出文本内容,不会解析html元素 -->
<div v-text="message"></div>
<!-- 输出文本内容,会解析html元素 -->
<div v-html="message"></div>
</div>
</body>
<script>
//view model
new Vue({
el: '#app',
data: {
message: '<h1>Hello world</h1>', //model
},
})
</script>
</html>

v-bind

插值语法不能作用在 HTML 属性上,遇到这种情况应该使用 v-bind 指令

v-bind 指令主要用于属性绑定,比方你的 class 属性,style 属性,value 属性,href 属性等等,只要是属性,就可以用 v-bind 指令进行绑定。

完整的写法是 v-bind:属性名

1
<a v-bind:href="url"></a>

简写的话可以直接省略 v-bind,只保留:属性名

1
<a :href="url"></a>

测试输出带有不同格式的文本内容

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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-bind</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--自定义样式-->
<style>
.color {
color: blue;
}

.size {
font-size: 30px;
}
</style>
</head>

<body>
<div id="app">
<p>Hello</p>
<!--字体变大-->
<p class="color size">Vue</p>

<!--字体变蓝-->
<p :class="{color:isBlue,size:isSize}">Hello world</p>

<!-- 在数组中使用三元表达式 -->
<!--字体变大-->
<p :class="[ok ? 'color' : 'size']">Hello</p>

<!-- 直接传递一个数组,注意: 这里的 class 需要使用 v-bind 做属性绑定 -->
<!-- 颜色蓝色,字体变大 -->
<p :class="[showColor,'size']">Hello Vue</p>

<!-- 百度的超链接 -->
<a :href="url">百度</a>
</div>
</body>

<script>
var vm = new Vue({
el: '#app',
data: {
isBlue: true,
isSize: false,
ok: false,
showColor: 'color',
url: 'https://www.baidu.com',
},
})
</script>
</html>

v-model

v-model 指令来实现表单元素和数据的双向绑定。监听用户的输入,然后更新数据。

v-model 本质上是个语法糖,其实现原理包含两个步骤

  1. 通过 v-bind 绑定一个 value 属性
  2. 通过 v-on 指令给当前元素绑定事件

测试:

  • 改变输入框的值,同时模型的数据发生改变
  • 改变 json 数据,同时输入框的内容也发生改变
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
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>v-model</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
<!-- 改变输入框的值,同时模型的数据发生改变 -->
<p>
<label>用户名:</label>{{username}}<br />
<input type="text" v-model="username" />
<input type="button" value="默认" v-on:click="fnChange" />
</p>

<!-- 改变json数据,验证同时输入框的内容也发生改变 -->

<!-- 测试单选框 -->
<br />
<input type="checkbox" v-model="danCheck" />同意用户协议<br />
<h1>{{danCheck}}</h1>

<!-- 测试复选框 -->
<br />
<input type="checkbox" value="西瓜" v-model="duoCheck" />西瓜
<input type="checkbox" value="苹果" v-model="duoCheck" />苹果
<input type="checkbox" value="黄瓜" v-model="duoCheck" />黄瓜
<h1>{{duoCheck}}</h1>
</div>
</body>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
username: '',
danCheck: true,
duoCheck: [],
},
methods: {
fnChange: function () {
this.username = 'admin'
},
},
})
</script>
</html>

v-for

1、循环普通数组

遍历 array 集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-for:普通数组</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
<p v-for="(item, i) in list">索引:{{i}} ---> 值:{{item}}</p>
</div>

<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
list: [1, 2, 3, 4, 5, 6],
},
})
</script>
</body>
</html>

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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-for:对象数组</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
<p v-for="(user, i) in list">
Id:{{ user.id }} ---> 名字:{{ user.name }} ---> 索引:{{i}}
</p>
</div>

<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
{ id: 3, name: '王五' },
{ id: 4, name: '赵六' },
],
},
})
</script>
</body>
</html>

3、循环对象

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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-for:循环对象</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
<!-- 注意:在遍历对象身上的键值对的时候, 除了有 val 和 key,在第三个位置还有一个索引 -->
<p v-for="(val, key, i) in user">
键是: {{key}} --- 值是: {{ val }} -- 索引是: {{i}}
</p>
<br />
<p v-for="(val, key) in user2">键是: {{key}} --- 值是: {{ val }}</p>
</div>

<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
user: {
id: 1,
name: '张三',
age: 18,
},
user2: {
id: 2,
name: '李四',
age: 25,
},
},
})
</script>
</body>
</html>

4、迭代数字

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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-for:迭代数字</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
<!-- in 后面除了可以放普通数组,对象数组,对象,还可以放数字 -->
<!-- 注意:如果使用 v-for 迭代数字的话,前面的 count 值从 1 开始 -->
<p v-for="count in 10">这是第 {{ count }} 次循环</p>
</div>

<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {},
})
</script>
</body>
</html>

5、for 循环中 key 的使用

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
<!DOCTYPE html>
<html xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>for循环中key的使用</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
<div id="app">
<div>
<!-- <label>用于为输入控件定义文本标签(label)——即显示在输入控件旁边的说明性文字 -->
<label
>Id:
<input type="text" v-model="id" />
</label>

<label
>Name:
<input type="text" v-model="name" />
</label>

<input type="button" value="添加" @click="add" />
</div>

<!-- 注意: v-for 循环的时候,key 属性只能使用 number获取string -->
<!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 -->
<!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须在使用 v-for 的同时,指定唯一的 字符串/数字类型 v-bind:key 值 -->
<!-- 这里指定唯一的key值为list中的id -->
<p v-for="item in list" :key="item.id">{{item.id}} ---> {{item.name}}</p>
</div>

<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
list: [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
{ id: 3, name: '王五' },
{ id: 4, name: '赵六' },
{ id: 5, name: '钱七' },
],
},
methods: {
add() {
// 添加方法
//unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
this.list.unshift({ id: this.id, name: this.name })
},
},
})
</script>
</body>
</html>

v-if 与 v-show

v-if 是根据表达式的值来决定是否渲染元素,即 v-if 只有当判断条件为真时,浏览器才会生成标签并在浏览中渲染,反之判断条件为假时,浏览器将不会生成标签更不会渲染

v-show 是根据表达式的值来切换元素的 display css 属性,浏览器会生成标签并在浏览中渲染,条件为真的时候内联样式 display:block;条件为假的时候内联样式更改为 display:none;

使用 vue 赋值 flag 变量(boolean 类型),用来判断元素中的内容是否显示

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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-if与v-show</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<!-- v-if 的特点:每次都会重新删除或创建元素 -->
<!-- v-show 的特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式 -->
<body>
<div id="app">
<p v-if="flag">这是使用了v-if的p标签</p>
<p v-else>这是使用了v-else的p标签</p>

<!-- 当flag为false时浏览器元素:<p style="display: none;">这是使用v-show的p标签</p> -->
<p v-show="flag">这是使用v-show的p标签</p>

<div v-if="code=='A'">A</div>

<div v-else-if="code=='B'">B</div>
<div v-else-if="code=='C'">C</div>
<div v-else>结果不属于A、B、C!</div>
</div>
</body>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
flag: true,
code: 'D',
},
})
</script>
</html>

五、Vue 生命周期

什么叫生命周期?

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 、并在数据变化时更新 DOM 等

什么叫钩子函数?

同时在生命周期执行的这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会

比如 created 钩子可以用来在一个 Vue 实例被创建之后执行代码,例如 ajax 可以在 created 钩子函数下运行,使用 ajax 对页面数据初始化

vue 在生命周期中有这些钩子函数:

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

六、axios

1、什么是 axios?

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中

axios 的 github:https://github.com/axios/axios

2、引入 axios

1
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>