【笔记】Vue2学习笔记

前言

Vue.js是一个用于创建用户界面的开源JavaScript框架,也是一个创建单页应用的Web应用框架。 2016年一项针对JavaScript的调查表明,Vue有着89%的开发者满意度。在GitHub上,该项目平均每天能收获95颗星,为Github有史以来星标数第3多的项目。(维基百科

引入依赖

1
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js"></script>

快速入门

el:用于指定挂在点位置
data:用于指定数据
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
</head>
<body>

<div id="app">
...
</div>

<script>
new Vue({
el: "#app",
data: {
...
},
methods: function () {
...
}
});
</script>

</body>
</html>

插值表达式(胡子语法)

  • 插值表达式(胡子语法){{}}可以在HTML中插入JS数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>

<div id="app">
{{ key }}
</div>

<script>
new Vue({
el: "#app",
data: {
key: "Hello World"
}
});
</script>

</body>

Vue提供的HTML属性

v-text指定标签内文本(不解析标签)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>

<div id="app">
<div v-text="key"></div>
</div>

<script>
new Vue({
el: "#app",
data: {
key: "value"
}
});
</script>

</body>

v-html指定标签内文本(解析标签)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>

<div id="app">
<div v-html="key"></div>
</div>

<script>
new Vue({
el: "#app",
data: {
key: "<font color='red'>value</font>"
}
});
</script>

</body>

v-if判断语句

v-if一层判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>

<div id="app">
<div v-if="age>18">成年</div>
<div v-if="age<=18">未成年</div>
</div>

<script>
new Vue({
el: "#app",
data: {
age: 18
}
});
</script>

</body>

v-else两层判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>

<div id="app">
<div v-if="age>18">成年</div>
<div v-else>未成年</div>
</div>

<script>
new Vue({
el: "#app",
data: {
age: 18
}
});
</script>

</body>

v-else-if多层判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>

<div id="app">
<div v-if="age>18">成年</div>
<div v-else-if="age<0">输入有误</div>
<div v-else>未成年</div>
</div>

<script>
new Vue({
el: "#app",
data: {
age: 18
}
});
</script>

</body>

v-show展现

  • 判断符合条件的展现标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>

<div id="app">
<div v-show="age>18">成年</div>
</div>

<script>
new Vue({
el: "#app",
data: {
age: 18
}
});
</script>

</body>

v-for循环

遍历数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>

<div id="app">
<div v-for="color in colors">
{{ color }}
</div>
</div>

<script>
new Vue({
el: "#app",
data: {
colors: ["red","green","blue"]
}
});
</script>

</body>

遍历对象(各个值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<div v-for="(value, key, index) in person">
{{ index }},{{ key }},{{ value }}
</div>
</div>

<script>
new Vue({
el: "#app",
data: {
person: {
name: "zhangsan",
age: 18,
address: "China"
}
}
});
</script>

</body>

遍历对象(单独对象)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<div v-for="p in person">
{{ p.name }},{{ p.age }},{{ p.address }}
</div>
</div>

<script>
new Vue({
el: "#app",
data: {
person: {
name: "张三",
age: 18,
address: "China"
}
}
});
</script>

</body>

v-cloak标记

  • 在加载页面时,双大括号渲染数据之前可能会展示未渲染的变量
  • v-cloak标记在双大括号渲染之后会消失
  • 所以使用v-cloak配合CSS,实现双大括号未渲染时隐藏,渲染后展示
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
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>

<div id="app" v-cloak>
{{ key }}
</div>

<script>
new Vue({
el: "#app",
data: {
key: "value"
}
});
</script>

</body>

v-once渲染一次

  • 被v-once标记的标签内,只会渲染视图一次,当数据发生改变时,不会再次渲染视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body>

<div id="app" v-once>
<h1>{{ num }}</h1>
<button @click="add()">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
console.log(this.num);
}
}
});
</script>

</body>

v-pre跳过编译

  • 被v-pre标记的标签会跳过当前标签内的双括号编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>

<div id="app" v-pre>
<h1>{{ num }}</h1>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
}
});
</script>

</body>

v-on添加事件

  • v-on的作用是给元素增加事件监听,在原生事件关键字前去掉on。然后加上v-on:即可
  • 所有的监听方法,都要写在methods
  • 遇到同名方法,后面的会覆盖前面的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<h1>{{ num }}</h1>
<button v-on:click="add()">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

</body>
  • v-on:可以简写为@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<h1>{{ num }}</h1>
<button @click="add()">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

</body>

方法传递参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<h1>{{ num }}</h1>
<button v-on:click="add(5)">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add(n) {
this.num += n;
}
}
});
</script>

</body>

方法的默认参数

  • 如果方法中不传递参数,则会传递默认的事件参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="app">
<h1>{{ num }}</h1>
<button v-on:click="add">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add(event) {
console.log(event);
}
}
});
</script>

v-bind动态属性

  • 通过在原生的html属性前添加v-bind:前缀,来实现动态数据的支持
  • v-bind:可以简写为:

动态src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="app">
<img v-bind:src="'./img/'+n+'.jpg'" width="800px">
<button v-on:click="add()">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
n: 1
},
methods: {
add() {
this.n++;
}
}
});
</script>

动态class

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
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
div {
width: 200px;
height: 200px;
background: red;
}
.green {
background: green;
}
.blue {
background: blue;
}
</style>
</head>
<body>

<div id="app">
<div :class="{green:num<=0, blue:num>0}">{{ num }}</div>
<button v-on:click="add()">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

动态style

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
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
div {
width: 100px;
height: 200px;
background: red;
}
</style>
</head>
<body>

<div id="app">
<div :style="{width: num+'px'}">{{ num }}</div>
<button v-on:click="add()">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 100
},
methods: {
add() {
this.num += 10;
}
}
});
</script>

v-model双向绑定

  • 使用在表单元素中
  • 实现表单和数据的双向绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<h1>{{ key }}</h1>
<input type="text" v-model:value="key">
</div>

<script>
new Vue({
el: "#app",
data: {
key: "value"
}
});
</script>

修饰符

事件修饰符

  • 事件修饰符通常在vue事件末尾追加.修饰符

stop阻止事件冒泡

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
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
.outer {
width: 180px;
height: 180px;
background: gold;
margin: 100px auto;
padding: 30px;
border-radius: 50%;
}
.outer .center {
width: 130px;
height: 130px;
background: pink;
padding: 30px;
border-radius: 50%;
}
.outer .center .inner {
width: 130px;
height: 130px;
background: cyan;
border-radius: 50%;
}
</style>
</head>
<body>

<div id="app">
<div class="outer" @click="outer">
<div class="center" @click="center">
<div class="inner" @click.stop="inner"></div>
</div>
</div>
</div>

<script>
new Vue({
el: "#app",
data: {
outer() {
console.log("外层");
},
center() {
console.log("中间");
},
inner() {
console.log("内层");
}
}
});
</script>

self阻止事件冒泡

  • 但只有点击元素本身时,才会触发,不接受冒泡上来的事件,同时也不能阻止事件的冒泡
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
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
.outer {
width: 180px;
height: 180px;
background: gold;
margin: 100px auto;
padding: 30px;
border-radius: 50%;
}
.outer .center {
width: 130px;
height: 130px;
background: pink;
padding: 30px;
border-radius: 50%;
}
.outer .center .inner {
width: 130px;
height: 130px;
background: cyan;
border-radius: 50%;
}
</style>
</head>
<body>

<div id="app">
<div class="outer" @click.self="outer">
<div class="center" @click.self="center">
<div class="inner" @click.self="inner"></div>
</div>
</div>
</div>

<script>
new Vue({
el: "#app",
data: {
outer() {
console.log("外层");
},
center() {
console.log("中间");
},
inner() {
console.log("内层");
}
}
});
</script>

prevent清除默认事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>

<div id="app">
<a href="https://www.baidu.com" v-on:click.prevent="alert('超链接')">超链接</a>
</div>

<script>
new Vue({
el: "#app",
data: {}
});
</script>

</body>

capture事件捕获

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
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
.outer {
width: 180px;
height: 180px;
background: gold;
margin: 100px auto;
padding: 30px;
border-radius: 50%;
}
.outer .center {
width: 130px;
height: 130px;
background: pink;
padding: 30px;
border-radius: 50%;
}
.outer .center .inner {
width: 130px;
height: 130px;
background: cyan;
border-radius: 50%;
}
</style>
</head>
<body>

<div id="app">
<div class="outer" @click.capture="outer">
<div class="center" @click="center">
<div class="inner" @click="inner"></div>
</div>
</div>
</div>

<script>
new Vue({
el: "#app",
data: {
outer() {
console.log("外层");
},
center() {
console.log("中间");
},
inner() {
console.log("内层");
}
}
});
</script>

once使事件只触发一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<h1>{{ num }}</h1>
<button @click.once="add">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

</body>

按键修饰符

  • 可以使用别名,也可以使用键盘编码值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body>

<div id="app">
<h1>{{ num }}</h1>
<input type="text" @keydown.space="add">
<input type="text" @keydown.32="add">
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

</body>

其他常用按键

按键 键码值 修饰符
空格 32 space
回车 13 enter
左键 37 left
右键 39 right
上键 38 up
下键 40 down
制表符 9 tab
删除键 46或8 space或delete

系统修饰符

  • 键盘鼠标组合触发
  • 可以使用别名,也可以使用键盘编码值
  • 只要按键组合包含设定的按键就会触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<h1>{{ num }}</h1>
<button v-on:click.meta="add">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

</body>

其他常用按键

按键(Win) 按键(Mac) 修饰符
ctrl键 control键 ctrl
alt键 option键 alt
shift键 shift键 shift
Win键 command键 meta

exact精确匹配

  • 在对应的系统修饰符后追加.exact
  • 按键组合必须符合设定的按键才会触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<h1>{{ num }}</h1>
<button v-on:click.meta.exact="add">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

</body>

鼠标修饰符

  • .right鼠标右键监听配合.prevent取消默认事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>

<div id="app">
<h1>{{ num }}</h1>
<button v-on:click.right.prevent="add">+</button>
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
}
}
});
</script>

</body>

其他常用按键

按键 修饰符
鼠标左键 left
鼠标右键 right
鼠标滚轮 middle

表单修饰符

  • 表单修饰符都是修饰v-model属性的

lazy懒加载

  • 当表单失去焦点才会更新数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>

<div id="app">
<h1>{{ num }}</h1>
<input type="text" v-model.lazy="num">
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {}
});
</script>

</body>

number转换为数字类型

  • 将字符串转换为数字类型
  • 将字符串过滤,只保留数字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>

<div id="app">
<h1>{{ num }}</h1>
<input type="text" v-model.number="num">
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {}
});
</script>

</body>

trim清除首尾空格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>

<div id="app">
<h1>{{ num }}</h1>
<input type="text" v-model.trim="num">
</div>

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {}
});
</script>

</body>

完成

参考文献

哔哩哔哩——Python小清风
哔哩哔哩——黑马程序员