基本使用
使用Vue的步骤
- 需要提供标签用于填充数据
- 引入VUE.js文件
- 可以使用vue的语法做功能
- 把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({ el: '#app', data: { title: 'xiaokang' } }) </script> </body>
|
指令
v-cloak
https://cn.vuejs.org/v2/api/#v-cloak
作用:用于解决当vue没有渲染时显示两个大括号等问题。
指令用法:
提供样式
1 2 3 4 5
| <style> [v-cloak] { display: none; } </style>
|
在插值表达式所在的标签中添加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({ el: '#app', data: { title: 'xiaokang', text: 'v-text 纯文本内容', html: '<h1>v-html 填充html</h1>', pre: 'v-pre显示原始信息,跳过编译过程' } }) </script> </body>
</html>
|
数据响应式
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({ el: '#app', data: { title: 'xiaokang', msg: 'once只渲染一次', } }) </script> </body>
|
双向数据绑定
双向数据绑定使用v-model
命令。
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({ 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>
|
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({ el: '#app', data: { num: 0, }, methods: { add() { this.num++ }, min() { this.num-- } }, }) </script> </body>
|
参数传递
直接调用函数,不传递参数
1
| <button v-on:click="fn">test</button>
|
此种情况在methods中接受的第一个参数为事件对象。
1 2 3 4 5
| methods: { fn(e) { console.log(e); } },
|
传递参数
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); } }
|
事件修饰符
.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>
<div v-on:click.self="doThat">...</div>
|
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self
会阻止所有的点击,而 v-on:click.self.prevent
只会阻止对元素自身的点击。
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({ el: '#app', methods: { fn() { console.log('点击a标签了。'); } }, }) </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 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({ el: '#app', data: { username: '', password: '' }, methods: { fn() { console.log('按下了delete键'); this.username = '' }, fn2() { console.log('按下了回车键'); } }, }) </script> </body>
|
虽然VUE提供了自定义按键修饰符的方法,但此方法已经被废弃。keyCode
案例:简单计算器
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({ 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
属性的值。
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({ el: '#app', data: { href: 'https://xiaokang.me' }, methods: { fn() { this.href = 'https://www.antmoe.com' } }, }) </script> </body>
|
样式绑定
1 2 3
| <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"> <div :class='{active:isActive}'></div> </div> <script src="../js/vue.js"></script> <script> let app = new Vue({ el: '#app', data: { isActive: true }, }) </script> </body>
|
通过isActive
属性控制类是否生效
通过数组方式添加类名:
1
| <div :class='[activeClass,errorClass]'></div>
|
1 2 3 4 5 6 7 8 9 10
| <script> let app = new Vue({ 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({ 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({ 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({ 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>
|
此指令只会渲染一个div,然而v-show
会渲染多个div,即控制display
来决定是否显示。
1
| <div v-show='flag'>测试</div>
|
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({ 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({ el: '#app', data: { fruits: ['apple', 'orange', 'banana'] },
}) </script> </body>
|
为了保证没一条记录的唯一性,最好通过唯一值为每一个元素绑定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({ 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>
|
案例: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) { this.currentIndex = index; } } }); </script> </body>
</html>
|
案例:TODO
DEMO:https://tzk.acs.pw/2020-11/01/Stable/todos.html