基本使用

使用Vue的步骤

  1. 需要提供标签用于填充数据
  2. 引入VUE.js文件
  3. 可以使用vue的语法做功能
  4. 把vue提供的数据填充到标签里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<div id="app">
<!-- 插值表达式 可以做简单的运算 -->
<h1>{{title}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
// 模型数据
data: {
title: 'xiaokang'
}
})
</script>
</body>

image-20201101085009406

指令

v-cloak

https://cn.vuejs.org/v2/api/#v-cloak

作用:用于解决当vue没有渲染时显示两个大括号等问题。

指令用法:

  1. 提供样式

    1
    2
    3
    4
    5
    <style>
    [v-cloak] {
    display: none;
    }
    </style>
  2. 在插值表达式所在的标签中添加v-cloak指令

    1
    <h1 v-cloak>{{title}}</h1>

数据绑定

将数据填充到标签中。

  • v-text

    此指令没有闪动问题,插入内容为纯文本内容

  • v-html

    填充HTML片段,存在安全问题。

  • v-pre

    显示原始信息,跳过编译过程

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="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>

<body>
<div id="app">
<!-- 插值表达式 可以做简单的运算 -->
<h1>{{title}}</h1>
<div v-text='text'></div>
<div v-html='html'></div>
<div v-pre='pre'>{{pre}}</div>
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
// 模型数据
data: {
title: 'xiaokang',
text: 'v-text 纯文本内容',
html: '<h1>v-html 填充html</h1>',
pre: 'v-pre显示原始信息,跳过编译过程'
}
})
</script>
</body>

</html>

image-20201101090556170

数据响应式

v-once指令可以使数据只渲染一次,即数据不再是响应式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<div id="app">
<!-- 插值表达式 可以做简单的运算 -->
<h1>{{title}}</h1>
<h1 v-once>{{msg}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
// 模型数据
data: {
title: 'xiaokang',
msg: 'once只渲染一次',
}
})
</script>
</body>

image-20201101091330644

双向数据绑定

双向数据绑定使用v-model命令。

4b52bf92-ca42-42b1-a3cb-ba67c14292e0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<div id="app">
<!-- 插值表达式 可以做简单的运算 -->
<p>{{msg}}</p>
<input type="text" v-model='msg'>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
// 模型数据
data: {
msg: 'once只渲染一次',
}
})
</script>
</body>

原理:通过v-bind绑定属性,v-on:input绑定输入事件,以此改变属性的值。

事件绑定

https://cn.vuejs.org/v2/guide/events.html

事件绑定通过v-on指令,v-on指令可以简写为@,例如:

1
<button @click='num++'>点击</button>

835c22b8-f2b4-486d-8ba8-ca205ae06413

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
<body>
<div id="app">
<div>{{num}}</div>
<button v-on:click='add()'>加1</button>
<button v-on:click='min()'>减1</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
// 模型数据
data: {
num: 0,
},
// 定义方法,用于事件绑定
methods: {
add() {
this.num++
},
min() {
this.num--
}
},
})
</script>
</body>

参数传递

  1. 直接调用函数,不传递参数

    1
    <button v-on:click="fn">test</button>

    此种情况在methods中接受的第一个参数为事件对象。

    1
    2
    3
    4
    5
    methods: {
    fn(e) {
    console.log(e);
    }
    },

    image-20201031144142085

  2. 传递参数

    1
    <button v-on:click="fn(1,2,3,$event)">按钮 - {{title}}</button>

    此时无论传递多少个参数,传递事件对象时必须使用$event名称且只能放在最后一个位置。

    1
    2
    3
    4
    5
    6
    7
    8
    methods: {
    fn(a, b, c, d) {
    console.log("a: ", a);
    console.log("b: ", b);
    console.log("c: ", c);
    console.log("d: ", d);
    }
    }

    image-20201031144401317

事件修饰符

  • .stop

    阻止事件继续传播

  • .prevent

    阻止默认事件

  • .capture

    是否是以捕获模式

  • .self

    是否是自己触发的

  • .once

    只触发一次

  • .passive

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

b1fe6135-e483-4fae-9b00-6235b15151d2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<div id="app">
<a href="https://xiaokang.me" target="_blank" @click.prevent='fn'>小康</a>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
// 定义方法,用于事件绑定
methods: {
fn() {
console.log('点击a标签了。');
}
},
})
</script>
</body>

按键修饰符

按键修饰符

00f7b330-b079-42dd-ab20-153f84df8b3c

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
<body>
<div id="app">
<input type="text" v-model='username' @keyup.delete='fn'>
<input type="text" v-model='password' @keyup.enter='fn2'>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
username: '',
password: ''
},
// 定义方法,用于事件绑定
methods: {
fn() {
console.log('按下了delete键');
this.username = ''
},
fn2() {
console.log('按下了回车键');
}
},
})
</script>
</body>

虽然VUE提供了自定义按键修饰符的方法,但此方法已经被废弃。keyCode

案例:简单计算器

image-20201101100152302

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">
数值A: <input type="text" v-model='a'><br>
数值B: <input type="text" v-model='b'><br>
<button @click='fn'>计算</button>
<p>计算结果:{{result}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
a: '',
b: '',
result: ''
},
// 定义方法,用于事件绑定
methods: {
fn() {
this.result = parseInt(this.a) + parseInt(this.b)
}
},
})
</script>
</body>

属性绑定

属性绑定通过v-bind实现,这个属性也可以存在两种写法:全写与简写

1
2
<a v-bind:href="href">{{href}}</a>
<a :href="href">{{href}}</a>

例如:通过数据动态控制a标签中href属性的值。

c827dd89-21d6-420e-addd-a4123a9383c3

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">
<a v-bind:href="href">{{href}}</a>
<button @click='fn'>切换</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
href: 'https://xiaokang.me'
},
// 定义方法,用于事件绑定
methods: {
fn() {
this.href = 'https://www.antmoe.com'
}
},
})
</script>
</body>

样式绑定

1
2
3
<!-- 左边为class名,右边为属性 -->
<div :class='{active:isActive}'></div>
<div :class='[activeClass,errorClass]'></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
<head>
<style>
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
</style>
</head>

<body>
<div id="app">
<!-- 左边为class名,右边为属性 -->
<div :class='{active:isActive}'></div>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
isActive: true
},
})
</script>
</body>

image-20201101103818361

通过isActive属性控制类是否生效

通过数组方式添加类名:

1
<div :class='[activeClass,errorClass]'></div>
1
2
3
4
5
6
7
8
9
10
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
activeClass: 'active',
errorClass: 'error'
},
})
</script>

在数组中同样可以添加对象,即两者结合使用

1
<div :class='[activeClass,errorClass,{test:"isTest"}]'></div>

或者也可以通过如下方式:

1
<div :class='myClass'></div>
1
2
3
4
5
6
7
8
9
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
myClass:['activeClass','errorClass',{test:"isTest"}]
},
})
</script>

关于样式绑定,如果元素存在默认的class,那么默认class会被保留

通过style绑定样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<div id="app">
<div :style='{border:boderStyle,height:heightStyle,width:widthStyle}'></div>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
boderStyle: '1px solid red',
heightStyle: '100px',
widthStyle: '100px'
},
})
</script>
</body>

关于样式也可以通过对象的方式

1
<div :style='objStyle'></div>
1
2
3
4
5
6
7
8
9
10
11
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
objStyle: {
border: '1px solid red',
height: '100px',
width: '100px',
}
},
})

直接操作值就会改变样式。

分支循环

1
2
3
<div v-if='score>=90'>优秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else='score<90&&score>=80'>垃圾</div>

image-20201101111047174

此指令只会渲染一个div,然而v-show会渲染多个div,即控制display来决定是否显示。

1
<div v-show='flag'>测试</div>

image-20201101111223710

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id="app">
<div v-if='score>=90'>优秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else='score<90&&score>=80'>垃圾</div>
<div v-show='flag'>测试</div>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
score: 99,
flag: false
},

})
</script>
</body>

循环结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<div id="app">
<ul>
<li v-for='(item,index) of fruits'>{{index}}---{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
fruits: ['apple', 'orange', 'banana']
},

})
</script>
</body>

image-20201101111803212

为了保证没一条记录的唯一性,最好通过唯一值为每一个元素绑定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
<body>
<div id="app">
<ul>
<li v-if='flag' v-for='item of obj'>
{{item.id}}---{{item.name}}---{{item.age}}
</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
// 元素挂载的位置,可以是CSS选择器或者DOM元素
el: '#app',
data: {
obj: [
{
id: 1,
name: 'a',
age: 12
},
{
id: 2,
name: 'b',
age: 13
},
{
id: 3,
name: 'c',
age: 14
},
],
flag: false
},

})
</script>
</body>

image-20201101113239670

案例:Tab选项卡

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

<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}

.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 100px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
cursor
}

.tab ul li:first-child {
border-left: 1px solid blue;
}

.tab ul li.active {
background-color: orange;
}

.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}

.tab div.current {
display: block;
}
</style>
</head>

<body>
<div id="app">
<div class="tab">
<ul>
<li v-on:click='change(index)' :class='currentIndex==index?"active":""' :key='item.id'
v-for='(item,index) in list'>{{item.title}}</li>
</ul>
<div :class='currentIndex==index?"current":""' :key='item.id' v-for='(item, index) in list'>
<img :src="item.path">
</div>
</div>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
/*

*/
var vm = new Vue({
el: '#app',
data: {
currentIndex: 0, // 选项卡当前的索引
list: [{
id: 1,
title: '第一个',
path: 'https://cdn.jsdelivr.net/gh/blogimg/picbed@master/2020/04/13/5005109d1aa2ffd28984c2b02b8cbfbe.png'
}, {
id: 2,
title: '第二个',
path: 'https://cdn.jsdelivr.net/gh/blogimg/picbed@master/2020/04/13/163a2ade4361d1ed705ed523091af67e.png'
}, {
id: 3,
title: '第三个',
path: 'https://cdn.jsdelivr.net/gh/blogimg/picbed@master/2020/04/13/d8ccc2fd66f340c46b8fb98ed7148223.png'
}]
},
methods: {
change: function (index) {
// 在这里实现选项卡切换操作:本质就是操作类名
// 如何操作类名?就是通过currentIndex
this.currentIndex = index;
}
}
});
</script>
</body>

</html>

3b37e63f-fb69-4d20-a3be-5e8f1655772b

案例:TODO

DEMO:https://tzk.acs.pw/2020-11/01/Stable/todos.html