banner
NEWS LETTER

Vue基础

Scroll down

Vue基础

学习目标

  • 了解:vue概述(第一章)
  • 掌握:Vue快速入门(第二章)
  • 掌握:Vue常用指令(第三章)
  • 了解:Vue生命周期(第四章)
  • 掌握:Vue的ajax的使用(第五章)

第一章 Vue概述

1.1 Vue介绍

  • Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!
  • Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
  • 前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道,来制作前端页面效果;

官网:https://cn.vuejs.org/

VueJS是前端渐进式框架,让HTML和JavaScript无缝的整合,实现了视图和模型的双向数据绑定(MVVM)

渐进式框架:可以先使用vue的基础功能,然后在此基础上逐渐使用你所需要的其他的功能

1.2 MVVM模式

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

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

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

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

​ Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

​ MVVM模式是视图和模型的双向数据绑定,通过ViewModel实现,当View发生变化,Model变化;当Model变化,View也相应的变化。

第二章 Vue快速入门

2.1 快速入门

  1. 创建工程
  2. 导入vue.js
  3. 编写入门程序(Vue实例)
  4. 插值表达式

【需求】:使用vue,对 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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>快速入门</title>
</head>
<body>
<!-- 将来 new 的Vue实例,会控制这个元素中的所有内容 -->
<!-- Vue 实例所控制的这个元素区域,就是我们的 V -->
<div id="app">
<p>{{ message }}</p>
</div>

<!-- 1. 导入Vue的js文件-->
<script src="./js/vue.js"></script>
<script>
// 2. 创建一个Vue的实例
// 当我们导入包之后,在浏览器的内存中,就多了一个 Vue 构造函数
// 注意:我们 new 出来的这个 vm 对象,就是我们 MVVM中的 VM调度者
var vm = new Vue({
el: '#app', // 表示,当前我们 new 的这个 Vue 实例,要控制页面上的哪个区域
// 这里的 data 就是 MVVM中的 M,专门用来保存每个页面的数据
data: { // data 属性中,存放的是 el 中要用到的数据
message: '欢迎学习Vue' // 通过 Vue 提供的指令,很方便的就能把数据渲染到页面上
}
})
</script>
</body>
</html>

2.2 插值表达式

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

​ Vue.js 都提供了完全的 JavaScript 表达式支持。

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 lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>插值表达式</title>
</head>

<body>
<div id="app">
{{ message }} <br>
{{ message1 }} <br>
{{ message1 + 10 + 100 }} <br>
{{ message1 > 5 ? "大于5的数" : "小于5的数" }}
</div>
<script src="./js/vue.js"></script>
<script>
var vue = new Vue({
el: "#app",
data:{
message: "hello vue",
message1: 10
},
methods:{ // 声明函数,绑定页面的事件
}
})
// 改变模型的数据,测试视图是否发生变化
vue.message = "hello Kevin"
</script>
</body>
</html>

​ 这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

1
2
3
4
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

2.3 小结

​ Vue的使用其实很简单,只需要导入1个js,定义1个Vue实例,写3个属性(el,data,methods),写1个插值表达式输出结果,即可实现效果。

  • data:用来定义模型(Model)
  • {{}}:用来显示数据(View)
  • ViewModel:用来将模型的数据显示到视图上

第三章 Vue常用指令

​ 指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

3.1 v-on(缩写@)

​ 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

3.1.1 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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>v-on:click单击事件</title>
</head>
<body>
<div id="app">
{{ message }}
<!--<button v-on:click="fun('good')">改变</button>-->
<button @click="fun('good')">改变</button>
</div>
<script src="js/vue.js"></script>
<script>
//view model
var vm = new Vue({
el: "#app",
data:{
message: "hello world" // model表示模型,封装数据
},
methods:{
fun(msg) {
// this代表的是vue对象,或者使用vm
this.message = msg;
}
}
});
</script>
</body>
</html>

3.1.2 v-on:keydown

表示键盘按下事件。

xxxxxxxxxx :smile: :heart: :+1:text

KeyCode对照

【需求】:对文本输入框做校验,使用键盘按下事件,如果按下0-9的数字,正常显示,其他按键则阻止事件执行。

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 lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>v-on:keydown</title>
</head>
<body>
<div id="app">
<input type="text" v-on:keydown="fun($event)">
<!-- <input type="text" @keydown="fun($event)" /> -->
</div>
<script src="js/vuej.js"></script>
<script>
//view model
new Vue({
el: "#app",
data: {
message: 10 //model
},
methods: {
fun(e) {
// 1. 捕获keyCode 判断它是否是0-9 需要使用event对象
var keyCode = e.keyCode;
// 只能输入数字
if(!(keyCode >= 48 && keyCode <= 57)) {
//2.阻止默认行为执行
e.preventDefault();
}
}
}
});
</script>
</body>
</html>

3.1.3 v-on:mouseover

鼠标移入区域事件

【需求1】:给指定区域大小的div中添加样式,鼠标移到div中,弹出窗口。

【需求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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.father{
width: 500px;
height: 500px;
background: red;
}
.son{
width: 300px;
height: 300px;
background: blue;
}
</style>
</head>
<body>

<div id="app">
<div class="father" @mouseover="father()">

<div class="son" @mouseover="son()"></div>
</div>
</div>
<script src="vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
methods: {
father(){
alert('father');
},
son(){
alert('son');
}
}
})

</script>
</body>
</html>

3.2 v-text与v-html

使用{{}}可以输出文本的值。

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

v-html:输出文本内容,会解析html元素

【需求】:使用message属性赋值,查看页面输出内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>v-text与v-html</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-text="message"></div>
<div v-html="message"></div>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
message: "<h1>hello world</h1>"
}
});
</script>
</html>

3.3 v-bind(缩写 :)

插值语法不能作用在 HTML 属性上,遇到这种情况应该使用 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
40
41
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.red{
color: red;
}
.big{
font-size: 30px;
}
</style>
</head>
<body>
<div id="app">
<p>百度</p>
<p class="red big">百度</p>
<p v-bind:class="{red:isRed, big:isBig}">百度</p>
<!-- 在数组中使用三元表达式 -->
<p :class="[ok ? 'red' : '', 'big']">百度</p>
<!-- 直接传递一个数组,注意: 这里的 class 需要使用 v-bind 做数据绑定 -->
<p :class="[showred, 'big']">百度</p>
<a :href="url">百度</a>
</div>
<script src="./js/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data:{
isRed: true,
isBig: true,
ok: true,
showred: 'red',
url: "http://www.baidu.com"
}

})
</script>
</body>
</html>

v-bind缩写方式

1
2
3
4
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>

3.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
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
67
68
69
70
71
72
73
74
75
76
77
78
79
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>选项卡</title>
<style>
.tab_con {
width: 800px;
height: 350px;
margin: 50px auto 0;
}
.tab_btns{
height: 50px;
}
.tab_btns input {
width: 100px;
height: 50px;
background: #ddd;
font-size: 18px;
font-weight: bold;
border: 0px;
outline: none;
border-radius: 5px 5px 0 0;
font-weight: bold;
}
.tab_btns input:hover {
cursor: pointer;
}

.tab_btns .active {
background: #06f;
color: #fff;
}
.tab_cons {
height: 300px;
background: #06f;
border-radius: 0 5px 5px 5px;
}
.tab_cons div{
height: 300px;
line-height: 300px;
text-align: center;
display: none;
font-size: 26px;
color: #fff;
}
.tab_cons .current {
display: block;
}
</style>
</head>

<body>
<div id="app">
<div class="tab_con">
<div class="tab_btns">
<input type="button" value="按钮一" :class="[(num==0)?'active':'']" @click="num=0">
<input type="button" value="按钮二" :class="[(num==1)?'active':'']" @click="num=1">
<input type="button" value="按钮三" :class="[(num==2)?'active':'']" @click="num=2">
</div>
<div class="tab_cons">
<div :class="[(num==0)?'current':'']">按钮一对应的内容</div>
<div :class="[(num==1)?'current':'']">按钮二对应的内容</div>
<div :class="[(num==2)?'current':'']">按钮三对应的内容</div>
</div>
</div>
</div>

<script type="text/javascript" src="./js/vue.js" ></script>
<script type="text/javascript">
new Vue({
el: "#app",
data:{
num: 0
}
})
</script>
</body>
</html>

3.5 v-model

用于读取视图中的数据。

【需求】:使用vue赋值json数据,并显示到页面的输入框中(表单回显)。

点击提交按钮:

测试:改变输入框的值,同时验证模型的数据发生改变。

测试:改变json数据,验证同时输入框的内容也发生改变。

这就是MVVM模式

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
67
68
69
70
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<title>v-model</title>
<style>
.box {
margin: 20px 0px;
}
</style>
</head>

<body>
<div id="app">
<div class="box">
<label>用户名:</label> {{ username }} <br>
<!-- 除了插值表达式,其他地方不需要使用双大括号来取值 -->
<input type="text" v-model="username" />
<input type="button" value="改变值" @click="fnChange" />
</div>

<div class="box">
<select v-model="sel">
<option value="0">大班</option>
<option value="1">中班</option>
<option value="2">小班</option>
</select>
{{ sel }}
</div>

<input type="checkbox" v-model="danCheck" />同意用户协议
<h1>{{ singleCheck }}</h1>

<input type="checkbox" value="西瓜" v-model="multipleCheck" />西瓜
<input type="checkbox" value="苹果" v-model="multipleCheck" />苹果
<input type="checkbox" value="黄瓜" v-model="multipleCheck" />黄瓜
<h1>{{ multipleCheck }}</h1>

<div class="box">
<input type="radio" value="男" v-model="sex" />
<input type="radio" value="女" v-model="sex" />
</div>

<textarea v-model="tarea"></textarea>
<h1>{{ tarea }}</h1>

</div>

<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript">
var vue = new Vue({
el: '#app',
data: {
username: 'Kevin',
sel: 1,
singleCheck: false,
multipleCheck: ['西瓜', '苹果', '黄瓜'],
sex: '女',
tarea: ''
},
methods: {
fnChange(){
this.username += 'haha'
}
}
})
</script>
</body>
</html>

3.6 v-for

3.6.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
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<title>v-for遍历普通数组</title>
</head>

<body>
<div id="app">
<!--
<p>{{list[0]}}</p>
<p>{{list[1]}}</p>
<p>{{list[2]}}</p>
<p>{{list[3]}}</p>
<p>{{list[4]}}</p>
-->

<p v-for="(item, i) in list">
索引值:{{i}} --- 每一项:{{item}}
</p>
</div>

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

3.6.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
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<title>v-for遍历对象数组</title>
</head>

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

<script src="./js/vue.js"></script>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: 'Tom' },
{ id: 2, name: 'Jerry' },
{ id: 3, name: 'Jack' },
{ id: 4, name: 'Lucy' }
]
},
methods: {}
});
</script>
</body>
</html>

3.6.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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>v-for遍历对象</title>
</head>

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

<script src="./js/vue.js"></script>
<script>
// 创建 Vue 实例,得到 ViewModel
new Vue({
el: '#app',
data: {
user: {
id: 1,
name: 'Pony',
address: '深圳'
}
},
methods: {}
});
</script>
</body>
</html>

3.6.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
26
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<title>v-for迭代数字</title>
</head>

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

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

3.6.4 key属性的使用

​ key的作用主要是为了高效的更新虛拟DOM,其原理是vue在patch(补丁)过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
​ 另外,若不设置key还可能在列表更新时引发一些隐蔽的bug,如某行数据不该更新的却更新了。
​ vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

没有增删操作的场景下,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
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<title>v-for中key的使用</title>
</head>

<body>
<div id="app">
<div>
<label>Id:</label>
<input type="text" v-model="id">

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

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

<!-- 注意: v-for 循环的时候,key 属性只能使用 number或者string -->
<!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 -->
<p v-for="item in list" :key="item.id">
<input type="checkbox">{{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>

3.7 v-if与v-show

v-if是根据表达式的值来决定是否渲染元素

v-show是根据表达式的值来切换元素的display(css属性)

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

<p v-show="ok">这是使用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>NOT A/B/C</div>
</div>
<script src="js/vue.js" ></script>
<script type="text/javascript">
new Vue({
el: "#app",
data:{
ok: true,
code: 'D'
}
})
</script>
</body>
</html>

3.8 数组 splice() 方法

splice() 方法向数组中添加或者删除项目,然后返回被删除的项目。

该方法会改变原始数组。

语法:

1
arrayObject.splice(index, howmany, item1, ..., itemX)
参数 描述
index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
item1, …, itemX 可选。向数组添加的新项目。

返回值:

类型 描述
Array 包含被删除项目的新数组。

说明:

​ splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。

​ 如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。

3.8.1 案例1

新增:在本例中,我们将创建一个新数组,并向其添加一个元素

1
2
3
4
5
6
<script>
var arr = ["George", "John", "Thomas", "James", "Adrew", "Martin"]
document.write(arr + "<br>")
arr.splice(2, 0, "William")
document.write(arr)
</script>

输出:

George, John, Thomas, James, Adrew, Martin
George, John, William, Thomas, James, Adrew, Martin

3.8.2 案例2

修改:在本例中我们将删除位于 index 2 的元素,并添加一个新元素来替代被删除的元素

1
2
3
4
5
6
<script>
var arr = ["George", "John", "Thomas", "James", "Adrew", "Martin"]
document.write(arr + "<br>")
arr.splice(2, 1, "William")
document.write(arr)
</script>

输出:

George, John, Thomas, James, Adrew, Martin
George, John, William, James, Adrew, Martin

3.8.3 案例3

删除:在本例中我们将删除从 index 2 开始的三个元素

1
2
3
4
5
6
7
<script>
var arr = ["George", "John", "Thomas", "James", "Adrew", "Martin"]
document.write(arr + "<br>")
var del = arr.splice(2, 3)
document.write(arr + "<br>")
document.write(del)
</script>

输出:

George, John, Thomas, James, Adrew, Martin
George, John, Martin
Thomas, James, Adrew

3.9 TodoList案例

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<title>todolist</title>
<style>
.list_con {
width: 600px;
margin: 50px auto 0;
}

.inputtxt {
width: 550px;
height: 30px;
border: 1px solid #ccc;
padding: 0px;
text-indent: 10px;
}

.inputbtn {
width: 40px;
height: 32px;
padding: 0;
border: 1px solid #06f;
background-color: #06f;
color: #fff;
}

.list {
margin: 0;
padding: 0;
list-style: none;
margin-top: 20px;
}

.list li {
height: 40px;
line-height: 40px;
border-bottom: 1px solid #ccc;
}

.list li span {
float: left;
}

.list li a {
float: right;
text-decoration: none;
margin: 0 10px;
}
</style>
</head>

<body>
<div id="app" class="list_con">
<h2>To do list</h2>

<input id="txt1" type="text" class="inputtxt" v-model="txt">
<input type="button" value="增加" class="inputbtn" @click="fnAdd">

<ul id="list" class="list">
<li v-for="(item,index) in content">
<span>{{item}}</span>
<a href="javascript:;" class="up" @click="fnUp(index)"></a>
<a href="javascript:;" class="down" @click="fnDown(index)"></a>
<a href="javascript:;" class="del" @click="fnDel(index)">删除</a>
</li>
</ul>
</div>

<script src="js/vue.js" ></script>
<script>
new Vue({
el: "#app",
data:{
content: ['学习HTML', '学习CSS', '学习JavaScript'],
txt: ''
},
methods:{
// 添加
fnAdd() {
if (this.txt.trim() === '') {
alert('输入内容不能为空')
return
}
this.content.push(this.txt)
this.txt = ''
document.querySelector('#txt1').focus()
},

// 删除
fnDel(index) {
if(confirm('确认删除吗?')){
this.content.splice(index, 1)
}
},

// 上移
fnUp(index) {
if (index == 0) {
alert('亲,到顶了')
return
}
this.content.splice(index - 1, 0, this.content[index])
this.content.splice(index + 1, 1)
},

// 下移
fnDown(index) {
if (index == this.content.length - 1) {
alert('亲,到底了')
return
}
this.content.splice(index + 2, 0, this.content[index])
this.content.splice(index, 1)
}
}
})
</script>
</body>
</html>

3.10 聊天对话框 课堂练习

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>聊天对话框</title>
<style type="text/css">
.talk_con {
width: 600px;
height: 500px;
border: 1px solid #666;
margin: 50px auto 0;
background: #f9f9f9;
}

.talk_show {
width: 580px;
height: 420px;
border: 1px solid #666;
background: #fff;
margin: 10px auto 0;
overflow: auto;
}

.talk_input {
width: 580px;
margin: 10px auto 0;
}

.whotalk {
width: 80px;
height: 30px;
float: left;
outline: none;
}

.talk_word {
width: 420px;
height: 26px;
padding: 0px;
float: left;
margin-left: 10px;
outline: none;
text-indent: 10px;
}

.talk_sub {
width: 56px;
height: 30px;
float: left;
margin-left: 10px;
}

.atalk {
margin: 10px;
}

.atalk span {
display: inline-block;
background: #0181cc;
border-radius: 10px;
color: #fff;
padding: 5px 10px;
}

.btalk {
margin: 10px;
text-align: right;
}

.btalk span {
display: inline-block;
background: #ef8201;
border-radius: 10px;
color: #fff;
padding: 5px 10px;
}
</style>
</head>

<body>
<div class="talk_con" id="app">
<div class="talk_show" id="words">
<div :class="[item.who=='A'?'atalk':'btalk']" v-for="item in content">
<span>{{item.who}}说:{{item.say}}</span>
</div>
</div>
<div class="talk_input">
<select class="whotalk" id="who" v-model="sel">
<option value="0">A说:</option>
<option value="1">B说:</option>
</select>
<input type="text" class="talk_word" id="talkwords" v-model="txt">
<input type="button" value="发送" class="talk_sub" id="talksub" @click="fnAdd">
</div>
</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
// 代码实现
var oTxt = document.getElementById("talkwords")
oTxt.focus()
new Vue({
el: "#app",
data: {
content: [{
who: 'A',
say: '吃饭了吗?'
},
{
who: 'B',
say: '还没呢,你呢?'
},
],
txt: '',
sel: '0'
},
methods: {
fnAdd: function() {
if(this.txt==''){
alert('请您输入内容');
return;
}
this.content.push({
who: this.sel == '0' ? 'A' : 'B',
say: this.txt
})
this.txt = ''
oTxt.focus()
}
}
})
</script>
</body>
</html>

第四章 Vue生命周期

4.1 生命周期概述

​ 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM(文档对象模型),以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。

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

1
2
3
4
5
6
7
8
9
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})

4.2 生命周期图示

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

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

Vue在实例化的过程中,会调用这些生命周期的钩子,给我们提供了执行自定义逻辑的机会。那么,在这些vue钩子中,vue实例到底执行了哪些操作,我们先看下面执行的例子。

【需求】:演示vue对象的创建、赋值、显示、改值、销毁的全过程,即Vue的生命周期,同时使用钩子函数添加自己的业务逻辑。

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
67
68
69
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>vuejs生命周期</title>
</head>

<body>
<div id="app">
<h1>{{ message }}</h1>
</div>

<script src="./js/vue.min.js"></script>
<script>
// 实例化vue
var vue = new Vue({
// 挂载vue实例到dom节点
el: "#app",
data: {
message: 'hello world'
},
beforeCreate: function() {
showData('创建vue实例前', this);
},
// vue实例创建完成
created: function() {
showData('创建vue实例后', this);
},
beforeMount: function() {
showData('挂载到dom前', this);
},
// 页面的真实dom挂载完成
mounted: function() {
showData('挂载到dom后', this);
},
beforeUpdate: function() {
showData('数据变化更新前', this);
},
updated: function() {
showData('数据变化更新后', this);
},
beforeDestroy: function() {
showData('vue实例销毁前', this);
},
destroyed: function() {
showData('vue实例销毁后', this);
}
});

function showData(process, obj) {
console.log(process);
console.log('data 数据:' + obj.message)
console.log('vue挂载的虚拟dom对象:')
console.log(obj.$el)
console.log('真实dom结构:' + document.getElementById('app').innerHTML)
console.log('------------------------------------------------------')
}

setTimeout(function(){
vue.message = "good...";
},3000)

setTimeout(function(){
vue.$destroy(); // 销毁了监听,不会执行数据变化的监听,即不会将message的值改成good...
},6000)

</script>
</body>
</html>

总结:

vue对象初始化过程中,会执行到beforeCreate、created、beforeMount、mounted 这几个钩子的内容

beforeCreate:数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象

created:数据已经绑定到了对象实例,但是还没有挂载对象(使用ajax可在此方法中查询数据,调用函数,页面的初始化)

beforeMount:模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点。

mounted:将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并进行各种操作。

当我们的data发生改变时,会调用beforeUpdate和updated方法

beforeUpdate :数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还没有发生改变。

updated :dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到dom上面,完成更新。

当调用vue.$destroy(),用来销毁vue。

beforeDestroy,destroed :实例的销毁,vue实例还是存在的,只是解绑了事件的监听、还有model对象数据与view的绑定,即数据驱动。

第五章 Axios

5.1 Axios介绍

Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。

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

5.2 Axios请求方法

为方便起见,axios为所有支持的请求方法提供了别名

  • axios.request(config)
  • axios.get(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.patch(url[, data[, config]])

5.3 Axios基本使用

【需求】:创建data/user.json文件,使用axios调用json,将数据显示到页面上

第一步:创建data目录,创建user.json(后续我们从数据库查询,获取json数据)

1
2
3
4
5
6
[
{"username":"张三","age":22},
{"username":"李四","age":21},
{"username":"王五","age":20},
{"username":"赵六","age":23}
]

第二步:使用axios读取user.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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>vuejs中axios数据调用</title>
</head>

<body>
<div id="app">
<p v-for="user in users">
{{user.username}} --- {{user.age}}
</p>
</div>

<script src="./js/vue.min.js"></script>
<script src="js/axios.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
users: []
},
methods: {
init(){
axios.get("./data/user.json").then(response => {
console.log(response);
// 注意:需要使用箭头函数,才能正确获取this指向(vue实例)
this.users = response.data;
})
}
},
created() {
this.init()
}
});
</script>
</body>
</html>

第六章:作业

  • 完成所有案例代码
  • 完成聊天对话框代码实现
其他文章
cover
ajax
  • 24/08/13
  • 15:13