[toc]
前端框架—Vue指令 
指令 (Directives) 是带有 v- 前缀的特殊特性。指令特性的预期值是:单个 JavaScript 表达式。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。 例如我们在入门案例中的v-on,代表绑定事件。
 
1. 插值表达式 
说明: 
该表达式支持JS语法,可以调用js内置函数(必须有返回值) 
表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:var a = 1 + 1; 
可以直接获取Vue实例中定义的数据或函数 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 {{表达式}} <div  id ="app" > {{name}}</div > <script >     var  app = new  Vue ({         el :"#app" ,         data :{             name :"Jack"          }     }) </script > 
 
1.1 插值闪烁 
使用{{}}方式在网速较慢时会出现问题。`在数据未加载完成时,页面会显示出原始的`{{}},加载完毕后才显示正确数据,我们称为插值闪烁。我们将网速调慢一些,然后试试看刚才的案例:
 
刷新页面:
 
1.2 v-text和v-html解决差值闪烁问题 
使用v-text和v-html指令来替代{{}}
说明:
v-text:将数据输出到元素内部,如果输出的数据有HTML代码,会作为普通文本输出。 
v-html:将数据输出到元素内部,如果输出的数据有HTML代码,会被渲染。 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 <div  id ="app" >     v-text:<span  v-text ="hello" > </span >  <br />      v-html:<span  v-html ="hello" > </span >  </div > <script > 	var  vm = new  Vue ({         el :"#app" ,         data :{             hello : "<h1>大家好,我是晓哥</h1>"           }     }); </script > 
 
并且不会出现插值闪烁,当没有数据时,会显示空白。
 
2. v-model 
刚才的v-text和v-html可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。接下来学习的v-model是双向绑定,==视图(View)和模型(Model)之间会互相影响==。既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。目前v-model的可使用元素有:
input标签中type类型是:
select 
checkbox 
radio 
components(Vue中的自定义组件) 
 
以及textarea标签
 
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 <!DOCTYPE html > <html  lang ="en" > <head >     <meta  charset ="UTF-8" >      <title > v-model双向绑定</title >      <script  src ="node_modules/vue/dist/vue.js" > </script >  </head > <body >     <div  id ="app" >          <span  v-text ="name" > </span >  <br />          姓名:<input  type ="text"  v-model ="name" >  <br />          <input  type ="checkbox"  v-model ="language"  value ="java" >  <br />          <input  type ="checkbox"  v-model ="language"  value ="sql" >  <br />          <input  type ="checkbox"  v-model ="language"  value ="h5" >  <br />          {{language}}<br />          男: <input  type ="radio"  value ="男"  v-model ="sex" >  <br />          女: <input  type ="radio"  value ="女"  v-model ="sex" >  <br />          {{sex}}     </div >  </body >     <script >          var  vue = new  Vue ({            el :"#app" ,             data :{               name :"涛哥" ,               language :[],               sex :''              }         });      </script > </html > 
 
多个CheckBox对应一个model时,model的类型是一个数组,单个checkbox值默认是boolean类型 
radio对应的值是input的value值 
text 和textarea 默认对应的model是字符串 
select单选对应字符串,多选对应也是数组 
 
 
3. v-on 3.1 v-on入门 
v-on指令用于给页面元素绑定事件。 
语法:v-on:事件名="js片段或函数名 
  ==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 27 28 29 30 31 32 33 34 35 <!DOCTYPE html > <html  lang ="en"  xmlns:v-on ="http://www.w3.org/1999/xhtml" > <head >     <meta  charset ="UTF-8" >      <title > v-on事件绑定 </title >      <script  src ="node_modules/vue/dist/vue.js" > </script >  </head > <body >     <div  id ="app" >                   {{num}} <br />          <button  v-on:click ="decrement" > 减减</button >          <button  @click ="decrement" > 减减</button >          <br />                   <button  v-on:click ="num++" > 加加</button >          <button  @click ="num++" > 加加</button >      </div >  </body >     <script >          var  vue = new  Vue ({             el :"#app" ,             data :{                 num :1              },             methods :{                 decrement ( ){                     this .num --;                 }             }         })      </script > </html > 
 
3.2 事件修饰符 在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。修饰符是由点开头的指令后缀来表示的。
.stop :阻止事件冒泡到父元素 
.prevent:阻止默认事件发生 
.capture:使用事件捕获模式 
.self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行) 
.once:只执行一次 
contextmenu鼠标右击事件 
 
 
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 <!DOCTYPE html > <html  lang ="en" > <head >     <meta  charset ="UTF-8" >      <title > 事件修饰符</title >      <script  src ="node_modules/vue/dist/vue.js" > </script >  </head > <body >     <div  id ="app" >          <buton  v-on:contextmenu.once ="increment($event)" > 增加一个</buton >              <buton  v-on:contextmenu.prevent ="decrement" > 减少一个</buton >          <h1 > 有{{num}}个妹妹迷恋涛哥</h1 >          <div  @click ="wai"  style ="width: 200px;height: 200px;background-color: #90ee90;" >                           <div  @click.stop ="nei"  style ="width: 100px;height: 100px; background-color: #fff;" >              </div >          </div >      </div >  </body >     <script >          var  vue = new  Vue ({             el :"#app" ,             data :{                 num :1              },             methods :{                 wai ( ){                     console .log ("外面" );                 },                 nei ( ){                     console .log ("里面" );                 },                 increment (event ){                     event.preventDefault ();                     this .num ++;                 },                 decrement ( ) {                     this .num --;                 }             }         })      </script > </html > 
 
3.3 按键修饰符 
 
1 2 3 4 5 6 7 8 <input  v-on:keyup.13 ="submit" > <input  v-on:keyup.enter ="submit" > <input  @keyup.enter ="submit" > 
 
3.4 组合按钮 
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
 
1 2 3 4 5 <input  @keyup.alt.67 ="clear" > <div  @click.ctrl ="doSomething" > Do something</div > 
 
4. v-for 
遍历数据渲染页面是非常常用的需求,Vue中通过v-for指令来实现。
语法:v-for="item in items" 
items:要遍历的数组,需要在vue的data中定义好。 
item:迭代得到的数组元素的别名 
 
 
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 <div  id ="app" >          <ul >          <li  v-for ="user in users" >              {{user.name}} - {{user.gender}} - {{user.age}}         </li >      </ul >           =====================================     <ul >          <li  v-for ="(user,index) in users"  :key ="index" >              {{index+1}}--{{user.name}}--{{user.gender}}--{{user.age}}         </li >      </ul >      ======================================          <ul >          <li  v-for ="(value,key,index) in user"  :key ="index" >              {{index+1}}--{{value}}--{{key}}         </li >      </ul >  </div > <script  src ="./node_modules/vue/dist/vue.js" > </script > <script  type ="text/javascript" >     var  app = new  Vue ({         el : "#app" ,         data : {             users :[                 {name :'柳岩' , gender :'女' , age : 21 },                 {name :'晓哥' , gender :'男' , age : 18 },                 {name :'范冰冰' , gender :'女' , age : 24 },                 {name :'刘亦菲' , gender :'女' , age : 18 },                 {name :'古力娜扎' , gender :'女' , age : 25 }             ],                user : {name :'柳岩' , gender :'女' , age : 21 },         },     }) </script > 
 
4.1 数组角标 
 
1 2 3 4 5 <ul >     <li  v-for ="(user, index) in users" >          {{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}}     </li >  </ul > 
 
4.2 遍历对象 
v-for除了可以迭代数组,也可以迭代对象。语法基本类似
 
1 2 3 4 v-for ="value in object"  v-for ="(value,key) in object"  v-for ="(value,key,index) in object"  
 
1个参数时,得到的是对象的属性值 
2个参数时,第一个是属性值,第二个是属性名 
3个参数时,第三个是索引,从0开始 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div  id ="app" >     <ul >          <li  v-for ="(value, key, index) in user" >              {{index + 1}}. {{key}} - {{value}}         </li >      </ul >  </div > <script  src ="./node_modules/vue/dist/vue.js" > </script > <script  type ="text/javascript" >     var  vm = new  Vue ({         el :"#app" ,         data :{             user :{name :'涛哥' , gender :'男' , age : 18 }         }     }) </script > 
 
4.3 key☆ 
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。 这个功能可以有效的提高渲染的效率。
 
但是要实现这个功能,你需要给Vue一些提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。 
 
这里使用了一个特殊语法::key="" 我们后面会讲到,它可以让你读取vue中的属性,并赋值给key属性
 
这里我们绑定的key是数组的索引,应该是唯一的
 
 
 
1 2 3 <ul >     <li  v-for ="(item,index) in items"  :key =index > </li >  </ul > 
 
5. v-if和v-show 
语法:v-if="布尔表达式" 
  v-if的值如果是false,那么会删除该节点 
一般用在切换比较少的情况下。 
 v-if更加灵活,他可以配合着v-else,v-else-if来使用。 
v-show的值如果是false,那么会在该节点上添加一个display:none的样式来隐藏。
 
 
 
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 <!DOCTYPE html > <html  lang ="en" > <head >     <meta  charset ="UTF-8" >      <title > 条件判断</title >      <script  src ="node_modules/vue/dist/vue.js" > </script >  </head > <body >     <div  id ="app" >          <button  @click ="show=!show" > 点击显示隐藏</button >          <h1  v-if ="show" >              v-if显示了         </h1 >          <h1  v-show ="show" >              v-show显示了         </h1 >                   <ul >              <li  v-for ="(user,index) in users"  v-if ="user.gender==='女'"  :key ="index" >                  {{index+1}}--{{user.name}}--{{user.gender}}--{{user.age}}             </li >          </ul >                   <button  @click ="random=Math.random()*100" > 生成分数</button >           得分:{{random}}          <h1  v-if ="random>80" > 优秀</h1 >           <h1  v-else-if ="random>70" > 良好</h1 >           <h1  v-else-if ="random>60" > 及格</h1 >           <h1  v-else ="random>=0" > 不及格</h1 >      </div >  </body >     <script >          var  vue = new  Vue ({             el :"#app" ,            data :{                users :[                    {name :'柳岩' , gender :'女' , age : 21 },                    {name :'晓哥' , gender :'男' , age : 18 },                    {name :'范冰冰' , gender :'女' , age : 24 },                    {name :'刘亦菲' , gender :'女' , age : 18 },                    {name :'古力娜扎' , gender :'女' , age : 25 }                ],                show :true ,                random :0             }         });      </script > </html > 
 
5.1 v-if与v-for结合 
当v-if和v-for出现在一起时,v-for优先级更高。也就是说,会先遍历,再判断条件。
 
1 2 3 4 5 <ul >     <li  v-for ="(user,index) in users"  v-if ="user.gender==='女'"  :key ="index" >          {{index+1}}--{{user.name}}--{{user.gender}}--{{user.age}}     </li >  </ul > 
 
5.2 v-else和v-else-if 
v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
 
v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用
 
类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。
 
 
 
1 2 3 4 5 6 <button  @click ="random=Math.random()*100" > 生成分数</button >    得分:{{random}}    <h1  v-if ="random>80" > 优秀</h1 >     <h1  v-else-if ="random>70" > 良好</h1 >     <h1  v-else-if ="random>60" > 及格</h1 >     <h1  v-else ="random>=0" > 不及格</h1 >  
 
6. v-bind☆ 
 
1 2 3 4 5 <div  title ="{{title}}" > 我是div1</div > <div  v-bind:title ="title" > 我是div2</div > 
 
6.1 绑定class样式 
语法表示 red 这个 class 存在与否将取决于数据属性 isActive 的 truthiness 
(所有的值都是真实的,除了false,0,“”,null,undefined和NaN )。
 
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 <!DOCTYPE html > <html  lang ="en"  xmlns:v-bind ="http://www.w3.org/1999/xhtml" > <head >     <meta  charset ="UTF-8" >      <title > v-bind绑定</title >      <script  src ="node_modules/vue/dist/vue.js" > </script >      <style >          .green {             color :green;         }         .red {             color :red;         }         .blue {             color :blue;         }      </style > </head > <body >     <div  id ="app" >                   <div  v-bind:class ="green" > 绑定class样式测试1</div >          <div  v-bind:class ="[green,red]" > 绑定class样式测试2</div >          <div  v-bind:class ="groupColor" > 绑定class样式测试3</div >          <hr />                   <div  v-bind:class ="{red:isActive}" > 绑定测试--对象</div >          <hr />      </div >  </body >     <script >          var  vue = new  Vue ({             el :"#app" ,             data :{                 title :"我是标题" ,                 green :"green" ,                 red :"red" ,                 groupColor :["green" ,"blue" ],                 isActive :1 ,                 baseStyle :{'border' :'1px solid #ff0000' },                 bgcStyle :{'background-color' :'blue' }             }         });      </script > </html > 
 
6.2 绑定style样式 
数组语法
 
数组语法可以将多个样式对象应用到同一个元素上: 
1 <div  v-bind:style ="[baseStyles, overridingStyles]" > </div > 
 
数据:
1 2 3 4 data : {    baseStyles : {'background-color' : 'red' },     overridingStyles : {border : '1px solid black' } } 
 
渲染后的结果:
1 <div  style ="background-color: red; border: 1px solid black;" > </div > 
 
对象语法
 
v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名: 
1 <div  v-bind:style ="{ color: activeColor, fontSize: fontSize + 'px' }" > </div > 
 
数据:
 
1 2 3 4 data : {  activeColor : 'red' ,   fontSize : 30  } 
 
效果:
 
1 <div  style ="color: red; font-size: 30px;" > </div > 
 
6.3 简写 
v-bind:class可以简写为:class
v-bind:style可以简写为:style
 
7. 计算属性 
在插值表达式中使用js表达式是非常方便的,而且也经常被用到。
 
但是如果表达式的内容很长,就会显得不够优雅,而且后期维护起来也不方便,例如下面的场景,我们有一个日期的数据
 
计算属性本质就是方法,但是一定要返回数据。然后页面渲染时,可以把这个方法当成一个变量来使用。
 
 
 
1 2 3 data :{    birthday :1529032123201   } 
 
1 2 3 4 5 <h1 > 您的生日是:{{    new Date(birthday).getFullYear() + '-'+ new Date(birthday).getMonth()+ '-' + new Date(birthday).getDay()     }} </h1 > 
 
虽然能得到结果,但是非常麻烦。Vue中提供了计算属性,来替代复杂的表达式:
 
1 2 3 4 5 6 7 8 9 10 11 12 13 var  vm = new  Vue ({    el :"#app" ,     data :{         birthday :1429032123201       },     computed :{         birth ( ){                          const  d = new  Date (this .birthday );             return  d.getFullYear () + "-"  + (d.getMonth ()+1 ) + "-"  + d.getDay ();         }     } }) 
 
1 2 3 <div  id ="app" >    <h1 > 您的生日是:{{birth}} </h1 >  </div > 
 
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要birthday还没有发生改变,多次访问 birthday 计算属性会立即返回之前的计算结果,而不必再次执行函数。 
 
8. watch☆ 
watch可以让我们监控一个值的变化。从而做出相应的反应。
 
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 <!DOCTYPE html > <html  lang ="en" > <head >     <meta  charset ="UTF-8" >      <title > watch监听</title >      <script  src ="node_modules/vue/dist/vue.js" > </script >  </head > <body >     <div  id ="app" >          <input  type ="text"  v-model ="wd" >      </div >  </body >     <script >          var  vue = new  Vue ({             el :"#app" ,             data :{                 wd :"" ,             },             watch :{                                  wd (newVal,oldVal ){                     console .log ("去后台查询" +newVal);                     console .log (newVal,oldVal);                 }             }         })      </script > </html > 
 
效果:
☆