前言
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>
|
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/_vue@2.6.14@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添加事件
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/_vue@2.6.14@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
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/_vue@2.6.14@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>
|
修饰符
事件修饰符
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/_vue@2.6.14@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/_vue@2.6.14@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/_vue@2.6.14@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 |
表单修饰符
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小清风
哔哩哔哩——黑马程序员