每一個Vue程序都要進行實例化以後使用,實例有兩種。javascript
對於M-V-VM模型,由M-V-C模型衍生。css
只不過M-V-C中的C在M-V-VM中變爲了VM。在M-V-VM中VM就是邏輯操做。經過VM,咱們去控制視圖和數據之間 的變化。html
構建一個Vue實例逐步解析vue
//建立一個Vue實例 var vm= new Vue(); -->這個Vue實例就是VM //掛載一個DOM元素,做爲數據展現的容器 -->這個el選項就是V var vm =new Vue({ el:'#XXX' }) //設置一個data選項,做爲一個對象,只保存數據,而且其屬性被Vue實例代理。 -->這個data對象就是M var vm =new Vue({ el:'#Name', data:{ key:value, ..... } })
每一個Vue實例都是經過構造函數Vue建立一個Vue的根實例java
var vm = new Vue({ //options })
在實例化Vue時,須要傳入一個選項對象,它能夠包含數據
(data),模板
,掛載元素
(el),方法
,生命週期鉤子
等選項。web
Vue就是用選項對象中的data,created...等選項,來建立你想要的行爲。這些選項能夠在Vue中的API文檔查看。express
能夠擴展
的Vue構造器,從而用預約義
選項建立複用
的組件構造器
數組
//定義一個組件構造器 var myComponent =Vue.exted({ //擴展選項 }); //全部的 myComponent的實例都將以擴展的組件構造器建立 var mycomponentExp=new myComponent(); //mycomponentExp是一個組件
因此咱們如今知道,全部Vue.js組件都是被擴展的Vue構造器的實例瀏覽器
//html代碼 <div id="app"> <p>{{name}}</p> </div> //javascript代碼 var vm = new Vue({ el: '#app', data: { name: 'huang' } });
經過上面的代碼思考,爲何能夠在視圖中直接使用name屬性?app
每一個Vue實例都會代理其選項對象中data對象的全部屬性。
這就關於Vue的另外一個概念,數據代理
所謂數據代理(另稱數據劫持),指的是在訪問或修改對象的某個屬性時,經過一段代碼攔截這個行爲,並進行額外的操做或者返回修改結果。比較典型的是Object.defineProperty()
和E2015的Proxy
對象。
對於數據劫持,最著名的應用就是雙向綁定。
Vue2.x中使用的就是Object.defineProperty()
(Vue 3.x改用Proxy
進行實現)
這裏只做大概瞭解。
詳細: 參考末尾連接
因此,Vue實例經過數據劫持,代理data對象的屬性。咱們能夠經過Vue實例來訪問data對象中的屬性。
上面的代碼完整寫法
//html代碼 <div id="app"> <p>{{this.$data.name}}</p> //經過vm.$data訪問源數據 <p>{{$data.name}}</p> //上一種的簡寫 <p>{{this.name}}</p> //與上等價,Vue實例代理data屬性 <p>{{name}}</p> //上一種的簡寫 </div> //javascript代碼 var vm = new Vue({ el: '#app', data: { name: 'huang' } }); //注1:this指向的是掛載在該元素的或是該元素的祖先元素的Vue實例。這裏指向vm //注2:data對象中,以$或_開頭的屬性不會被Vue實例代理,由於它們是Vue定義私有屬性的寫法可能和 Vue 內置的屬性、API 方法衝突。能夠經過$data.privateName來訪問這些屬性 //注3:privateName就是$,_ 開頭的屬性。
注意:只有這些被實例代理的屬性是與視圖響應的,代理的屬性變化,源數據也會發生變化。同理,源數據變化,代理的屬性也會變化
若是是實例被建立後添加新屬性給實例,它是不會觸發視圖更新的。
//html代碼 <div id="app"> <p>{{name}}</p> </div> //javascript代碼 var mydata = { a: 1, name: 'huang' } var vm = new Vue({ el: '#app', data: mydata }); //視圖響應數據,發生變化。代理屬性改變,mydata對象name屬性也改變 vm.name = 'new'; //建立Vue實例後給實例添加屬性,視圖對其無響應 vm.age = 22;
指令(Directives)是帶有v-前綴的特殊屬性。指令屬性的值預期是Javascript表達式 (這點很重要 !)v-for例外。
藉助尤雨溪的話:基於指令的數據綁定使得具體的DOM操做都被合理地封裝在指令定義中
簡單來講,指令的指責就是當其表達式的值改變時相應地將某些行爲應用到DOM上。
只須要將指令做爲html元素的屬性來使用就能夠了,
例如:
<div v-if="expression">
指令只對當前所在的這個元素起做用,它在哪一個元素上,就對哪一個元素作出對應的DOM操做。
我更願意將指令的值叫作指令的"表達式",爲何這麼說?
例如:
<div v-if="expression">
expression在模板中所對應的是this.expression
眼熟嗎?這就是Vue實例代理data的屬性。
既然是表達式,那麼就必定會有返回值
它的值被傳給指令,指令根據表達式返回的結果來決定所在的元素進行怎樣的操做。
而表達式的變量
,都來自Vue實例代理的data選項的屬性。
v-if:依照起Value
是否爲Truthy來決定是否渲染此元素
<div v-if="expression"> {{...}} </div>
若是this.expression值爲真,元素則被插入到Dom中,this.expression爲假,則當前元素會從Dom中移出。
當咱們有多個元素須要用同一個判斷怎麼辦?
<div v-if="expression"> ..... </div> <p v-if="expression"> ..... </p>
這種寫法,有些繁瑣。咱們能夠用<template>標籤,根據元素的株連性
把這個標籤做爲父元素,操做這個元素,而且此元素在渲染後不會影響到頁面結構。
<template v-if="expression"> <div> ..... </div> <p> ..... </p> </template>
v-show:依照起Value
是否爲Truthy來決定改變其Css的display屬性值。
和v-if
在頁面上的效果相同,都是決定元素是否顯示,可是二者的渲染方式不一樣。
v-if
在初始渲染時條件若爲假,則什麼也不作,直到第一次條件爲真,纔會渲染元素並將其插入DOM中
v-show
無論初始條件是什麼,都會對元素進行一次初始渲染,在接下來的操做中,就是Css的切換。
那麼,咱們知道,移除元素會致使DOM樹變化,產生一次迴流(reflow)
,它會從新計算樣式和渲染DOM樹。
而改變Css屬性這類值改變某個節點的一些樣式,只會引起重繪(repaint)
,只會繪製這個元素。
這麼一對比,v-if頻繁切換對瀏覽器性能開銷影響更大,因此建議在運行時,若是條件的Truthy
頻繁的切換,則咱們應該優先考慮v-show。而運行時條件不多改變,我更以爲是條件鎖死
,v-if的Truthy爲false時,則更推薦v-if,由於它沒有初始渲染開銷。
v-else:v-if的else語句塊,當v-if的expression的值爲Truthy,則執行v-else指令,將元素渲染在頁面上,不然,不渲染。
使用注意:必須緊跟在v-if後,不然不會有任何做用
v-for:指令基於源數據重複渲染該元素或模板塊。
數組迭代: 用 v-for
指令根據一組數組的選項列表進行渲染
支持第二個參數爲當前項的索引
語法:
v-for="(every, index) in expression"
every
:能夠用任意名字,表示迭代的數組元素的別名,能夠用這個別名訪問數組元素
index
:任意名稱,表示迭代的數組索引的別名,能夠用這個別名訪問數組索引
expression: 要迭代的源數據數組
實例:
<div v-for="i in arr"> {{i}} </div> var vm = new Vue({ el: '#app', data: { arr: [{ name: 'li' }, { name: 'huanghao' }, { name: 'wang' }] } })
對象迭代:v-for
經過一個對象的屬性來迭代
還能夠有兩個額外參數,第二個參數爲鍵名,第三個參數爲索引(這個索引更像是for循環的 i)
語法:
v-for="(value, key, index) in object"
value:任意名稱,表示迭代的對象屬性值的別名,能夠用這個別名訪問對象屬性值
key:任意名稱,表示迭代的對象的鍵值的別名,能夠用這個別名訪問對象鍵值
index:任意名稱,表示迭代的對象的索引的別名 ..
object:要迭代的源數據對象。
實例
<div id="app"> <div v-for="(value,key1,index1) in obj"> {{value}} --{{key1}} ---{{index1}} </div> </div> var vm = new Vue({ el: '#app', data: { obj: { name: 'huang', age: 22, sex: 'man' } } })
在v-for
塊中,擁有對父做用域屬性的徹底訪問權限,v-for塊中,其內部
的模板語法,能夠將v-for塊中別名做爲變量使用
綁定型指令會有參數,參數是綁定的屬性或事件。
v-bind:
綁定一個屬性
語法: v-bind:prop="expression
"
prop:綁定的屬性
expression:表達式
v-bind綁定一個屬性,若是expression的值爲真,則表達式的值
被添加到綁定的屬性上,不然不被添加
以一個<img>元素的src屬性舉例
<img alt="" :src="src"> // <img alt="" :src="1.img"> new Vue({ el: '#app', data: { Src:'1.img' } });
v-bind綁定了一個src屬性,而且屬性值爲 this.Src,當表達式的值爲真時,src屬性的屬性值就是this.Src
v-bind綁定class和style有些特殊,可使用對象和數組形式綁定
綁定html元素的class
對象語法:
語法: v-bind:class="{className:expression,className2:expression2...}"
計算expression是否爲Truthy,若是爲真,則className/className2將被添加到class屬性中,不然不會添加.
也能夠直接綁定data選項中的一個對象
<div id="app" :class="classObject"></div> var app = new Vue({ el: '#app', data:{ classObject: { active: true, 'text-danger': false } } })
或者綁定一個返回對象
的計算屬性
<div id="app" :class="classObject"></div> var app = new Vue({ el: '#app', data: { isActive: true, error: null }, computed: { classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal', } } } })
數組語法:和對象語法有不一樣,它添加的類名是被實例代理的data對象中的屬性的屬性值,而且此屬性值必須的字符串。
例子
<div v-bind:class="[app,cls]" //<div class="sss"></div> > new Vue({ el: '#app', data: { cls:"sss", app:true } });
爲了更加方便,還能夠在數組中使用對象語法,對象語法在模板中照常解析
例子
<div v-bind:class="[app,cls,expression]" //<div class="sss active error click"></div> > new Vue({ el: '#app', data: { name: '黃昊', src:'1.img', expression:{ active:"class1", error:'class2', click:789 }, cls:"sss", app:true } });
關於綁定style
對象語法: v-bind:style="{style1:expression,style2:expression2}"
style1/style2:爲style屬性添加的樣式名
expression/expression2:表達式的值必須爲字符串,數字例外。表達式的值符合樣式屬性。
舉例
<div :style="{color:'red'}" //<div style="color: red;"></div> > </div> //上方等同下方 <div :style="{color:red}" > </div> new Vue({ el: '#app', data: { red:'red', } });
或者爲了讓模板更加清晰,咱們直接給定一個對象表達式
舉例
<div :style="styleObject" ///<div style="color: red; font-size: 16px;"></div> > </div> new Vue({ el: '#app', data: { styleObj:{ color:'redd fontSize:'16px'//樣式按照Js的寫法,由於咱們一切模板語法的操做都是基於掛載的Dom對象 } } });
數組語法:將多個樣式對象應用到同一個元素上
須要注意的是,數組語法中的元素必須是對象形式。
例子:
<div :style="[styleObj,styleObj2]" > </div> new Vue({ el: '#app', data: { styleObj:{ color:'red', fontSize:'16px' }, styleObj2:{ width:'100px', height:'100px' } } });
在Vue2.3.0+,style綁定的屬性提供一個包含多個值 的數組,經常使用於提供多個帶前綴的值
例子
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex','inline','a'] }"></div> //<div style="display: inline;"></div>
這樣寫只會渲染數組中最後一個被瀏覽器支持的值
咱們經過computed
選項來添加計算屬性
對於任何複雜的邏輯,都應該使用計算屬性
當咱們在computed聲明一個計算屬性時,咱們提供的函數將用做vm.computed_prop的getter函數 當計算屬性被調用時,觸發這個函數執行。
怎麼使用?vm.computed_prop 簡化--->computed_prop
組件化思惟
組件化針對的是頁面中的整個完整的功能模塊劃分 (項目的分工)
組件的概念( 一個文件 )
組件是一個html、css、js、image等外鏈資源,這些部分組成的一個聚合體
優勢:代碼複用,便於維護
劃分組件的原則:複用率高的,獨立性強的
組件基礎:
vue.js文件中暴露出一個Vue的構造器函數, 這個函數的做用,是用來實例化出來一個實例, 這個實例也是一個組件, 咱們稱之爲 '根實例'
Vue爲了擴展功能, 給了一個方法 , 這個方法叫 extend Vue.extend()
組件的表現形式是標籤
使用組件必須遵照H5的標準,組件須要合法,必須註冊組件。
組件使用前必須註冊
組件的註冊
全局註冊
局部註冊
在使用組件時,要注意會不會與原有的標籤衝突