【笔记】Vue学习笔记

前言

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

引入Vue

1
<script src="js/vue.min.js"></script>

初次使用

  • 定义挂载点,数据可以展现在挂载点内
1
2
3
4
5
<body>
<div id="app">
...
</div>
</body>
  • 创建Vue对象

el:用于指定挂在点位置
data:用于指定数据
methods:用于指定函数

1
2
3
4
5
6
7
8
9
10
11
<script>
new Vue({
el: "#app",
data: {
...
},
methods: function(){
...
}
});
</script>

案例

  • 利用插值表达式{{}}将数据展现在页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>

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

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

</body>

常用指令

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="message"></div>
</div>

<script>
new Vue({
el: "#app",
data: {
message: "Hello World"
}
});
</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="message"></div>
</div>

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

</body>

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: "zhangsan",
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>Title</title>
<script src="./node_modules/[email protected]@vue/dist/vue.min.js"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>

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

<script>
new Vue({
el: "#app",
data: {
name: "hello"
}
});
</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:即可

  • 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
23
24
25
26
<body>

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

<script>
new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add() {
this.num++;
},
minus() {
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

  • 案例:通过更改数字,来动态修改div的class属性,通过css来控制不同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
39
40
41
42
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./node_modules/[email protected]@vue/dist/vue.min.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:n<-3, blue:n>3}">{{n}}</div>
<button v-on:click="add()">+</button>
<button v-on:click="minus()">-</button>
</div>

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

动态style

  • 案例:通过改变数值,动态改变div宽度
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
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./node_modules/[email protected]@vue/dist/vue.min.js"></script>
<style>
div {
width: 100px;
height: 200px;
background: red;
}
</style>
</head>
<body>

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

<script>
new Vue({
el: "#app",
data: {
n: 100
},
methods: {
add() {
this.n += 10;
},
minus() {
this.n -= 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: "hello"
}
});
</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>Title</title>
<script src="./node_modules/[email protected]@vue/dist/vue.min.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>Title</title>
<script src="./node_modules/[email protected]@vue/dist/vue.min.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
15
16
<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>Title</title>
<script src="./node_modules/[email protected]@vue/dist/vue.min.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
19
20
<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
19
20
<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
19
20
<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小清风
哔哩哔哩——黑马程序员