1.渐进式vue
构建用户界面的渐进式框架
只关注视图层
2.vue中的两个核心点
- 响应的数据绑定:当数据发生改变时,自动更新视图
利用Object.definedProperty(该属性IE8不兼容)中的setter/getter代理数据,监控对数据的操作
- 组合的视图组件:UI界面映射为组件树;划分组件可维护、可重用、可测试
3.虚拟DOM
大量dom操作会很慢,通常在更新数据后重新渲染页面。如果只改变发生改变的部分,减少资源的浪费。
利用在内存中生成与真实DOM与之对应的数据结构,这个在内存中生成的结构称之为虚拟DOM.
当数据发生变化时,能够智能地计算出重新渲染组件的最小代价并应用到DOM操作上。
当数据改变时,渲染,然后对比两个虚拟DOM树改变的地方,以最小代价渲染出真实的DOM
虚拟DOM在js中的映射可以理解为对象嵌套对象
4.MVVM模式
利用其可以实现双向数据绑定
M:Model 数据模型
V:view视图模板
VM:view-Model视图模型,执行数据绑定及监听dom事件
5.vue实例
vue实例:每一个应用都是通过Vue这个构造函数创建根实例启动
new Vue(选项对象)
其中,需传入选项对象,对象包括挂载元素、数据、模板、方法等
el: 挂载元素选择器 String|HtmlElement
data:代理数据 Object|Function
methods:定义方法 Object
vue代理data数据:
每个vue都会代理其data对象里所有的属性,这些被代理的属性是响应式的,新添加的属性不具备响应功能,改变后不会更新视图
Vue实例自身的属性和方法
暴露自身的属性和方法,以$开头,如$el $data
简单实例:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <!--模板--> <div id="demo"> {{message}} </div> <script> //数据 let data={ message:"hello vue" //这里的数据用于呈现在页面中的数据 } //vm实例,通过vue声明一个参数,该参数为一个对象 var vm=new Vue({ el:"#demo", //html的挂载元素,里面直接写上选择器即可,一般用id,也可以用class的类名 data:data //上面定义的数据 }); //响应式数据绑定,则当数据发生改变时,页面也应该发生改变,这里可以用chrome浏览器的检查功能进行验证 console.dir(document); </script> </body> </html>
双向数据绑定:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <!--模板--> <div id="demo"> <input type="text" v-model="message" /> <!--//v-model为指令--> <p>{{message}}</p> </div> <script> //数据 let data={ message:"hello vue" //这里的数据用于呈现在页面中的数据 } //vm实例,通过vue声明一个参数,该参数为一个对象 var vm=new Vue({ el:"#demo", //html的挂载元素,里面直接写上选择器即可,一般用id,也可以用class的类名 data:data //上面定义的数据 }); //响应式数据绑定,则当数据发生改变时,页面也应该发生改变,这里可以用chrome浏览器的检查功能进行验证 </script> </body> </html>
Eg. Es6下: <!DOCTYPE html> <html xmlns:v-on="http://www.w3.org/1999/xhtml"> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <!--模板--> <div id="demo"> <span v-on:click="clickHandle()">{{message}}</span> <!--v-on指令可以实现绑定事件--> </div> <script> //数据 let obj={ message:"hello" } //声明式渲染 var vm=new Vue({ el:"#demo" , //el即为element,即让html的哪一部部分作为模板为其传入选择器,因其是id,则用#id名 data:obj , //data 是一个对象,将数据绑定在模板里 methods:{ clickHandle(){ alert("click") } } //这个浏览器里可以 }); console.log(vm); console.log(vm.$data); </script> </body> </html> Es5下: <!DOCTYPE html> <html xmlns:v-on="http://www.w3.org/1999/xhtml"> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <!--模板--> <div id="demo"> <span v-on:click="clickHandle()">{{message}}</span> <!--v-on指令可以实现绑定事件--> </div> <script> //数据 var obj={ message:"hello" } new Vue({ el:"#demo" , //el即为element,即让html的哪一部部分作为模板,为其传入选择器,因其是id,则用#id名 data:obj , //data 是一个对象,将数据绑定在模板里 methods: { //可以把事件处理函数都放在这里 clickHandle:function(){ //事件处理函数需要绑定在某个元素身上 alert("click"); } } }); </script> </body> </html>
6.声明式渲染
声明式渲染:只需要声明在哪里做什么,而无需关心如何实现
Eg. 求数组中每一项的倍数: 使用for循环拿出每一项,然后求值完成后,再放入另一数组中。
命令式渲染:需要以具体的代码表达在哪里做什么,怎么实现
Eg. 求数组中每一项的倍数:使用map方法关注如何求值
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <script> var arr=[1,2,3,4,5] //球数组中每一项的倍数,然后放入另一个数组中 /* //命令式地渲染 var newArr=[]; for(var i=0;i<arr.length;i++){ newArr.push(arr[i]*2); } */ //声明式渲染 var newArr=arr.map(function(item){ return item*2 ; }); console.log(newArr); </script> </body> </html>
Vue声明式渲染:初始化根实例,vue自动将数据绑定在DOM模板上。
7.指令
一种特殊的自定义行间属性
指令的职责:当其表达式的值改变时相应地将某些行为应用到dom上,如绑定事件处理函数
在vue中指令以v-开头
8.模板
- Html模板:
基于DOM的模板,模板都是可解析的有效的html
插值:
² 文本:使用双大括号{{value}}
作用:替换实例上的属性值,当值改变时,插值内容处会自动更新
² 原生的html:双大括号输出的是文本,不会解析html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="demo"> <span>{{html}}</span> </div> <script> //数据 let obj={ html:"<div>hello,miaov</div>" } var vm=new Vue({ el:"#demo", data:obj }) </script> </body> </html> 输出:<div>hello,miaov</div> 如果需要将文本解析成html,输出hello,miaov,则需要用到v-html指令,具体如下: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="demo"> <div v-html="html"></div>//v-html指令将文本解析成html </div> <script> //数据 let obj={ html:"<div>hello,miaov</div>" } var vm=new Vue({ el:"#demo", data:obj }) </script> </body> </html>
² 属性:使用v-bind进行绑定,可以响应变化
<!DOCTYPE html> <html xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="demo" v-bind:custom="abc"><!--可以通过v-bind绑定自定义属性--> <div v-html="html"></div><!--//v-html指令将文本解析成html--> </div> <script> //数据 let obj={ html:"<div>hello,miaov</div>", abc:1 } var vm=new Vue({ el:"#demo", data:obj }) </script> </body> </html>
<div @click="toDetail(item.id)" v-for="(item,index) in items" :key="index" :paramId="item.id"> </div> toDetail(id){ console.log(event.currentTarget.getAttribute("paramId")); this.$router.push({ path: "/***", query: { id: id } }); } ps:绑定属性值paramId,可以通过dom元素操作,获取当前元素属性方法,从而判断点击的哪一项,但不推荐此种写法; 最方便的直接在点击方法中传参即可;
² 使用JavaScript表达式: 写简单的表达式
<!DOCTYPE html> <html xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="demo" v-bind:custom="abc"><!--可以通过v-bind绑定自定义属性--> {{3+6}} {{true?"yes":"no"}} <div v-html="html"></div><!--//v-html指令将文本解析成html--> </div> <script> //数据 let obj={ html:"<div>hello,miaov</div>", abc:1 } var vm=new Vue({ el:"#demo", data:obj }) </script> </body> </html>
- 字符串模板:
template字符串:
template选项对象的属性,模板将会替换挂载的元素。挂载元素的内容都将被忽略。(模板和template不能共存)
// 根节点只能有一个 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="demo"> <span>miaov ketang</span> </div> <script> let obj={ html:"<div>hello,miaov</div>", abc:1 }; var str="<div>hello,{{abc}}</div>" //根节点只能有一个,即不能有并列的元素标签,但可以有包含的元素标签 var vm=new Vue({ el:"#demo", data:obj, template:str /*将新渲染的str替换掉前面的整个div*/ }) </script> </body> </html> 输出:hello,1
将html结构写在一对script标签中,设置type=“x-template”
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="demo"> <span>miaov ketang</span> </div> <script type="x-template" id="temp"> <div> hello {{abc}} <span>miaov</span> </div> </script> <script> let obj={ html:"<div>hello,miaov</div>", abc:1 }; var vm=new Vue({ el:"#demo", data:obj, template:"#temp" /*将新渲染的str替换掉前面的整个div*/ // }) </script> </body> </html>
- render模板:
render函数
render选项对象的属性
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="demo"> </div> <script> let obj={ html:"<div>hello,miaov</div>", abc:1 }; var vm=new Vue({ el:"#demo", data:obj, render:function(createElement){ return createElement( "ul", [ createElement("li",1), createElement("li",2), createElement("li",3) ] ); } /* render(){ //es6 }*/ }) </script> </body> </html> createElement(标签名,[数据对象],子元素); 子元素为文本或数组
数据对象属性:
class:{} //绑定class,和 `v-bind:class`一样的API
<!DOCTYPE html> <html xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> .red{ color:red; } .fontSize{ font-size: 50px; } </style> <script src="./vue.js"></script> </head> <body> <div id="demo"> <span class="fontSize" v-bind:class='{red:addClass}'>hello</span> <!--绑定的class和原生的class是可以共存的--> </div> <script> let obj={ addClass:true //这里的数据会影响前面页面内容的呈现 }; var vm=new Vue({ el: "#demo", data: obj }); </script> </body> </html>
style:{} //绑定样式,和`v-bind:style` 一样的API attrs:{} //添加行间属性 domProps:{} //DOM元素属性 on:{} //绑定事件 nativeOn:{} //监听原生事件 directives:{} //自定义指令 scopeSlots:{} //slot作用域 slot:{} //定义slot名称 key:”key” //给元素添加唯一标示 ref:”ref” //引用信息