赵工的个人空间


专业技术部分转网页计算转业余爱好部分


 编程语言

常用的编程语言
C#编程语言基础
C#面向对象与多线程
C#数据及文件操作
JavaScript基础
JavaScript的数据类型和变量
JavaScript的运算符和表达式
JavaScript的基本流程控制
JavaScript的函数
JavaScript对象编程
JavaScript内置对象和方法
JavaScript的浏览器对象和方法
JavaScript访问HTML DOM对象
JavaScript事件驱动编程
JavaScript与CSS样式表
Ajax与PHP
ECMAScript6的新特性
Vue.js前端开发
PHP的常量与变量
PHP的数据类型与转换
PHP的运算符和优先规则
PHP程序的流程控制语句
PHP的数组操作及函数
PHP的字符串处理与函数
PHP自定义函数
PHP的常用系统函数
PHP的图像处理函数
PHP类编程
PHP的DataTime类
PHP处理XML和JSON
PHP的正则表达式
PHP文件和目录处理
PHP表单处理
PHP处理Cookie和Session
PHP文件上传和下载
PHP加密技术
PHP的Socket编程
PHP国际化编码
MySQL数据库基础
MySQL数据库函数
MySQL数据库账户管理
MySQL数据库基本操作
MySQL数据查询
MySQL存储过程和存储函数
MySQL事务处理和触发器
PHP操作MySQL数据库
数据库抽象层PDO
Smarty模板
ThinkPHP框架
Python语言基础
Python语言结构与控制
Python的函数和模块
Python的复合数据类型
Python面向对象编程
Python的文件操作
Python的异常处理
Python的绘图模块
Python的NumPy模块
Python的SciPy模块
Python的SymPy模块
Python的数据处理
Python操作数据库
Python网络编程
Python图像处理
Python机器学习
TensorFlow深度学习
Tensorflow常用函数
TensorFlow用于卷积网络
生成对抗网络GAN


首页 > 专业技术 > 编程语言 > Vue.js前端开发
Vue.js前端开发
  1. Vue实例与选项:
  2. 数据绑定:
  3. 条件判断:
  4. 计算属性与监听属性:
  5. 样式绑定:
  6. 事件处理:
  7. 过渡:

Vue.js是一条用于构建用户界面的渐进式框架,只关注图层,采用自底向上的增量开发方式,通过简单的API实现响应的数据绑定和组合的视图组件。Vue.js是一个用于开发Web前端界面的库,采用MVVM(Model-View-ViewModel)的开发模式,View的变化会自动更新到ViewModel,而ViewModel的变化也会自动同步到View上显示。Vue.js拥有组件化理念,可以将任意封装好的代码注册成组件,这样减少了重复开发,提高了开发效率和代码的复用性。如果配合vue-loader,可以将一个组件的HTML、CSS和JavaScript代码都写在一个文件中,实现模块化开发。

1. Vue实例与选项:

每个Vue.js应用都需要通过构造函数创建一个Vue实例。创建一个Vue实例的语法格式:
  var vm=new Vue({
     //选项
  })

在创建对象实例时,可以在构造函数中传入一个选项对象。选项对象中包括挂载元素、数据、方法、生命周期钩子函数等选项。

1)挂载元素:

在Vue.js的构造函数中有一个el选项,作用是为Vue实例提供挂载元素。定义挂载元素后,接下来的全部操作都在该元素内进行,元素外部不受影响。该选项可以使用CSS选择符,也可以使用原生的DOM元素名称。例如定义一个div元素,代码:
  <div id="box" class="box"></div>
如果将该元素作为Vue实例的挂载元素,可以设置为:el:'#box'、el:'.box'或el:'div'。

2)数据:

通过data选项可以定制数据,这些数据可以绑定到实例对应的模板中。示例代码:
  <div id="box" class="box">
     <h3>网站名称:{{name}}</h3>
     <h3>网站地址:{{url}}</h3>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         name: '个人空间',
         url: 'www.dwenzhao.cn'
       }
     });
  </script>

上述代码中创建了一个Vue实例demo,实例的data中定义了name和url两个属性。模板中的{{name}}用于输出name属性,{{url}}用于输出url属性,也就是data数据与DOM进行了关联。
在创建实例时,如果传入的data是一个对象,那么实例会代理data对象中的所有属性。当这些属性的值发生变化时,HTML视图也会发生相应变化。因此data对象中定义的属性为响应式属性。示例代码:
  <div id="box" class="box">
     <h3>网站名称:{{name}}</h3>
     <h3>网站地址:{{url}}</h3>
  </div>
  <script type="text/javascript">
     var data={name:'个人空间',url:'www.dwenzhao.cn'};
     var demo=new Vue({
       el: '#box',
       data: data
     });
     ducument.write(demo.name===data.name);//引用了相同对象
     demo.url='http://www.dwenzhao.cn';//重新设置属性
  </script>

代码中,demo.name===data.name的输出结果为true,当重新设置url属性时,模板中的{{url}}也会随之变化。
注意,只有在创建Vue实例时传入的data对象中的属性才是响应式的。如果开始不能确定某些属性值,可以为其设置初始值,如:
  data: {
     name: '',
     count: 0,
     price:[],
     flag:true
  }

Vue.js还提供了一些有用的实例属性和方法,其名称都有前缀$,以便与用户定义的属性区分。例如可以通过Vue实例中的data属性来获取声明的数据:
  <script type="text/javascript">
     var data={name:'个人空间',url:'www.dwenzhao.cn'};
     var demo=new Vue({
       el: '#box',
       data: data
     });
     ducument.write(demo.$data===data);  //输出true
  </script>

3)方法:

在Vue实例中,通过methods选项可以定义方法,示例代码:
  <div id="box" class="box">
     <h3>网站名称:{{showInfo()}}</h3>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         name: '个人空间',
         url: 'www.dwenzhao.cn'
       },
       methods:{
         showInfo:function(){
           return this.name+': '+this.url;
         }
       }
     });
  </script>

上述代码中,实例的methods选项中定义了一个showInfo()方法,模板中{{showInfo()}}用于调用该方法,从而输出data对象中的属性值。

4)生命周期的钩子函数:

每个Vue实例在创建时都有一系列的初始化步骤,如创建数据绑定、编译模板、将实例挂载到DOM并在数据变化时触发DOM更新、销毁实例等。在这个过程中会运行一些称为生命周期钩子的函数,通过这些钩子函数可以定义业务逻辑。Vue实例的几个主要的生命周期钩子函数为:
  ·  beforeCreate:在Vue实例开始初始化时调用
  ·  created:在实例创建之后调用,此时尚未开始DOM编译
  ·  mounted:在DOM文档渲染完毕之后调用,相当于window.onload()方法
  ·  beforeDestroy:在销毁实例之前调用,此时实例仍然有效
  ·  destroyed:在实例销毁之后调用
示例代码:
  <div id="box" class="box"></div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       beforeCreate:function(){
         console.log('beforeCreate');
       },
       created:function(){
         console.log('created');
       },
       beforeDestroy:function(){
         console.log('beforeDestroy');
       },
       destroyed:function(){
         console.log('destroyed');
       },
       mounted:function(){
         console.log('mounted');
         this.$destroy();
       }
     });
  </script>

代码中在mounted函数中应用了$destroy()方法,该方法用于销毁一个实例。

2. 数据绑定:

数据绑定是Vue.js最核心的一个特性,建立数据绑定后,数据和视图会相互关联,当数据发生变化时,视图会自动进行更新,使代码更加简洁。

1)插值:

⑴ 文本插值:
文本插值是数据绑定的最基本形式,使用双大括号标签。
  <div id="box">
     <h3>hello {{name}}</h3>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         name: 'Vue.js',
       }
     });
  </script>

代码中,{{name}}标签会被相应的数据对象中的name属性值所替代,并且将DOM中的name与data中的name属性进行了绑定。当数据对象中的name属性值发生改变时,文本中的值也会相应地发生变化。
如果只渲染一次数据,可以使用单次插值。单次插值只执行一次,在第一次插入文本后,当数据对象中的属性值发生改变时,插入的文本将不会更新。单次插值可以使用v-once指令:
  <div id="box">
     <h3 v-once>hello {{name}}</h3>
  </div>

⑵ 插入HTML:
双大括号标签会将其中的值作为普通文本来处理,如果要输出HTML内容,需要使用v-html指令。示例:
  <div id="box">
     <p v-html=”message”></p>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         message: '<h1>这里可以使用HTML标记</h1>',
       }
     });
  </script>

代码中,为<p>标记应用v-html指令后,数据对象中message属性值将作为HTML元素插入<p>标记中。
⑶ 属性:
如果要为HTML元素绑定属性,不能直接使用文本插值方式,而需要使用v-bind指令对属性绑定。示例:
  <style type="text/css">
  .title{
     color:#FF0000;
     border:1px solid #FF0000;
     display:inline-block;
     padding:5px;
  }
  </style>
  <div id="box">
     <span v-bind:class="value">面对现实</span>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         value: 'title'
       }
     });
  </script>

代码中使用v-bind指令为HTML元素<span>绑定class属性,这样数据对象中value属性的值将作为<span>标记的class属性值。还可以将属性值设置为对象的形式,示例:
  <div id="box">
     <span v-bind:class="{'title':value}">面对现实</span>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         value: true
       }
     });
  </script>

代码中用v-bind指令为HTML元素<span>绑定class属性,并判断title的值,如果为true则使用title样式,否则不使用该类。
为HTML元素绑定属性操作比较繁琐,为了防止经常使用v-bind指令带来的繁琐操作,Vue.js提供了一种简写形式“:”,如超链接设置url格式,完整形式为:
  <a v-bind:href="url">个人空间</a>
简写形式为:
  <a :href="url">个人空间</a>
下面示例代码为图片绑定属性,使用简写形式:
  <style type="text/css">
  .myImg{
     width:300px;
     border:1px solid #000000;
  }
  </style>
  <div id="box">
     <img :src="src" :class="value" :title="tip"/>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         src: 'images/js.png',
         value: 'myImg',
         tip: '提示文字'
       }
     });
  </script>

⑷ 表达式:
在双大括号中进行数据绑定,可以是一个JavaScript表达式,表达式的值是其运算的结果。
  <div id="box">
     {{number+10}}<br/>
     {{boo?'真':'假'}}<br/>
     {{str.toLowerCase()}}<br/>
  </div<
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         number: 10,
         boo: true,
         str: 'MJH My Job'
       }
     });
  </script>

注意,其中只能使用单个表达式,而不能使用JavaScript语句。

2)过滤器:

对于一些经过复杂计算的数据绑定,简单的表达式可能无法实现,这时可以使用Vue.js的过滤器处理,通过自定义的过滤器对文本格式化。
过滤器可以使用在双大括号插值和v-bind指令中,过滤器需要被添加在JavaScript表达式的尾部,由管道符合“|”表示。格式分别为:
  {{message|filter}}
  <div v-bind:id="rawId|formatId"></div>

定义过滤器主要有两种方式,第1种是使用Vue.js的全局方法Vue.filter()定义,第2种是应用选项对象中额filters选项定义。
⑴ Vue.filter()定义:
Vue.js提供了全局方法Vue.filter()定义过滤器,格式:
  Vue.filter(ID,function(){})
该方法有两个参数,第1个参数为定义的过滤器ID,作为自定义过滤器的唯一标识;第2个参数为具体的过滤器函数,函数以表达式的值为第1个参数,再将接收到的参数格式化为结果。获取当前日期和星期并输出的过滤器代码示例:
  <div id="box">
     <span>{{date|nowdate}}</span>
  </div>
  <script type="text/javascript">
     Vue.filter('nowdate',function(value){
       var year=value.getFullYear();
       var month=value.getMonth()+1;
       var date=value.getDate();
       var day=value.getDay();
       var week="";
       switch(day){
         case 1:
           week="星期一";
           break;
         case 2:
           week="星期二";
           break;
         case 3:
           week="星期三";
           break;
         case 4:
           week="星期四";
           break;
         case 5:
           week="星期五";
           break;
         case 6:
           week="星期六";
           break;
         default:
           week="星期日";
           break;
       }
       return "今天是:"+year+"年"+month+"月"+date+"日"+week;
     });
     var demo=new Vue({
       el: '#box',
       data: {
         date: new Date()
       }
     });
  </script>

⑵ 应用filters选项定义:
定义的过滤器包括过滤器名和过滤器函数两部分,过滤器函数以表达式的值作为第1个参数。
  <div id="box">
     <ul>
       <li><a href='#'><span>[特惠]</span>{{title1|subStr}}</a></li>
       <li><a href='#'><span>[公告]</span>{{title2|subStr}}</a></li>
       <li><a href='#'><span>[特惠]</span>{{title3|subStr}}</a></li>
       <li><a href='#'><span>[公告]</span>{{title4|subStr}}</a></li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         title1: '商城爆款1分秒杀',
         title1: '商城与厂家签署合作协议',
         title1: '年末促销,低至两折',
         title1: '满额100配送免费'
       },
       filters:{
         subStr:function(value){
           if(value.length>10){
             return value.substr(0,10)+"...";
           }else{
             return value;
           }
         }
       }
     });
  </script>

多个过滤器可以串联使用,如:
  {{message|filterA|filterB}}
示例代码:
  <div id="box">
     <span>{{str|lowercase|firstUppercase}}</span>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         str: 'HTML+CSS+JAVASCRIPT'
       },
       filters:{
         lowercase:function(value){
           return value.toLowerCase();
         },
         firstUppercase:function(value){
           return value.charAt(0).toUpperCase()+value.substr(1);
         }
       }
     });
  </script>

过滤器实质上是一个函数,因此也可以有额外的参数,格式为:
  {{message|filterA(arg1,arg2,...)}}
将价格格式化的示例代码:
  <div id="box">
     <span>{{price|formatPrice("¥")}}</span>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         price: 199
       },
       filters:{
         formatPrice:function(value,symbol){
           return symbol+value.toFixed(2);
         }
       }
     });
  </script>

3)指令:

指令是Vue.js中的重要特性之一,它是带有v-前缀的特殊属性。指令用于在绑定表达式的值发生改变时,将这种数据的变化应用到DOM上。当数据变化时,指令会根据指定的操作对DOM进行修改,这就无须手动去管理DOM的变化和状态。示例:
  <p v-if="show">message</p>
上述代码中,v-if指令将根据表达式show的值来确定是否插入p元素,如果值为true则插入,否则移除。
还有一些指令的语法不同,能够接收参数和修饰符。
⑴ 参数:
一些指令可以接收一个参数,如v-bind、v-on指令,该参数位于指令和表达式之间,并用冒号分隔。v-bind指令的示例代码为:
  <img v-bind:src="imageSrc">
上述代码中,src为参数,通过v-bind指令将img元素的src属性与表达式imageSrc的值进行绑定。v-on指令的示例代码为:
  <button v-on:click="login">登录</button>
上述代码中,click为参数,该参数为监听的事件名称。当触发登录按钮的click事件时,会调用login()方法。
⑵ 修饰符:
修饰符在参数后面,以半角句号点符号指明的特殊后缀。例如,.prevent修饰符用于调用event. preventDefault()方法。示例代码:
  <form v-on:submit.prevent="onSubmit"></form>
上述代码中,提交表单时会调用event.preventDefault()方法用于阻止浏览器的默认行为。

3. 条件判断:

程序设计中,条件判断和循环控制是必不可少的,Vue.js也提供了相应指令用于实现条件判断和循环控制。

1)条件判断:

在视图中,经常需要控制某些DOM元素的显示或隐藏,Vue.js提供了多条指令来实现条件判断。
⑴ v-if指令:
v-if指令可以根据表达式的值来判断是否输出DOM元素及其包含的子元素,如果表达式的值为true,就输出DOM元素及其包含的子元素,否则就将DOM元素及其包含的子元素移除。示例代码:
  <div id="box">
     <p>a的值是{{a}}</p>
     <p>b的值是{{b}}</p>
     <p v-if="a<b">a小于b</p>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         a: 100,
         b: 200
       }
     });
  </script>

⑵ 在<template>元素中使用v-if:
v-if是一个指令,必须将其加到一个元素上,根据表达式的结果判断是否输出该元素。如果需要对一组元素进行判断,需要使用<template>元素作为包装元素,并在该元素上使用v-if,最后的渲染结果中不会包含<template>元素。
根据表达式的结果判断是否输出一组单选按钮的示例代码:
  <div id="box">
     <template v-if="show">
       <input type="radio" value="A">A
       <input type="radio" value="B">B
       <input type="radio" value="C">C
     </template>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         show: true
       }
     });
  </script>

⑶ v-else指令:
v-else指令的作用相当于JavaScript中的else语句部分,可以将其与v-if指令一起使用。
  <div id="box">
     <p>a的值是{{a}}</p>
     <p>b的值是{{b}}</p>
     <p v-if="a<b">a小于b</p>
     <p v-else>a大于b</p>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         a: 200,
         b: 100
       }
     });
  </script>

⑷ v-else-if指令:
v-else-if指令的作用相当于JavaScript中的else if部分,应用此指令可以进行更多的条件判断。
  <div id="box">
     <p v-if="score>=90">考试成绩优秀</p>
     <p v-else-if="score>=75">考试成绩良好</p>
     <p v-else-if="score>=60">考试成绩及格</p>
     <p v-else>考试成绩不及格</p>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         score: 80
       }
     });
  </script>

v-else指令必须紧跟在v-if指令或v-else-if指令的后面,否则将不起作用;v-else-if指令也必须紧跟在v-if指令或v-else-if指令的后面。
⑸ v-show指令:
此指令根据表达式的值来判断是否显示或隐藏DOM元素,当表达式的值为true时元素被显示,否则元素将被隐藏,此时为元素添加了内联样式style="display:none"。无论表达式的值为true或false,元素都保留在DOM中,只是改变了CSS属性display。v-show指令不支持<template>元素。示例代码:
  <div id="box">
     <input type="button" :value="bText" v-on:click="toggle">
     <div v-show="show">
       <img src="face.png">
     </div>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         bText: '隐藏图片',
         show: true
       },
       methods:{
         toggle:function(){
           this.bText=='隐藏图片'?this.bText='显示图片':this.bText=='隐藏图片';
           this.show=!this.show;
         }
       }
     });
  </script>

v-if指令在初始条件为false时什么都不会做,但切换时会有一个局部编译/卸载过程,切换消耗大;v-show指令在初始化时都需要渲染,但切换时仅发生样式改变。在需要频繁切换场合适合使用v-show指令,而运行中很少改变时用v-if指令更好。

2)列表渲染:

Vue.js的列表渲染功能用于将数组或对象中的数据循环渲染到DOM中,类似于JavaScript中的遍历。
⑴ v-for指令遍历数组:
v-for指令根据接收数组中的数据重复渲染DOM元素,需要使用item in items形式的语法,其中items为数组名称,item为数组元素的别名,通过别名可以获取当前数组遍历的每个元素。
  <div id="box">
     <ul>
       <li v-for="item in items">{{item.name}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         items: [
           {name:'张三'},
           {name:'李四'},
           {name:'王五'}
         ]
       }
     });
  </script>

在应用v-for指令遍历数组时,还可以指定一个参数作为当前数组元素的索引,语法格式为:(item,index) in items,其中index为数组元素的索引。
  <div id="box">
     <ul>
       <li v-for="(item,index) in items">{{index}}-{{item.name}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         items: [
           {name:'张三'},
           {name:'李四'},
           {name:'王五'}
         ]
       }
     });
  </script>

⑵ 在<template>元素中使用v-for指令:
如果需要对一组元素进行循环遍历,可以使用<template>元素作为包装元素,并在其中使用该指令。
  <div id="box">
     <ul>
       <template v-for="menu in menulist">
         <li class="item">{{menu}}</li>
         <li class="separator"></li>
       </template>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         menulist: ['首页','闪购','生鲜','团购','全球购']
       }
     });
  </script>

⑶ 数组更新检查:
Vue.js中包含了一些检查数组变化的变异方法,调用这些方法可以改变原始数组并触发视图更新。
  ·  push():向数组的末尾添加一个元素或多个元素
  ·  pop():将数组中的最后一个元素从数组中删除
  ·  shift():将数组中的第1个元素从数组中删除
  ·  unshift():向数组的开头添加一个元素或多个元素
  ·  splice():添加或删除数组中的元素
  ·  sort():对数组的元素进行排序
  ·  reverse():颠倒数组中元素的顺序
电影票房降序排列示例代码:
  <div id="box">
     <div class="title">
       <div class="col-1">排名</div>
       <div class="col-2">电影名称</div>
       <div class="col-3">票房</div>
     </div>
     <div class="content" v-for="(value,index) in movie">
       <div class="col-1">{{index+1}}</div>
       <div class="col-2">{{value.name}}</div>
       <div class="col-3">{{value.boxoffice}}亿</div>
     </div>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
       movie: [
         {name:'我不是药神',boxoffice:30.9},
         {name:'红海行动',boxoffice:36.2},
         {name:'唐人街探案',boxoffice:33.9}
       ]
       }
     })
     exam.movie.sort(function(a,b){
       var x=a.boxoffice;
       var y=b.boxoffice;
       return x<y?1:-1;
     });
  </script>

Vue.js还包含几个非变异方法,如filter()、concat()、slice()方法。调用非变异方法不会改变原数组,而是返回一个新的数组。当使用非变异的方法时,可以用新的数组替换原来的数组。
  <div id="box">
     <ul>
       <li v-for="item in items">{{item.name}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         items: [
           {name:'张三'},
           {name:'李四'},
           {name:'王五'}
         ]
       }
     });
     demo.items=demo.items.slice(1);
  </script>

由于JavaScript的限制,Vue.js不能检测下面两种情况引起的数组的变化:
  ①  直接使用数组索引设置元素
  ②  修改数组的长度
为了解决第①种情况,可以使用全局方法Vue.set(array,index,value)或实例方法vm.$set (array,index,value)来设置数组元素的值,这样设置的设置元素是响应式的,可以触发视图更新。示例代码:
  <div id="box">
     <ul>
       <li v-for="item in items">{{item.name}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         items: [
           {name:'张三'},
           {name:'李四'},
           {name:'王五'}
         ]
       }
     });
     vue.set(demo.items,1,{name:'李逵'});
  </script>

为了解决第②种情况,可以使用splice()方法修改数组的长度。示例代码:
  <div id="box">
     <ul>
       <li v-for="item in items">{{item.name}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         items: [
           {name:'张三'},
           {name:'李四'},
           {name:'王五'}
         ]
       }
     });
     demo.items.splice(2);
  </script>

⑷ 应用v-for指令遍历对象:
v-for指令不仅可以遍历数组,还可以遍历对象,这时需要使用value in object形式的语法,其中object为对象名,value为对象属性值的别名。
  <div id="box">
     <ul>
       <li v-for="value in object">{{value}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         object: {
           name:'张三',
           sex:'男',
           age:25
         }
       }
     });
  </script>

使用v-for指令遍历对象时,还可以使用第2个参数为对象属性名提供一个别名,语法格式为(value,key) in object,其中key为对象属性的别名。
  <div id="box">
     <ul>
       <li v-for="(value,key) in object">{{key}}:{{value}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         object: {
           name:'张三',
           sex:'男',
           age:25
         }
       }
     });
  </script>

使用v-for指令遍历对象时,还可以使用第3个参数为对象提供一个索引,语法格式为(value, key, index) in object,其中index为对象的索引。
  <div id="box">
     <ul>
       <li v-for="(value,key,index) in object">{{index}}-{{key}}:{{value}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         object: {
           name:'张三',
           sex:'男',
           age:25
         }
       }
     });
  </script>

⑸ 向对象中添加属性:
在已经创建的实例中,使用全局方法Vue.set(object,key,value),或实例方法vm.$set (object,key,value)可以向对象中添加响应式属性,同时触发视图更新。
  <div id="box">
     <ul>
       <li v-for="(value,key,index) in object">{{key}}:{{value}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         object: {
           name:'张三',
           sex:'男',
           age:25
         }
       }
     });
     Vue.set(demo.object,'interest','歌唱');
  </script>

如果需要添加多个响应式属性,可以使用Object.assign()方法。在使用该方法时,需要将源对象的属性和新添加的属性合并成一个新的对象。
  <div id="box">
     <ul>
       <li v-for="(value,key,index) in object">{{key}}:{{value}}</li>
     </ul>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         object: {
           name:'张三',
           sex:'男',
           age:25
         }
       }
     });
     demo.object=Object.assign({},demo.object,{
         'interest':'歌唱',
         'address':'观塘镇'
     });
  </script>

⑹ 应用v-for指令遍历整数:
v-for指令也可以遍历整数,接收的整数为循环次数,根据循环次数将模板重复整数次。
  <div id="box">
     <div v-for="n in 5">员工第{{n}}年工龄补贴为:{{n*salary}}元</div>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box',
       data: {
         salary: 30
       }
     });
  </script>

九九乘法表的示例代码:
  <div id="box">
     <div v-for="n in 9">
       <span v-for="m in n">{{m}}*{{n}}*={{m*n}}</span>
     </div>
  </div>
  <script type="text/javascript">
     var demo=new Vue({
       el: '#box'
     });
  </script>

4. 计算属性与监听属性:

在模板中绑定的表达式通常用于简单的运算,如果在模板的表达式中应用过多的业务逻辑会使模板难以维护。为了使模板结构清晰,对于比较复杂的逻辑,可以使用Vue.js提供的计算属性。

1)计算属性:

⑴ 计算属性简单应用:
计算属性需要定义在computed选项中,当计算属性依赖的数据发生变化时,这个属性的值会自动更新,所有依赖该属性的数据绑定也会同步更新。
一个计算属性中可以实现各种复杂的逻辑,包括运算、函数调用等。示例代码:
  <div id="example">
     <p>原字符串:{{str}}</p>
     <p>新字符串:{{newstr}}</p>
  </div>
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         str:'HTML*JavaScript*Vue.js'
       },
       computed:{
         newstr:function(){
           return this.str.splite('*').join('+');
         }
       }
     });
  </script>

上述代码中定义了一个计算属性newstr,并在模板中绑定了这个计算属性。newstr属性的值依赖于str属性的值。当str属性的值发生变化时,newstr属性的值也会自动更新。
计算属性还可以依赖Vue实例中的多个数据,只要其中任一数据发生变化,计算属性都会随之变化,视图也会随之更新。
  <div id="example">
     <div class="title">
       <p>商品名称</p>
       <p>单价</p>
       <p>数量</p>
       <p>金额</p>
     </div>
     <div class="content" v-for="value in shop">
       <p>{{value.name}}</p>
       <p>{{value.price|twoDecimal}}</p>
       <p>{{value.count}}</p>
       <p>{{value.price*value.count|twoDecimal}}</p>
     </div>
     <p>合计:{{totalprice|formatPrice("¥")}}</p>
  </div>
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         shop:[{
           name:'Nokia TA1054',
           price:999,
           count:3
         },{
           name:'Samsung S21',
           price:1999,
           count:2
         }]
       },
       computed:{
         totalprice:function(){
           var total=0;
           this.shop.forEach(function(s){
             total+=s.price*s.count;
           });
           return total;
         }
       },
       filters:{
         twoDecimal:function(value){
           return value.toFixed(2);
         },
         formatPrice:function(value,symbol){
           return symbol+value.toFixed(2);
         }
       }
     });
  </script>

⑵ getter和setter:
每一个计算属性都包含一个getter和一个setter。当没有指明方法时,默认使用getter来读取数据。
  <div id="example">
     <p>姓名{{fullname}}</p>
  </div>
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         surname:'韦',
         name:'小宝'
       },
       computed:{
         fullname:function(){
           return this.surname+this.name;
         }
       }
     });
  </script>

上述代码中定义了一个计算属性fullname,为该属性提供的函数将默认作为fullname属性的getter。代码也可以写为:
  <div id="example">
     <p>姓名{{fullname}}</p>
  </div>
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         surname:'韦',
         name:'小宝'
       },
       computed:{
         fullname:{
           get:function(){
             return this.surname+this.name;
           }
         }
       }
     });
  </script>

也可以设置计算属性的setter,用来执行设置值的操作。当手动更新计算属性的值时,就会触发setter,执行一些自定义的操作。示例代码:
  <div id="example">
     <p>姓名{{fullname}}</p>
  </div>
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         surname:'韦',
         name:'小宝'
       },
       computed:{
         fullname:{
           get:function(){//getter
             return this.surname+this.name;
           },
           set:function(value){//setter
             this.surname=value.substr(0,1);
             this.name=value.substr(1);
           }
         }
       }
     });
     exam.fullname='张三丰';
  </script>

上述代码中定义了一个计算属性fullname,在为其重新赋值时,Vue.js会自动调用setter,并将新值作为参数传递给set()方法,surname和name属性会相应更新,模板中绑定的fullname属性的值也会随之更新。在未设置setter情况下未计算属性重新赋值是不会触发模板更新的。
⑶ 计算属性缓存:
除了使用计算属性外,在表达式中调用方法也可以实现同样的效果。示例代码:
  <div id="example">
     <p>姓名{{fullname}}</p>
  </div>
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         surname:'韦',
         name:'小宝'
       },
       methods:{
         fullname:function(){
           return this.surname+this.name;
         }
       }
     });
  </script>

将相同的操作定义为一个方法,或者定义为一个计算属性,结果完全相同。但使用计算属性时,每次获取的值是基于依赖的缓存值。当页面重新渲染时,如果依赖数据未发生改变,使用计算属性获取的值就一直是缓存值,只有依赖的数据发生改变时才会重新执行getter。

2)监听属性:

⑴ 监听属性简单应用:
监听属性是Vue.js提供的一种用来监听和响应Vue实例中的数据变化的方式。在监听数据对象中的属性时,每当监听的属性发生变化,都会执行特定的操作。监听属性可以定义在watch选项中,也可以使用实例方法vm.$watch()。示例代码:
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         surname:'韦',
         name:'小宝'
       },
       watch:{
         fullname:function(newvalue,oldvalue){
           alert("原值"+oldvalue+" 新值"+newvalue);
         }
       }
     });
     exam.fullname='张三丰';
  </script>

上述代码中,在watch选项中对fullname属性进行了监听,当改变该属性值时,会执行对应的回调函数,函数中两个参数分别表示监听属性的新值和旧值,其中第2个参数可以省略。
使用vm.$watch()实例方法的示例代码:
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         surname:'韦',
         name:'小宝'
       }
     });
     vm.$watch('fullname':function(newvalue,oldvalue){
       alert("原值"+oldvalue+" 新值"+newvalue);
     });
     exam.fullname='张三丰';
  </script>

⑵ deep选项:
如果要监听的属性值是一个对象,为了监听对象内部值的变化,可以在选项参数中设置deep选项的值为true。示例代码:
  <script type="text/javascript">
     var exam=new Vue({
       el: '#example',
       data:{
         shop:{
           name:'Nokia TA1054',
           price:999,
       },
       watch:{
         shop:{
           handler:function(val){
             alert(val.name+"新的价格为"+val.price+"元");
           },
           deep:true
         }
       }
     });
     exam.shop.price=888;
  </script>

当监听的数据是一个数组或者对象时,回调函数中的新值和旧值是相等的,因为这两个形参指向的是同一个数据对象。

5. 样式绑定:

对元素的样式绑定实际上就是对元素的class和style属性进行操作,class属性用于定义元素的类名列表,style属性用于定义元素的内联样式。使用v-bind指令可对这两个属性进行数据绑定,表达式的结果类型除了字符串外,还可以是对象和数组。

1)class属性绑定:

在样式绑定中,首先是对元素的class属性进行绑定,绑定的数据可以是对象或数组。
⑴ 对象语法:
在应用v-bind对元素的class属性进行绑定时,可以将绑定的数据设置为一个对象,从而动态地切换元素的class。将元素的class属性绑定为对象主要有三种形式。
  ·  内联绑定:
内联绑定是将元素的class属性直接绑定为对象的形式,格式:
  <div v-bind:class="{active:isActive}"></div>
上述代码中,active是元素的class类名;isActive是数据对象的属性,是一个布尔值,如果该值为true,表示元素使用类名为active的样式,否则就不使用。示例代码:
  <style type="text/css">
  .active{
     font-style:italic;
  }
  </style>
  <div id="box">
     <p v-bind:class="{active:isActive}">Vue.js样式绑定</p>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         isActive:true
       }
     });
  </script>

上述代码为div元素绑定class属性,将字体样式设置为斜体。下面是更复杂的一种使用。
  <div id="box">
     <div>
       <div class="item" v-for="book in books">
         <img v-bind:src="book.image">
         <span v-bind:class="{active:book.active}">{{book.bookname}}</span>
       </div>
     </div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         books:[{
           bookname:'红楼梦',
           image:'images/hlm.png',
           active:true
         },{
           bookname:'三国演义',
           image:'images/sgyy.png',
           active:false
         },{
           bookname:'西游记',
           image:'images/xyj.png',
           active:false
         }]
       }
     });
  </script>

在对象中可以传入多个属性来动态切换元素的多个class,而且v-bind:class也可以与普通的class属性共存。示例代码:
  <style type="text/css">
  .default{
     text-decoration:underline;
  }
  .size{
     font-size:18px;
  }
  .color{
     color:#6699FF;
  }
  </style>
  <div id="box">
     <div class="default" v-bind:class="{size:isSize,color:isColor}">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         isSize:true,
         isColor:true
       }
     });
  </script>

  ·  非内联绑定:
非内联绑定是将元素的class属性绑定的对象定义在data选项中,改写上例,代码为:
  <div id="box">
     <div class="default" v-bind:class="classObject">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         classObject:{
           size:true,
           color:true
         }
       }
     });
  </script>

  ·  使用计算属性返回样式对象:
可以为class属性绑定一个返回对象的计算属性。改写上面的示例,代码为:
  <div id="box">
     <div class="default" v-bind:class="show">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         isSize:true;
         isColor:true
       },
       computed:{
         show:function(){
           return {
             size:this,isSize,
             color:this,isColor
           }
         }
       },
     });
  </script>

⑵ 数组语法:
在对元素的class属性进行绑定时,可以把一个数组传给v-bind:class,以应用一个class列表。
将元素的class属性绑定为数组有3种形式。
  ·  普通形式:
将元素的class属性直接绑定为一个数组,格式为:
  <div v-bind:class="[element1,element2]"></div>
上述代码中,element1和element2为数据对象中的属性,它们的值为class列表中的类名。示例代码:
  <style type="text/css">
  .line{
     text-decoration:line-through;
  }
  .size{
     font-size:24px;
  }
  </style>
  <div id="box">
     <div v-bind:class="[lineClass,sizeClass]">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         lineClass:'line',
         sizeClass:'size'
       }
     });
  </script>

  ·  在数组中使用条件运算符:
在使用数组形式绑定元素的class属性时,可以使用条件运算符构成表达式来切换列表中的class。示例代码:
  <div id="box">
     <div v-bind:class="[isLine?'line':'',sizeClass]">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         inLine:true,
         sizeClass:'size'
       }
     });
  </script>

上述代码中,sizeClass属性对应的类名是始终添加的,而只有当isLine为true时才会添加line类。
  ·  在数组中使用对象:
有时使用多个条件运算符比较繁琐,这时可以在数组中使用对象来更新class列表。改写上述示例代码:
  <div id="box">
     <div v-bind:class="[{line:isLine},sizeClass]">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         isLine:true,
         sizeClass:'size'
       }
     });
  </script>

2)Style属性内联样式绑定:

在样式绑定中,除了对元素的class属性进行绑定外,还可以对元素的style属性进行内联样式绑定,绑定的数据可以是对象或数组。
⑴ 对象语法:
对元素的style属性进行绑定,可以将绑定的数据设置为一个对象。对象中的CSS属性可以使用驼峰式camelCase或短横线分隔kebab-case命名(需用单引号括起来)。主要有三种形式。
  ·  内联绑定:
这种形式是将元素的style属性直接绑定为对象。示例代码:
  <div id="box">
     <div v-bind:style="{fontWeight:weight,'font-size':fontSize+'px'}">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         weight:'bold',
         fontSize:30
       }
     });
  </script>

上述代码中为div元素绑定style属性,设置文字的粗细和大小。
  ·  非内联绑定:
这种形式是将元素的style属性绑定的对象直接定义在data选项中,这样模板更清晰。改写上述示例代码:
  <div id="box">
     <div v-bind:style="styleObject">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         styleObject:{
           fontWeight:'bold',
           font-size:'30px'
         }
       }
     });
  </script>

  ·  使用计算属性返回样式对象:
内联样式绑定的对象语法常常结合返回对象的计算属性使用。改写上述示例代码:
  <div id="box">
     <div v-bind:style="show">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         weight:'bold',
         fontSize:30
       },
       computed:{
         show:function(){
           return {
             fontWeight:this.weight,
             'font-size':this.fontSize+'px'
           }
         }
       }
     });
  </script>

⑵ 数组语法:
在对元素的style属性进行绑定时,可以使用数组将多个样式对象应用到一个元素上。应用数组形式进行style属性绑定,也有几种形式。
  ·  直接在元素中绑定样式对象:
示例代码:
  <div id="box">
     <div v-bind:style="[{fontSize:'24px'}, {''font-weight':'bold'}, {'text-decoration':'underline'}]"> Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box'
     });
  </script>

  ·  在data选项中定义样式对象数组:
改写上述示例代码:
  <div id="box">
     <div v-bind:style="arrStyle">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         arrStyle:[{
           fontSize:'24px'
         },{
           'font-weight':'bold'
         },{
           'text-decoration':'underline'
         }]
       }
     });
  </script>

  ·  以对象数组形式进行绑定:
改写上述示例代码:
  <div id="box">
     <div v-bind:style="[size,weight,decoration]">Vue.js样式绑定</div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         size:{fontSize:'24px'},
         weight:{'font-weight':'bold'},
         decoration:{'text-decoration':'underline'}
       }
     });
  </script>

当v-bind:style使用需要特定前缀的CSS属性(如transform)时,Vue.js会自动侦测并添加相应的前缀。

6. 事件处理:

在Vue.js中,事件处理是很重要的环节,它可以使程序的结构更清晰,也更灵活。

1)事件监听:

监听DOM事件使用v-on指令,通常在模板使用,在触发事件时会执行一些JavaScript代码。
⑴ 使用v-on指令:
在HTML中使用v-on指令,其后面可以是原生事件名称。基本语法示例:
  <button v-on:click="show">显示</button>
上述代码中,将click单击事件绑定到show()方法,当单击“显示”按钮时,将执行show()方法,该方法在Vue实例中进行定义。
另外,Vue.js提供了v-on指令的简写形式“@”,上述代码的简写为:
  <button @click="show">显示</button>
在页面统计鼠标单击按钮次数的示例代码:
  <div id="box">
     <button v-on:click="count++">计数</button>
     <p>按钮被单击{{count}}次</p>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         count:0
       }
     });
  </script>

⑵ 事件处理方法:
通常情况下,通过v-on指令需要将事件和某种方法进行绑定。绑定的方法作为事件处理器定义在methods选项中。示例代码:
  <div id="box">
     <button v-on:click="show">显示</button>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         name:'Nokia TA-1054',
         price:999,
       },
       methods:{
         show:function(){
           alert('商品名称'+this.name+' 商品单价'+this.price);
         }
       }
     });
  </script>

上述代码中,单击“显示”按钮就会调用show()方法来显示商品的名称和单价。
  <div id="box">
     <img id='pic' v-bind:src='url' v-on:mouseover="visible(1)" v-on:mouseout="visible(0)">
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         url:'images/flower.jpg'
       },
       methods:{
         visible:function(i){
           var pic=document.getElementId('pic');
           if(i==1)
             pic.style.opacity=0.5;
           }else{
             pic.style.opacity=1;
           }
         }
       }
     });
  </script>

上述代码,当鼠标移入图片上时会改变图片的透明度;当鼠标移出图片时,透明度恢复。
与事件绑定的方法支持参数event,即原生DOM事件对象的传入。示例代码:
  <div id="box">
     <button v-on:click="show">显示</button>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       methods:{
         show:function(event){
           if(event){
             alert('触发事件的元素标记名:'+event.target.tagName);
           }
         }
       }
     });
  </script>

当鼠标指向图片时为图片添加边框的示例代码:
  <div id="box">
     <img v-bind:src='url' v-on:mouseover="addBorder" v-on:mouseout="removeBorder">
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         url:'images/flower.jpg'
       },
       methods:{
         addBorder:function(e){
           e.target.style.border='1px solid green';
         },
         removeBorder:function(e){
           e.target.style.border=0;
         }
       }
     });
  </script>

⑶ 使用内联JavaScript语句:
v-on指令也支持内联JavaScript语句,但只可以使用一个语句。示例代码:
  <div id="box">
     <button v-on:click="show('网络前端编程')">显示</button>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       methods:{
         show:function(name){
           alert('图书名称:'+name);
         }
       }
     });
  </script>

如果在内联语句中需要获取原生的DOM事件对象,可以将一个特殊变量$event传入方法。示例代码:
  <div id="box">
     <a href="http://www.dwenzhao.cn" v-on:click="show('个人网站欢迎你!',$event)">{{name}}</a>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       data:{
         name:'个人网站'
       },
       methods:{
         show:function(message,e){
           e.preventDefault();
           alert(message);
         }
       }
     });
  </script>

2)事件处理中的修饰符:

修饰符是以半角句点符号指明的特殊后缀。Vue.js为v-on指令提供了多个修饰符,这些修饰符分为事件修饰符和按键修饰符。
⑴ 事件修饰符:
在事件处理程序中经常需要调用preventDefault()或stopPropagation()方法来实现特定的功能。为了处理这些DOM事件细节,Vue.js为v-on指令提供了事件修饰符,见下表:

修饰符 说明
.stop 等同于调用event.stopPropagation()
.prevent 等同于调用event.preventDefault()
.capture 使用capture模式添加事件监听器
.self 只当事件是从监听器绑定的元素本身触发时才触发回调
.once 只触发一次回调
.passive 以{passive:true}模式添加监听器
修饰符可以串联使用,而且可以只使用修饰符,而不绑定事件处理方法。事件修饰符的使用方式示例:
  <!--阻止事件继续传播-->
  <a v-on:click.stop="doSomething"></a>
  <!--阻止表单默认提交事件-->
  <form v-on:submit.prevent="onSubmit"></form>
  <!--只当事件是从当前元素本身触发时才调用处理函数-->
  <div v-on:click.self="doSomething"></div>
  <!--修饰符串联,阻止表单默认提交事件并阻止冒泡-->
  <a v-on:click.stop.prevent="doSomething"></a>
  <!--只有修饰符,而不绑定事件-->
  <form v-on:submit.prevent></form>

下面是一个应用stop修饰符阻止事件冒泡的示例代码:
  <div id="box">
     <div v-on:click="show('div事件触发')">
       <button v-on:click.stop="show('按钮事件触发')">显示</button>
     </div>
  </div>
  <script type="text/javascript">
     var vm=new Vue({
       el: '#box',
       methods:{
         show:function(message){
           alert(message);
         }
       }
     });
  </script>

运行上述代码,当单击“显示”按钮时只会触发按钮的单击事件。
⑵ 按键修饰符:
Vue.js还为v-on指令提供了按键修饰符,以便监听键盘事件中的按键。当触发键盘事件时需要检测按键的keyCode值,示例代码:
  <input v-on:keyup.13="submit">
上述代码中,应用v-on指令监听键盘的keyup事件。键盘的回车键的keyCode值为13,所以在向文本框中输入内容后,当按回车键时就会调用submit()方法。
鉴于记住一些按键的keyCode值比较困难,Vue.js为一些常用的按键提供了别名,例如回车键<Enter>的别名为enter。上述代码可以修改为:
  <input v-on:keyup.enter="submit">
Vue.js为一些常用按键提供的别名见下表:
按键 keyCode 别名 按键 keyCode 别名
Enter 13 enter Tab 9 tab
Backspace 8 delete Delete 46 delete
Esc 27 esc Spacebar 32 space
Up Arrow 38 up Down Arrow 40 down
Left Arrow 37 left Right Arrow 39 right
Vue.js还提供了一种自定义按键别名的方法,即通过全局config.keyCodes对象自定义按键的别名。比如将按键中的F1键的别名定义为f1的代码为:
  Vue.config.keyCode.f1=112;

7. 过渡:

Vue.js内置了一套过渡系统,该系统是为DOM动画效果提供的一个特性,在插入、更新或移除DOM时可以触发CSS过渡和动画,从而产生过渡效果。

1)单元素过渡:

⑴ CSS过渡:
Vue.js提供了内置的过渡封装组件transition,该组件用于包含要实现过渡效果的DOM元素。transition组件只会把过渡效果用到其包含的内容上,而不会额外渲染DOM元素。过渡封装组件的语法格式为:
  <transition name="nameoftransition">
     <div></div>
  </transition>

其中的nameoftransition参数用于自动生成CSS过渡类名。
为元素和组件添加过渡效果主要用于条件渲染、条件展示、动态组件、组件根节点等情形。示例代码:
  <style type="text/css">
  //设置CSS属性名和持续时间
  .fade-enter-active, .fade-leave-active{
     transition:opacity 2s
  }
  .fade-enter, .fade-leave-to{
     opacity:0
  }
  </style>
  <div id="example">
     <button v-on:click="show=!show">切换</button>
     <transition name="fade">
       <p v-if="show">空想太多浪费时光</p>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       show:true,
     }
  });
  </script>

上述代码中,通过单击“切换”按钮将变量show的值在true和false之间切换,如果为true,则淡入显示<p>元素的比如;如果为false,则淡出隐藏<p>元素的内容。
CSS过渡其实就是一个淡入淡出的效果,当插入或删除包含在transition组件这的元素时,Vue.js将执行以下操作:
  ·  自动检测目标元素是否应用了CSS过渡或动画,如果是,则在合适的时机添加/删除CSS类名
  ·  如果过渡组件提供了JavaScript钩子函数,这些钩子函数将在合适的时机被调用
  ·  如果没有找到JavaScript钩子,并且也没有检测到CSS过渡/动画,DOM操作将在下一帧立即执行
⑵ 过渡的类名介绍:
Vue.js在元素显示与隐藏的过渡中,提供了6个class来切换,见下表:

class类名 说明
v-enter 定义进入过渡的开始状态。在元素被插入之前生效,在元素插入后的下一帧被移除
v-enter-active 定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间、延迟和曲线函数
v-enter-to 定义进入过渡的结束状态。在元素被插入之后下一帧生效(与此同时venter被移除)。在过渡/动画完成之后移除
v-leave 定义离开过渡的开始状态。在离开过渡被触发时立即生效,下一帧被移除
v-leave-active 定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间、延迟和曲线函数
v-leave-to 定义离开过渡的结束状态。在离开过渡被触发后下一帧生效(与此同时v-leave被移除)。在过渡/动画完成之后移除
对于这些过渡与切换的类名来说,如果使用一个没有名字的<transition>,则v-是这些类名的默认前缀。如果为<transition>设置了一个名字,如<transition name="my-transition">,则v-enter会替换为my-transition-enter。示例代码:
  <style type="text/css">
  //设置CSS属性名和持续时间
  .fade-enter-active, .fade-leave-active{
     transition:all 0.7s ease;
  }
  .fade-enter, .fade-leave-to{
     transform:translateY(-20px);
     opacity:0
  }
  </style>
  <div id="example">
     <div class="title" v-on:click="show=!show">公司简介</div>
     <transition name="fade">
       <div align="left" class="content" v-if="show">公司吹牛不用上税</div>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       show:false
     }
  });
  </script>

⑶ CSS动画:
CSS动画的用法与CSS过渡类似,但在动画中v-enter类名在节点插入DOM后不会立刻删除,而是在animationend事件触发时删除。示例代码:
  <style type="text/css">
  //设置CSS属性名和持续时间
  p{
     font:30px "微软雅黑";
     margin:30px auto;
     font-weight:500;
     color:#f35626;
  }
  //设置animation属性
  .scaling-enter-active{
     animation:scaling 1s;
  }
  .scaling-leave-active{
     animation:scaling 1s reverse;
  }
  //设置元素缩放效果
  @keyframe scaling{
     0%{
       transform:scale(0);
     }
     50%{
       transform:scale(1.2);
     }
     100%{
       transform:scale(1);
     }
  }
  </style>
  <div id="example" align="center">
     <button v-on:click="show=!show">切换显示</button>
     <transition name="scaling">
       <p v-if="show">资源多机会多</p>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       show:true
     }
  });
  </script>

运行上述代码,当单击“切换显示”按钮时,文本会以缩放的动画形式进行隐藏,再次单击该按钮,文本会以缩放的动画形式进行显示。
⑷ 自定义过渡类名:
除了使用普通的类名(如*-enter、*-leave等)之外,Vue.js也允许自定义过渡类名,自定义过渡类名的优先级高于普通的类名。通过自定义过渡类名可以使过渡系统和其他第三方CSS动画库(如animate.css)相结合,实现更丰富的动画效果。自定义过渡类名可以通过6个属性实现:enter-class、enter-active-class、enter-to-class、leave-class、leave-active=class、leave -to-class。使用第三方CSS动画库animate.css的示例代码:
  <style type="text/css">
  p{
     font:30px "微软雅黑";
     margin:40px auto;
     font-weight:500;
     color:#f35626;
  }
  </style>
  <div id="example" align="center">
     <button v-on:click="show=!show">切换显示</button>
     <transition name="rotate" enter-active-class="animated rotateIn" leave-active-class ="animated rotateOut">
       <p v-if="show">躺平</p>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       show:true
     }
  });
  </script>

运行上述代码,当单击“切换显示”按钮时,文本会以旋转动画的形式进行隐藏,再次单击该按钮,文本会以旋转动画的形式进行显示。
⑸ JavaScript钩子函数:
元素过渡效果还可以使用JavaScript钩子函数来实现,在钩子函数中可以直接操作DOM元素。在<transition>元素的属性中声明钩子函数,示例代码:
  <transition
     v-on:before-enter="beforeEnter"
     v-on:enter="enter"
     v-on:after-enter="afterEnter"
     v-on:enter-cancelled="enterCancelled"
     v-on:before-leave="beforeLeave"
     v-on:leave="leave"
     v-on:after-leave="afterLeave"
     v-on:leave-cancelled="leaveCancelled">
  </transition>
  new Vue({
     el: '#app',
     data:{
       //......
     },
     methods:{
       //设置过渡进入之前的组件状态
       beforeEnter:function(el){
         //......
       },
       //设置过渡进入完成时的组件状态
       enter:function(el,done){
         //......
       },
       //设置过渡进入完成之后的组件状态
       afterEnter:function(el){
         //......
       },
       enterCancelled:function(el){
         //......
       },
       //设置过渡离开之前的组件状态
       beforeLeave:function(el){
         //......
       },
       //设置过渡离开完成时的组件状态
       leave:function(el,done){
         //......
       },
       //设置过渡离开完成之后的组件状态
       afterLeave:function(el){
         //......
       },
       leaveCancelled:function(el){
         //......
       }
     }
  });
  </script>

这些钩子函数可以结合CSS过渡/动画使用,也可以单独使用。<transition>元素还可以添加v-bind:css="false",这样可以直接跳过CSS检测,避免CSS在过渡过程中的影响。
当只用JavaScript过渡时,在enter和leave钩子函数中必须使用done进行回调,否则它们将被同步回调,过渡会立即完成。
示例代码:
  <style type="text/css">
  p{
     font:30px "微软雅黑";
     margin:50px auto;
     font-weight:500;
     color:#f35626;
  }
  //设置元素缩放效果
  @keyframe scaling{
     0%{
       transform:scale(0);
     }
     50%{
       transform:scale(1.2);
     }
     100%{
       transform:scale(1);
     }
  }
  //创建旋转动画
  @-webkit-keyframe rotate{
     0%{
       -webkit-transform:rotateZ(0) scale(1);
     }
     50%{
       -webkit-transform:rotateZ(360deg) scale(0.5);
     }
     100%{
       -webkit-transform:rotateZ(720deg) scale(0);
     }
  }
  </style>
  <div id="example" align="center">
     <button v-on:click="show=!show">切换显示</button>
     <transition
       v-on:enter="enter"
       v-on:leave="leave"
       v-on:after-leave="afterLeave">
       <p v-if="show">受苦受累干活的没有钱</p>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       show:false
     },
     methods:{
       //设置过渡进入完成时的组件状态
       enter:function(el,done){
         el.style.opacity=1;
         el.style.animation='scaling 1s';
       },
       //设置过渡离开完成时的组件状态
       leave:function(el,done){
         el.style.animation='rotate 2s linear';
         setTimeout(function(){
           done();},1900)
       },
       //设置过渡离开完成之后的组件状态
       afterLeave:function(el){
         el.style.opacity=0;
       }
     }
  });
  </script>

运行上述代码,当单击“切换显示”按钮,文本会以缩放形式显示,再次单击该按钮,文本会以旋转动画的形式隐藏。

2)多元素过渡:

⑴ 基础用法:
最常见的多元素过渡是一个列表和描述这个列表为空消息的元素之间的过渡。在处理多元素过渡时可以使用v-if和v-else。示例代码:
  <style type="text/css">
  //设置过渡属性
  .fade-enter, .fade-leave-to{
     opacity:0;
  }
  .fade-enter-active, .fade-leave-active{
     transition:opacity .5s
  }
  </style>
  <div id="example">
     <button @click="clear">清空</button>
     <transition name="fade">
       <ol v-if="items.length>0">
         <li v-for="item in items">{{item}}</li>
       </ol>
       <p v-else>列表清空</p>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       items:['HTML','CSS','JavaScript']
     },
     methods:{
       clear:function(){
         this.items.splice(0);   //清空数组
       }
     }
  });
  </script>

运行上述代码,当单击“清空”按钮时,页面内容变化会有一个过渡效果。
⑵ key属性:
当有相同标签名的多个元素进行切换时,需要通过key属性设置唯一的值来标记以让Vue区分。示例代码:
  <style type="text/css">
  //设置过渡属性
  .fade-enter, .fade-leave-to{
     opacity:0;
  }
  .fade-enter-active, .fade-leave-active{
     transition:opacity .5s
  }
  </style>
  <div id="example">
     <button @click="show=!show">切换</button>
     <transition name="fade">
       <p v-if="show" key="m">山不在高有仙则名</p>
       <p v-else key="w">人不在贤有背景就行</p>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       show:true
     }
  });
  </script>

运行上述代码,当单击“切换”按钮时,页面内容变化会有一个过渡的效果。
在同一场景中,还可以通过为同一个元素的key属性设置不同的状态来替代v-if和v-else。改写上面的示例代码:
  <div id="example">
     <button @click="isChange=!isChange">切换</button>
     <transition name="fade">
       <p v-bind:key="isChange">{{isChange?'山不在高有仙则名':'人不在贤有背景就行'}}</p>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       isChange:true
     }
  });
  </script>

使用多个v-if的多个元素的过渡可以重写为绑定了动态属性的单个元素的过渡。
⑶ 过渡模式:
的默认行为中,元素的进入和离开是同时发生的。由于同时生效的进入和离开过渡不能满足所有要求,所以Vue.js提供了以下两种过渡模式:
  ·  in-out:新元素先进行过渡,完成之后当前元素过渡离开
  ·  out-in:当前元素先进行过渡,完成之后新元素过渡进入
应用out-in模式实现过渡的示例代码:
  <style type="text/css">
  //设置过渡属性
  .fade-enter, .fade-leave-to{
     opacity:0;
  }
  .fade-enter-active, .fade-leave-active{
     transition:opacity .5s
  }
  </style>
  <div id="example">
     <transition name="fade" mode="out-in">
       <button @click="show=!show" :key="show">{{show?'显示':隐藏''}}</button>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       show:true   //默认显示
     }
  });
  </script>

运行上述代码,当每次单击按钮时,按钮中的文字都会在“显示”和“隐藏”之间进行过渡切换。

3)多组件过渡:

多个组件过渡不需要使用key属性,只需要使用动态组件,示例代码:
  <style type="text/css">
  //设置过渡属性
  .fade-enter, .fade-leave-to{
     opacity:0;
  }
  .fade-enter-active, .fade-leave-active{
     transition:opacity .5s
  }
  </style>
  <div id="example">
     <button @click="toggle">切换组件</button>
     <transition name="fade" mode="out-in">
       <component :is="cName"></component>
     </transition>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       cName:componentA
     },
     component:{
       componentA:{
         template:'<p>组件A</p>'
       },
       componentB:{
         template:'<p>组件B</p>'
       }
     },
     methods:{
       taggle:function(){ //切换组件名称
         this.cName=this.cName=='componentA'?'componentB':'componentA'
       }
     }
  });
  </script>

运行上述代码,当每次单击“切换组件”按钮时,页面内容的变化都会有一个过渡的效果。

4)列表过渡:

实现列表过渡需要使用v-for和<transition-group>组件。该组件会以一个真实元素呈现,默认为一个<span>元素,可以通过tag属性更换为其他元素。列表中的元素需要提供唯一的key属性值。实现数字列表中插入数字和移除数字时的过渡效果的示例代码:
  <style type="text/css">
  //元素的样式
  .list-item{
     display:inline-block;
     margin-right:10px;
     background-color:darkgreen;
     width:30px;
     height:30px;
     line-height:30px;
     text-align:center;
     color:#ffffff;
  }
  //设置过渡效果
  .num-enter-active, .num-leave-active{
     transition: all 1s;
  }
  .num-enter, .num-leave-to{
     opacity:0;
     transform:translateY(30px);
  }
  </style>
  <div id="example">
     <div>
       <button v-on:click="add">插入一个数字</button>
       <button v-on:click="remove">移除一个数字</button>
       <transition-group name="num" tag="p">
         <span v-for="item in items" v-bind:key="item" class="list-item">{{item}}</span>
       </transition-group>
     </div>
  </div>
  <script type="text/javascript">
  var vm=new Vue({
     el: '#example',
     data:{
       items:[1,2,3,4,5,6],
       nextNum:7
     },
     methods:{
       randomNumber:function(){   //生成随机数索引
         return Math.floor(Math.random()*this.items.length);
       },
       add:function(){   //添加数字
         this.items.splice(this.randomNumber(),0,this.nextNum++);
       },
       remove:function(){   //移除数字
         this.items.splice(this.randomNumber(),1);
       }
     }
  });
  </script>

运行上述代码,当单击“插入一个数字”按钮时,会在下方的随机位置插入一个新的数字;当单击“移除一个数字”按钮时,会在下方的随机位置移除一个数字。

 

Copyright@dwenzhao.cn All Rights Reserved  备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com QQ:1608288659