new Vue创建Vue实例,el代表Vue接管的DOM的所有显示,data里面用于存放数据,由于Vue接管了app部分,所以会对DOM里面的语法进行分析,发现运用了{{}}插值表达式,就会去data里面寻找对应的数据,利用这个数据替换掉这个插值表达式
同时Vue也可以分析出DOM所绑定的事件,所以当点击DOM元素的时候,就会去Vue实例寻找对应的方法
程序的入口便是从Vue实例开始执行,Vue就是一个根实例,Vue中的每一个组件也是一个Vue实例,当我们创建一个组件的时候,Vue的底层也会将它编译成一个Vue的实例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello World</title> <script src="./vue.js"></script> </head> <body> <div id="app"> <div v-on:click="handleClick"> {{message}} </div> <item></item> </div> </body> <script> //组件也是Vue实例 Vue.component('item',{ template:'<div>hello world</div>' }) var vm = new Vue({ //接管的DOM el:'#app', //数据,实例属性,引用的时候便是$data data:{ message:'Derrick' }, //方法 methods:{ handleClick:function(){ alert("hello") } } }) </script> </html>
computed计算属性,下面的fullName便是计算而来,计算属性具有一定的缓存机制,例如这里的firstName与lastName不改变的话,就不会再次计算,由于age不属于计算范围,所以改变的时候不会再次计算,当改变firstName的时候才会再次计算
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> </head> <body> <div id="app"> {{fullName}} {{age}} </div> </body> <script> var vm = new Vue({ el:"#app", data:{ firstName:"Derrick", lastName:"Xu", age:28 }, //计算属性 computed:{ //fullName是经过计算得来的, fullName:function(){ console.log("进行计算"); return this.firstName+" "+this.lastName; } } }) </script> </html>methods方法属性,也可以实现4.1中拼接fullName的功能,但是性能比计算属性较差,因为fullName没有改变的之后依旧需要重新调用方法,没有缓存机制
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> </head> <body> <div id="app"> <!--由于是方法,需要加上()--> {{fullName()}} {{age}} </div> </body> <script> var vm = new Vue({ el:"#app", data:{ firstName:"Derrick", lastName:"Xu", age:28 }, //方法,同样可以实现fullName功能 methods:{ fullName:function(){ return this.firstName+" "+this.lastName } } }) </script> </html>侦听器,当firstName或者lastName改变的时候重新给fullName赋值,当在控制台改变age的时候是不会调用侦听器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> </head> <body> <div id="app"> <!--由于是方法,需要加上()--> {{fullName()}} {{age}} </div> </body> <script> var vm = new Vue({ el:"#app", data:{ firstName:"Derrick", lastName:"Xu", fullName:"Derrick Xu", age:28 }, //侦听器,当firstName或者lastName改变的时候重新给fullName赋值 watch:{ firstName:function(){ this.fullName = this.firstName+" "+this.lastName }, lastName:function(){ this.fullName = this.firstName+" "+this.lastName } } }) </script> </html>computed计算属性,将fullName定义成一个对象,插值表达式去读取fullName的时候会转到fullName的get方法,set方法用于设置属性值,接收外部传递过来的value
当在控制台设置fullName的时候,将接收到的value拆分赋值给firstName跟lastName,由于计算属性具有一定的缓存机制,firstName跟lastName改变了,所以会重新计算fullName
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> </head> <body> <div id="app"> {{fullName}} </div> </body> <script> var vm = new Vue({ el:"#app", data:{ firstName:"Derrick", lastName:"Xu", }, computed:{ //将fullName写成一个对象 fullName:{ //插值表达式去读取fullName的时候会转到fullName的get方法 get:function(){ return this.firstName+" "+this.lastName; }, //设置属性值,接收外部传递过来的value set:function(value){ //拆分value为数组 var arr = value.split(" "); this.firstName = arr[0]; this.lastName = arr[1]; console.log(value); } } } }) </script> </html>
前提说明:点击Hello World变成红色,再次点击变回原色
:class="{activated: isActivated}说明div需要有个class,名字为activated,class是否起作用取决于isActivated
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> <style> .activated{ color:red; } </style> </head> <body> <div id="app"> <!--说明div需要有个class,名字为activated,class是否起作用取决于isActivated--> <div @click="handleDivClick" :class="{activated: isActivated}"> Hello world </div> </div> </body> <script> var vm = new Vue({ el:"#app", data:{ isActivated:false }, methods:{ handleDivClick:function(){ //改变isActivated的值,决定activated class是否显示 this.isActivated = !this.isActivated; } } }) </script> </html>class="[activated]"说明div需要有个class,class取值显示的内容为activated里面的内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> <style> .activated{ color:red; } </style> </head> <body> <div id="app"> <!--说明div需要有个class,class显示的内容为activated里面的内容--> <div @click="handleDivClick" :class="[activated]"> Hello world </div> </div> </body> <script> var vm = new Vue({ el:"#app", data:{ activated:"" }, methods:{ handleDivClick:function(){ //将变量设置为activated,所以class的值便会取到这个activated字符串作为class的名字 if(this.activated === "activated"){ this.activated =""; }else{ this.activated = "activated"; } } } }) </script> </html>:style=“styleObj"使用的是对象,这里说明让div有样式,样式是颜色是红色。:style=”[styleObj]"使用的是数组,说明div的style由数组里面的对象决定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> </head> <body> <div id="app"> <!--使用对象--> <div :style="styleObj" @click="handleDivClick"> Hello world </div> <!--使用数组--> <div :style="[styleObj,{fontSize:'20px'}]" @click="handleDivClick"> Hello world </div> </div> </body> <script> var vm = new Vue({ el:"#app", data:{ //说明让div有样式,样式是颜色是红色 styleObj:{ color:"black" } }, methods:{ handleDivClick:function(){ this.styleObj.color = this.styleObj.color==="black" ? "red" : "black"; } } }) </script> </html>
v-if="XXX"后面接的依旧是js表达式,条件软件便是通过v-if结合js表达式返回值去决定一个标签是否显示与存在,v-show类似于v-if,两者都可以控制标签是否显示,但是有区别,当都为false的时候,v-show依旧会渲染到页面上,但是display设置成了none
v-if可以与v-else结合一起使用,但是中间不能被其他标签隔开
一开始show为false,显示的是邮箱名,输入完之后去控制台修改show为true,显示用户名,但是input框没有清空,这是vue会尽量让DOM元素复用,这时候需要给input加入key属性,让vue知道这是唯一的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Derrick</title> <script src="./vue.js"></script> </head> <body> <div id="app"> <div v-if="show"> 用户名:<input/> <!--加入key值--> 用户名:<input key="username"/> </div> <div v-else> 邮箱名:<input/> <!--加入key值--> 邮箱名:<input key="email"/> </div> </div> </body> <script> var vm = new Vue({ el:"#app", data:{ show:false, } }) </script> </html>
key尽量使用唯一的,但是不建议使用index,一般使用后台数据库返回的id,使用key值可以提高性能,用v-for更新已渲染的元素列表的时候,会使用就地复用的策略。这就是说列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改了就重新渲染,不然就复用之前的元素
<body> <div id="app"> <div v-for="(item,index) of list" :key="item.id"> {{item.text}} ---- {{index}} </div> </div> </body> <script> var vm = new Vue({ el:"#app", data:{ list:[ { id:"1", text:"hello" }, { id:"2", text:"Derrick" }, { id:"3", text:"Jessica" } ] } }) </script>不建议使用下标的添加,数据会添加成功,但是页面不会更新数据,vue提供了7个操作列表的方法:pop是删除数据最后一项,push往数组添加一条数据,shift删除数组第一项,unshift往数组第一项增加一些内容,splice用于截取数组,sort对数组进行排序,reverse对数组进行取反
所以7.3.1中的Derrick被删除,从第一项这里添加新的数据
template模板占位符可以帮我们包裹元素用于循环,但是它不会被渲染到页面上
<body> <div id="app"> <template v-for="(item,index) of list" :key="item.id"> <div> {{item.text}} ---- {{index}} </div> <span> {{item.text}} </span> </template> </div> </body> <script> var vm = new Vue({ el:"#app", data:{ list:[ { id:"1", text:"hello" }, { id:"2", text:"Derrick" }, { id:"3", text:"Jessica" } ] } }) </script>在控制台改变对象属性值的时候,会实时更新
插入属性键值对的时候页面不会实时刷新
set方法是Vue全局的方法,同时也是vue的实例方法,利用set方法弥补7.5.3问题
例子中说明是将第一项的值改为5,将第二项的值改为10