第2章 数据绑定和第一个Vue应用
2.1 Vue实例与数据绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello World</title> </head> <body> <div id="app"> <input type="text" v-model="name" placeholder="你的名字"> <h1>你好,{{name}}</h1> </div> <script src="../vue.min.js"></script> <script type="application/javascript"> var app=new Vue({ el:"#app", data:{ name:"" } }) </script> </body> </html>
在input输入框中输入文字,会同步到h1标签中显示
2.1.1 实例与数据
创建实例通过var关键字,如下app标示一个实例,几乎所有代码都是一个对象,写入Vue实例选项内
var app=new Vue({
el:"#app",
data:{
name:""
}
});
通过CSS选择器来指定el
var app=new Vue({ el:document.getElementById('app') })
挂在成功后,就可以通过app.$el来访问元素。Vue提供了很多常用的实例属性与方法,都以$开头。
Vue实例也代理了data对象里的所有属性,可以用点(.)的方式访问,如:app.name
单独指向一个已有变量,它们之间默认建立了双向绑定。
<script type="application/javascript"> var myData={ a:1 }; var app=new Vue({ el:document.getElementById("app"),//CSS选择器方式 data:myData }) </script>
Vue选项
选项 | 是否必须 | 说明 |
el | 是 | 指定一个页面中已经存在的DOM元素来挂在vue实例,可以是HTMLElement,也可以是CSS选择器 |
Vue指令
指令 | 用途 | 说明 |
v-model | 数据绑定 | 他的值对应Vue实例的data选项中的name字段 |
2.1.2 生命周期
Vue生命周期钩子,常用的有:
- created:实例创建完成后调用,此阶段完成了数据的观测,但是无法通过$el元素来访问。
- mounted:el挂载到实例上后调用,一般第一个业务逻辑会在这里处理。
- beforeDestroy:实例销毁之前调用。主要绑定一些使用addEventLister监听的事件。
- 些钩子与el和data类似,也是作为选项写入Vue实例内,并且钩子的this指向是调用它的Vue实例
<script type="application/javascript"> var myData={ number:1 }; var app=new Vue({ el:document.getElementById("app"),//CSS选择器方式 data:myData, created:function () { console.log(this.number); console.log(this.$el);//挂载前是无法通过$方式来访问的 }, mounted:function () { console.log(this.$el); } }) </script>
刷新页面查看console日志输出
2.1.3 插值与表达式
使用大括号“{{}}”是最基本的文本插值方法,数据双向绑定后它会自动将我们双向绑定的数据实时显示出来。没有双向绑定时我们更新实例时,view上将会同步。
例:网页上显示时间
<div id="app"> {{ date }} </div> <script type="application/javascript"> var app=new Vue({ el:"#app", data:{ date:new Date() }, mounted:function () { var _this=this; this.timer=setInterval(function () { _this.date=new Date(); },1000); }, beforeDestroy:function () { if(this.timer){ clearInterval(this.timer); } } }) </script>
网页上时间将会自动更新
如果希望输出html标签,而不是纯文本,则使用v-html。如果将用户产生的内容使用v-html输出后,可能导致XSS攻击,一般可将“<>”进行转义
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>V-HTML</title> </head> <body> <script src="../vue.min.js"></script> <div id="app"> <span v-html="link"></span> </div> <script> var app=new Vue({ el:"#app", data:{ link:"<a href='#'>这里使用v-html渲染一个链接</a>" } }) </script> </body> </html>
如果想显示显示{{}}标签,而不进行替换,使用v-pre即可跳过这个元素和它的子元素的编译过程
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-pre</title> </head> <body> <div id="app"> <span v-pre>{{one}}</span> <p>{{ two }}</p> </div> <script src="../vue.min.js"></script> <script type="application/javascript"> var app = new Vue({ el: "#app", data: { one: "我的标签上有v-pre属性", two: "我的标签上没有v-pre属性" } }) </script> </body> </html>
在{{}}中使用JavaScript表达式进行简单的运算,三元运算等。Vue.js只支持单个表达式,不支持语句和流程控制。不能使用用户自定义的全局变量,只能使用Vue白名单内的全局 变量。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>简单运算</title> </head> <body> <div id="app"> <p>除10:{{number/10}}</p> <p>三元运算:{{isOK ? "确定" : "取消"}}</p> <p>split(,)之后join(--):{{text.split(',').reverse().join('--')}}</p> </div> <script src="../vue.min.js"></script> <script type="application/javascript"> var app=new Vue({ el:"#app", data:{ number:100, isOK:false, text:'123,456' } }) </script> </body> </html>
2.1.4 过滤器
在{{}}中可以使用管道符(|)对数据进行过滤,格式化文本,如字母全大写,货币千位使用逗号分隔等。过滤规则是自定义后通过给Vue实例添加filters选项来设置的。
如:格式化时间显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>插值</title> </head> <body> <script src="../vue.min.js"></script> <div id="app"> {{ date | formatDate }} </div> <script type="application/javascript"> //定义方法,在月份、日期、小时等小于10时前面补0 var padDate=function (value) { return value < 10? '0'+value:value; } var app=new Vue({ el:"#app", data:{ date:new Date() }, filters:{ formatDate:function (value) { var date=new Date(value); var year=date.getFullYear(); var month=padDate(date.getMonth()+1); var day=padDate(date.getDay()); var hours=padDate(date.getHours()); var minutes=padDate(date.getMinutes()); var seconds=padDate(date.getSeconds()); //将整理好的数据进行返回 return year+'-'+month+'-'+day+' '+hours+':'+minutes+":"+seconds; }, }, mounted:function () { //声明_this变量,保证作用域一致 var _this=this; this.timer=setInterval(function () { _this.date=new Date(); },1000); }, beforeDestroy:function () { if(this.timer){ //在Vue实例销毁前,清楚定时器; clearInterval(this.timer); } } }) </script> </body> </html>
格式化前:
格式化后:
过滤器可以串联和接收参数。
串联:{{ message | filterA | filterB }}
接收参数:{{ message | filterA("arg1","arg2") }},字符串arg1和arg2分别传递给过滤器的第二个和第三个参数,因为第一个数据是数据本身。
2.2 指令与事件
指令带有前缀v-,如v-if、v-html、v-pre等,主要功能:当表达式的值改变时,相应地将某些行为应用到DOM上。数据驱动dom是vue核心概念,非万不得已不要主动操作dom,只要维护好数据,dom的事交给vue处理。
v-if:当show的值为true时,p标签被插入,否则移除。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>指令与事件</title> </head> <body> <script src="../vue.min.js"></script> <div id="app"> <p v-if="show"> 显示该文本 </p> </div> <script type="application/javascript"> var app=new Vue({ el:"#app", data:{ show:true } }) </script> </body> </html>
v-bind:动态更新HTML元素上的属性,比如id,class等。如下示例将连接地址和图片地址都与数据进行绑定,当通过各种方式改变数据时,连接和图片都会自动更新。
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>指令与事件</title> </head> <body> <script src="../vue.min.js"></script> <div id="bind"> <!--将url连接和图片连接和数据进行绑定--> <a v-bind:href="url">连接</a> <img v-bind:src="imgurl" alt=""> </div> <script type="application/javascript"> var bind=new Vue({ el:"#bind", data:{ url:"https://cn.vuejs.org/", imgurl:"https://cn.vuejs.org/images/logo.png?_sw-precache=cf23526f451784ff137f161b8fe18d5a" } }); //当改变数据时,dom中的连接将同步改变 bind.url="https://www.baidu.com"; </script> </body> </html>
v-on:绑定事件监听器,可以做交互功能。表达式除了方法名,也可以用内联表达式。<button v-on:click="show = false ”〉点击隐藏</ button>。
在普通元素上,v-on可以监听原生DOM事件,有click、dblclick、keyup、mousemove等。表达式可以是一个方法名,方法写在Vue实例的methods属性内,并且是函数的形式。函数内的this指Vue实例本身。
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>v-on</title> </head> <body> <script src="../vue.min.js"></script> <div id="app"> <p v-if="show">这是一段文本</p> <!--将click事件和handleClose方法绑定--> <button v-on:click="handleClose">点击隐藏</button> </div> <script type="application/javascript"> var app = new Vue({ el: "#app", data: { show: true, }, methods: { handleClose: function () { //修改数据为false后,页面中将隐藏p标签 this.show = false; } } }) </script> </body> </html>
Vue将methods里的方法也进行了代理,所以也可以像访问vue数据那样来调用方法。
2.3 语法糖(即缩写)
语法糖指在不影响功能的情况下,添加某种方法实现同样效果,从而方便程序开发。
v-bind ---> ":"
v-on ---> "@"
<a v-bind:href="url">连接</a> <img v-bind:src="imgurl" alt=""> <button v-on:click="handleClose">点击隐藏</button> <!--缩写为--> <a :href="url">连接</a> <img :src="imgurl" alt=""> <button @:click="handleClose">点击隐藏</button>