步入vue.js世界
一、遇见vue.js
1.1 Vue.js是什么?
Vue.js 是一套用于构建用户界面的渐进式框架,Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。Vue.js通过简单的API提供高效的数据绑定和灵活的组件系统。
1.2 MVC 和 MVVM
MVC是应用最广泛的软件架构之一,一般MVC分为:Model(模型)、Controller(控制器)和View(视图)。View一般都是通过Controller来和Model进行联系的。Controller是Model和View的协调者,View和Model不直接联系。
相比MVC,MVVM只是把MVC的Controller改成了ViewModel。View的变化会自动更新到ViewModel,ViewModel的变化也会自动同步到View上显示。
1.3Vue和Angular区别?
Vue——简单、易学
指令以 v-xxx
一片html代码配合上json,在new出来vue实例
个人维护项目
适合: 移动端项目,小巧
Angular——上手难
指令以 ng-xxx
所有属性和方法都挂到$scope身上
angular由google维护
合适: pc端项目
共同点: 都支持指令、过滤器和双向绑定,不兼容低版本IE
二、指令
2.1 v-if
v-if指令可以完全根据表达式的值在DOM中生成或移除一个元素。如果v-if表达式赋值为false,那么对应的元素就会从DOM中移除;否则,对应元素的一个克隆将被重新插入DOM中。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-if</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <p v-if="greeting">Holle World</p> 11 </div> 12 </body> 13 <script type="text/javascript"> 14 new Vue({ 15 el:'#box', 16 data:{ 17 greeting:true 18 } 19 }); 20 </script> 21 </html>
2.2 v-show
v-show指令是根据表达式的值来显示或者隐藏HTML元素。当v-show赋值为false时,元素将被隐藏。查看DOM时,会发现元素上多了 一个内联样式style=“display:none”。
注:v-if如果初始渲染时条件为假,则什么也不做,在条件第一次变为真时才开始局部编译(编译会被缓存起来)。相比之下,v-show元素始终被编译并保留,只是简单地基于CSS切换。一般来说,v-if有更高的切换消耗,而v-show有更高的初始渲染消耗。因此,如果需要频繁地切换,则使用v-show较好;如果在运行时条件不大可能改变,则使用v-if较好。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-show</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <h1>Hello,vue.js</h1> 11 <h1 v-show="yes">Yes</h1> 12 <h1 v-show="no">No</h1> 13 <h1 v-show="age>=25">Age:{{age}}</h1> 14 </div> 15 <script type="text/javascript"> 16 new Vue({ 17 el: '#box', 18 data: { 19 yes: true, 20 no: false, 21 age: 28, 22 } 23 }) 24 </script> 25 26 </body> 27 </html>
2.3 v-else
v-else就是javascript中else的意思,它必须跟着v-if,充当else功能。
注:v-show和v-else一起使用时会出现指令优先级问题,我们可以用另一个v-show替换v-else。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-else</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <h1 v-if="age>=25">Age:{{age}}</h1> 11 <h1 v-else>Name:{{name}}</h1> 12 </div> 13 14 <script type="text/javascript"> 15 new Vue({ 16 el:'#box', 17 data:{ 18 age:26, 19 name:'Male' 20 } 21 }) 22 </script> 23 24 25 </body> 26 </html>
2.4 v-model
v-model指令用来在input、select、text、checkbox、radio等表单控件元素上创建双向数据绑定。根据控件类型v-model自动选取正确的方法更新元素。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-model</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 10 <div id="box"> 11 <input type="text" v-model="msg" /> 12 <p>{{msg}}</p> 13 </div> 14 15 <script type="text/javascript"> 16 new Vue({ 17 el: '#box', 18 data: { 19 msg: "hello" 20 } 21 }) 22 </script> 23 24 </body> 25 </html>
2.5 v-for
我们可以使用v-for指令基于源数据重复渲染元素,我们也可以使用index来呈现相对应数组索引,key获取键名,keys是唯一值。
注:1.如果使用v-for迭代数字的话,值是从1开始而不是0,如:<p v-for="i in 10">这是第{{i}}个标签</p>——》 第一个 i=1
2.在组件中,使用v-for循环的时候,或者在一些特殊情况中,必须指定唯一的 字符串/数字 类型 :key="
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>v-for</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 <script> 8 window.onload = function() { 9 new Vue({ 10 el: '#box', 11 data: { 12 json: { 13 a: 'apple', 14 b: 'banana', 15 c: 'orange' 16 } 17 } 18 }); 19 }; 20 </script> 21 </head> 22 <body> 23 <div id="box"> 24 <ul> 25 <!-- key 获取键名,index 获取索引 --> 26 <li v-for="(value,key,index) in json"> 27 {{value}} {{key}} {{index}} 28 </li> 29 </ul> 30 </div> 31 </body> 32 </html>
2.6 v-bind
v-bind指令用于给html标签设置属性,在绑定class或style时,支持其他类型的值,如数组或对象。可以简写为 :
注:v-bind中,可以写合法的js表达式
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-bind</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 <style type="text/css"> 8 .red{ 9 width: 200px; 10 height: 200px; 11 background-color: red; 12 } 13 .blue{ 14 width: 200px; 15 height: 200px; 16 background-color: blue; 17 } 18 </style> 19 </head> 20 <body> 21 22 <div id="box"> 23 <h2 :class="redClass"></h2> 24 <h2 :class="blueClass"></h2> 25 </div> 26 27 <script type="text/javascript"> 28 new Vue({ 29 el:'#box', 30 data:{ 31 redClass:"red", 32 blueClass:"blue" 33 } 34 }) 35 </script> 36 37 </body> 38 </html>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>使用style绑定属性</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <!-- 方法一 --> 10 11 <!-- <div id="box"> 12 <strong :style="{color:'red'}">文字。。。</strong> 13 </div> 14 15 <script type="text/javascript"> 16 new Vue({ 17 el:'#box' 18 }); 19 </script> --> 20 21 <!-- 方法二 --> 22 23 <!-- <div id="box"> 24 <strong :style="[c,b]">文字。。。</strong> 25 </div> 26 27 <script type="text/javascript"> 28 new Vue({ 29 el:'#box', 30 data:{ 31 c:{color:'red'}, 32 b:{backgroundColor:'blue'} //注意: 复合样式,采用驼峰命名法 33 } 34 }); 35 </script> --> 36 37 <!-- 方法三 --> 38 <!-- 推荐使用 --> 39 <div id="box"> 40 <strong :style="json">文字。。。</strong> 41 </div> 42 43 <script type="text/javascript"> 44 new Vue({ 45 el: '#box', 46 data: { 47 json: { 48 color: 'red', 49 backgroundColor: 'blue' 50 } 51 } 52 }); 53 </script> 54 55 </body> 56 </html>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>使用class绑定属性</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 <style type="text/css"> 8 .red { 9 color: red; 10 } 11 12 .thin { 13 font-weight: 200; 14 } 15 16 .italic { 17 font-style: italic; 18 } 19 20 .active { 21 letter-spacing: 0.5em; 22 } 23 </style> 24 </head> 25 <body> 26 <div id="app"> 27 <!-- 第一种使用方式,直接传递一个数组,注意:这里的class需要使用 v-bind 做数据绑定 --> 28 <h1 :class="['red','thin']">这是一个很大很大的H1。</h1> 29 </div> 30 <script type="text/javascript"> 31 new Vue({ 32 el: '#app', 33 data: {} 34 }); 35 </script> 36 </body> 37 </html>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>用class绑定属性通过json进行数据传值</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 <style type="text/css"> 8 .a { 9 color: red; 10 } 11 12 .bg { 13 background: blue; 14 } 15 </style> 16 </head> 17 <body> 18 <div id="box"> 19 <strong :class="json">文字。。。</strong> 20 </div> 21 22 <script> 23 new Vue({ 24 el: '#box', 25 data: { 26 json: { 27 a: true, 28 bg: false 29 } 30 } 31 32 }); 33 </script> 34 </body> 35 </html>
2.7 v-on
v-on指令用于绑定事件监听器。可以简写为 @
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-on</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 10 <div id="box"> 11 <input type="button" value="提示" @click="doClick" /> 12 <h3>带参数的事件处理</h3> 13 <input type="button" value="参数处理" @click="doShow('zhuyujie')" /> 14 </div> 15 <script type="text/javascript"> 16 new Vue({ 17 el: '#box', 18 methods: { 19 doClick: function() { 20 alert("使用v-on定义事件处理方法"); 21 }, 22 doShow: function(name) { 23 alert("欢迎您!" + name); 24 } 25 } 26 }) 27 </script> 28 </html>
v-on后面不仅可以跟参数,还可以增加修饰符:
.stop——调用event.stopPropagation()。
.prevent——调用event.preventDefault()。
.capture——添加事件侦听器时使用capture模式。
.self——实现只有点击当前元素时候,才会触发事件处理函数。
.keydown\keyup——只在只定按键上触发回调。Vue.js提供的键值有:[esc:27、tab:9、enter:13、space:32、delete:[8,46]、up:28、left:37、right:39、down:40]。
<!--停止冒泡-->
<button @click.stop="doThis"></botton>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>阻止事件冒泡</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <div @click="show2()"> 11 <!-- stop 阻止事件冒泡 点击按钮时只弹出 1 不弹出 2 --> 12 <input type="button" value="按钮" @click.stop="show()" /> 13 </div> 14 </div> 15 16 <script> 17 new Vue({ 18 el: '#box', 19 data: { 20 21 }, 22 methods: { 23 show: function() { 24 alert(1); 25 }, 26 show2: function() { 27 alert(2); 28 } 29 } 30 }); 31 </script> 32 33 </body> 34 </html>
<!--阻止默认行为-->
<button @click.prevent="doThis"></botton>
<!--阻止默认行为,没有表达式-->
<button @click.prevent></botton>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>阻止右键默认行为</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <!-- contextmenu 右键菜单事件 prevent 阻止默认行为 (不让右击出现菜单只弹出 1) --> 11 <input type="button" value="按钮" @contextmenu.prevent="show()" /> 12 </div> 13 14 <script> 15 new Vue({ 16 el: '#box', 17 data: { 18 19 }, 20 methods: { 21 show: function() { 22 alert(1); 23 } 24 } 25 }); 26 </script> 27 28 </body> 29 </html>
<!--键修饰符,键别名-->
<button @keyup.enter="onEnter"></botton>
<!--键修饰符,键代码-->
<button @keyup.13="onEnter"></botton>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>获取点击按键键码值和使用键码值</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <!-- @keydown在文字输入文本框之前执行,@keyup:反之 --> 11 <input type="text" @keyup="show($event)" /> 12 </div> 13 14 <script> 15 new Vue({ 16 el: '#box', 17 data: { 18 19 }, 20 methods: { 21 show: function(ev) { 22 if (ev.keyCode != 13) { 23 // keyCode 获取点击按键键码 24 alert(ev.keyCode); 25 } else { 26 alert('你按了回车键'); 27 } 28 } 29 } 30 }); 31 </script> 32 33 </body> 34 </html>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>自定义全局按键修饰符</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 10 <div id="box"> 11 <input type="text" @keyup.113="add" /> 12 </div> 13 <script type="text/javascript"> 14 //自定义全局按键修饰符 将enter键码值113 赋给 f2 取代enter键 15 Vue.config.keyCodes.f2 = 113 16 17 new Vue({ 18 el: '#box', 19 data: { 20 add() { 21 alert('以将enter键码值113 赋给了 f2 '); 22 } 23 } 24 }); 25 </script> 26 27 </body> 28 </html>
<!--串联修饰符-->
<button @click.stop.prevent="doThis"></botton>
2.8 v-cloak
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。但有时添加完毕后仍有部分变量会显示,是因为 v-cloak 的display属性被优先级别高的样式覆盖所导致,在Css中添加!important。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-cloak</title> 6 <style type="text/css"> 7 [v-cloak]{ 8 display: none; 9 } 10 </style> 11 </head> 12 <body> 13 <!-- 防止页面加载时出现 vuejs 的变量名而设计的——> {{msg}} 14 但有时添加完毕后仍有部分变量会显示,是因为v-cloak的display属性被优先级别高的样式覆盖所导致,可以添加 !important 如:[v-cloak] { display:none !important;} 15 --> 16 <div id="box" v-cloak> 17 {{msg}} 18 </div> 19 20 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 21 <script type="text/javascript"> 22 new Vue({ 23 el: '#box', 24 data:{ 25 msg:'hi' 26 } 27 }); 28 </script> 29 </body> 30 </html>
2.9 v-text
v-text指令可以更新元素的textContent。在内部,{{Mustache}}插值也被编译为textNode的一个v-text指令。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-text</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <span>{{msg}}</span> 11 <br> 12 <span v-text="msg"></span> 13 </div> 14 <script type="text/javascript"> 15 new Vue({ 16 el:'#box', 17 data:{ 18 msg:'hollo' 19 } 20 }); 21 </script> 22 </body> 23 </html>
2.10 v-html
v-html指令可以更新元素的innerHTML。内容按普通HTML插入——数据绑定被忽略。不建议在网站上直接动态渲染任意HTML片段,很容易导致XSS攻击。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>v-html</title> 6 <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> 7 </head> 8 <body> 9 <div id="box"> 10 <span>{{msg}}</span> 11 <span v-html="msg"></span> 12 </div> 13 <script type="text/javascript"> 14 new Vue({ 15 el:'#box', 16 data:{ 17 msg:'<h1>hi</h1>' 18 } 19 }); 20 </script> 21 </body> 22 </html>
注:1.默认v-text,v-html是没有闪烁问题
2.v-text,v-html会覆盖元素中原本的内容,但是差值表达式( {{msg}} )只会替换自己的这个占位符,不会把整个元素的内容清空。