Vue近幾年來特別的受關(guān)注,三年前的時(shí)候angularJS霸占前端JS框架市場(chǎng)很長時(shí)間,接著react框架橫空出世,因?yàn)樗幸粋€(gè)特性是虛擬DOM,從性能上碾軋angularJS,這個(gè)時(shí)候,vue1.0悄悄
的問世了,它的優(yōu)雅,輕便也吸引了一部分用戶,開始收到關(guān)注,16年中旬,VUE2.0問世,這個(gè)時(shí)候vue不管從性能上,還是從成本上都隱隱超過了react,火的一塌糊涂,這個(gè)時(shí)候,angular
開發(fā)團(tuán)隊(duì)也開發(fā)了angular2.0版本,并且更名為angular,吸收了react、vue的優(yōu)點(diǎn),加上angular本身的特點(diǎn),也吸引到很多用戶,目前已經(jīng)迭代到5.0了。
學(xué)習(xí)vue是現(xiàn)在前端開發(fā)者必須的一個(gè)技能。
js框架幫助開發(fā)者寫js邏輯代碼,在開發(fā)應(yīng)用的時(shí)候js的功能劃分為如下幾點(diǎn):
渲染數(shù)據(jù)
操作dom(寫一些效果)
操作cookie等存儲(chǔ)機(jī)制api
在前端開發(fā)中,如何高效的操作dom、渲染數(shù)據(jù)是一個(gè)前端工程師需要考慮的問題,而且當(dāng)數(shù)據(jù)量大,流向較亂的時(shí)候,如何正確使用數(shù)據(jù),操作數(shù)據(jù)也是一個(gè)問題
而js框架對(duì)上述的幾個(gè)問題都有自己趨于完美的解決方案,開發(fā)成本降低。高性能高效率。唯一的缺點(diǎn)就是需要使用一定的成本來學(xué)習(xí)。
vue是漸進(jìn)式JavaScript框架
“漸進(jìn)式框架”和“自底向上增量開發(fā)的設(shè)計(jì)”是Vue開發(fā)的兩個(gè)概念
Vue可以在任意其他類型的項(xiàng)目中使用,使用成本較低,更靈活,主張較弱,在Vue的項(xiàng)目中也可以輕松融匯其他的技術(shù)來開發(fā),并且因?yàn)閂ue的生態(tài)系統(tǒng)特別龐大,可以找到基本所有類型的工
具在vue項(xiàng)目中使用
特點(diǎn):易用(使用成本低),靈活(生態(tài)系統(tǒng)完善,適用于任何規(guī)模的項(xiàng)目),高效(體積小,優(yōu)化好,性能好)
Vue是一個(gè)MVVM的js框架,但是,Vue 的核心庫只關(guān)注視圖層,開發(fā)者關(guān)注的只是m-v的映射關(guān)系
Vue的很多api、特性都與angularJS相似,其實(shí)是因?yàn)閂ue在開發(fā)的時(shí)候借鑒了很多AngularJS中的特點(diǎn),而AngularJS中固有的缺點(diǎn),在Vue中已經(jīng)解決,也就是青出于藍(lán)而勝于藍(lán),Vue的學(xué)習(xí)
成本比AngularJS低很多,因?yàn)閺?fù)雜性就低
AngularJS是強(qiáng)主張的,而Vue更靈活
Vue的數(shù)據(jù)流是單向的,數(shù)據(jù)流行更清晰
Angular里指令可以是操作dom的,也可以封裝一段結(jié)構(gòu)邏輯代碼,例如:廣告展示模塊
Vue中的指令只是操作dom的,用組件來分離結(jié)構(gòu)邏輯
AngularJS的性能比不上Vue
Vue不支持IE8,因?yàn)槭褂昧薊S5的很多特性
可以直接通過script標(biāo)簽來引入vue.js,有開發(fā)版本和生產(chǎn)版本,開發(fā)版本一般我們?cè)陂_發(fā)項(xiàng)目的時(shí)候引入,當(dāng)最后開發(fā)完成上線的時(shí)候引入生產(chǎn)版本,開發(fā)版本沒有壓縮的,并且有很多提
示,而生產(chǎn)版本全部刪掉了
在Vue中提供了一個(gè)腳手架(命令行工具)可以幫我們快速的搭建基于webpack的開發(fā)環(huán)境...
每一個(gè)應(yīng)用都有一個(gè)根實(shí)例,在根實(shí)例里我們通過組件嵌套來實(shí)現(xiàn)大型的應(yīng)用
也就是說組件不一定是必須的,但是實(shí)例是必須要有的
在實(shí)例化實(shí)例的時(shí)候我們可以傳入一個(gè);配置項(xiàng),在配置項(xiàng)中設(shè)置很多屬性方法可以實(shí)現(xiàn)復(fù)雜的功能
在配置中可以設(shè)置el的屬性,el屬性代表的是此實(shí)例的作用范圍
在配置中同過設(shè)置data屬性來為實(shí)例綁定數(shù)據(jù)
摘自阮一峰博客
mvc 分為三層,其實(shí)M層是數(shù)據(jù)模型層,它是真正的后端數(shù)據(jù)在前端js中的一個(gè)映射模型,他們的關(guān)系是:數(shù)據(jù)模型層和視圖層有映射關(guān)系,model改變,view展示也會(huì)更改,當(dāng)view產(chǎn)生用戶
操作或會(huì)反饋給controller,controller更改model,這個(gè)時(shí)候view又會(huì)進(jìn)行新的數(shù)據(jù)渲染
這是純純的MVC的模式,但是很多框架都會(huì)有一些更改
前端mvc框架,如angularjs,backbone:
會(huì)發(fā)現(xiàn),用戶可以直接操作controller(例如用戶更改hash值,conrtoller直接監(jiān)聽hash值變化后執(zhí)行邏輯代碼,然后通知model更改)
控制器可以直接操作view,如果,讓某一個(gè)標(biāo)簽獲得進(jìn)入頁面獲得焦點(diǎn),不需要model來控制,所以一般會(huì)直接操作(angularJS,指令)
view可以直接操作model (數(shù)據(jù)雙向綁定)
MVP:
view和model不能直接通信,所有的交互都由presenter來做,其他部分的通信都是雙向的
view較薄 ,presenter較為厚重
MVVM:
MVVM和MVP及其相似,只是view和viewmodel的通信是雙向綁定,view的操作會(huì)自動(dòng)的像viewmodel通過
在vue中可以通過v-for來循環(huán)數(shù)據(jù)的通知循環(huán)dom,語法是item in/of items,接收第二個(gè)參數(shù)是索引 (item,index) of items,還可以循環(huán)鍵值對(duì),第一個(gè)參數(shù)是value,第二個(gè)是key,第三
個(gè)依然是索引
在vue中還有v-on來為dom綁定事件,在v-on:后面加上要綁定的事件類型,值里可以執(zhí)行一些簡單javascript表達(dá)式:++ -- = ...
可以將一些方法設(shè)置在methods里,這樣就可以在v-on:click的值里直接寫方法名字可以,默認(rèn)會(huì)在方法中傳入事件對(duì)象,當(dāng)寫方法的時(shí)候加了()就可以傳參,這個(gè)時(shí)候如果需要事件對(duì)象,那
就主動(dòng)傳入$event
v-on綁定的事件可以是任意事件,v-on:可以縮寫為@
為什么在 HTML 中監(jiān)聽事件?
你可能注意到這種事件監(jiān)聽的方式違背了關(guān)注點(diǎn)分離 (separation of concern) 這個(gè)長期以來的優(yōu)良傳統(tǒng)。但不必?fù)?dān)心,因?yàn)樗械?Vue.js 事件處理方法和表達(dá)式都嚴(yán)格綁定在當(dāng)前視圖的
ViewModel 上,它不會(huì)導(dǎo)致任何維護(hù)上的困難。實(shí)際上,使用 v-on 有幾個(gè)好處:
在vue中,我們使用mustache插值({{}})來將數(shù)據(jù)渲染在模板中
使用v-once指令可以控制只能插入一次值,當(dāng)數(shù)據(jù)變化的時(shí)候,模板對(duì)應(yīng)的視圖不更新
使用v-html指令可以解析html格式的數(shù)據(jù)
在html標(biāo)簽屬性里不能使用mustache插值,這個(gè)時(shí)候給元素添加動(dòng)態(tài)屬性的時(shí)候使用v-bind來綁定屬性,可以縮寫成:
在使用v-bind綁定class和內(nèi)聯(lián)樣式的時(shí)候,vue做了一些優(yōu)化,可以使用對(duì)象語法和數(shù)組的語法來控制
防止表達(dá)式閃爍:
v-cloak
給模板內(nèi)的元素添加v-cloak屬性后,元素在vue沒有加載完的時(shí)候就有這個(gè)屬性,當(dāng)vue加載完成后這個(gè)屬性就消失了,所以我們可以給這個(gè)屬性設(shè)置css樣式為隱藏
<style> [v-cloak]{ visibility: hidden; } </style>
v-text/v-html
v-text會(huì)指定將模板內(nèi)元素的textContent屬性替換為指令值所代表的數(shù)據(jù),也可以用于防止閃爍
v-html可以解析標(biāo)簽,更改元素的innerHTML,性能比v-text較差
v-pre
跳過元素和其子元素的編譯過程,可以用來顯示mustache
這是一款vue的插件,可以用來進(jìn)行數(shù)據(jù)交互,支持的請(qǐng)求方式:GET/POST/JSONP/OPTIONS...
這個(gè)插件官方宣布不在更新維護(hù),也就是說盡量不要使用
有的時(shí)候我們需要在模板中使用數(shù)據(jù)a,這個(gè)時(shí)候就需要用到表達(dá)式,但是有的地方我們需要對(duì)a數(shù)據(jù)進(jìn)行一些簡單的處理后才能使用,那么我們就會(huì)在表達(dá)式中寫一些js邏輯運(yùn)算```<div id="example">{{ message.split('').reverse().join('') }}</div>```這樣我們的維護(hù)就會(huì)非常困難,也不便于閱讀那め我們就可以在methods里設(shè)置一個(gè)方法,在模板的表達(dá)式中使用這個(gè)方法```<p>Reversed message: "{{ reversedMessage() }}"</p>// 在組件中methods: {reversedMessage: function () { return this.message.split('').reverse().join('')}}```但是這個(gè)時(shí)候,只要vm中有數(shù)據(jù)變化,這個(gè)變化的數(shù)據(jù)可能和我們關(guān)注的數(shù)據(jù)無關(guān),但是vm都會(huì)重新渲染模板,這個(gè)時(shí)候表達(dá)式中的方法就會(huì)重新執(zhí)行,大大的影響性能這個(gè)時(shí)候其實(shí)我們可以使用監(jiān)聽器里完成:在vm實(shí)例中設(shè)置watch屬性,在里面通過鍵值對(duì)來設(shè)置一些監(jiān)聽,鍵名為數(shù)據(jù)名,值可以是一個(gè)函數(shù),這個(gè)函數(shù)在數(shù)據(jù)改變之后才會(huì)執(zhí)行,兩個(gè)參數(shù)分別是性格前的值和更改后的值
a: function (val, oldVal) { console.log('new: %s, old: %s', val, oldVal) }
值還可以是一個(gè)方法名字,當(dāng)數(shù)據(jù)改變的時(shí)候這個(gè)方法會(huì)執(zhí)行當(dāng)數(shù)據(jù)為object的時(shí)候,object的鍵值對(duì)改變不會(huì)被監(jiān)聽到(數(shù)組的push等方法可以),這個(gè)時(shí)候需要設(shè)置深度監(jiān)聽:
c: { deep:true, handler:function (val, oldVal) { console.log('new: %s, old: %s', val, oldVal) } },
監(jiān)聽的handler函數(shù)前面的這幾種寫法都是在數(shù)據(jù)變化的時(shí)候才會(huì)執(zhí)行,初始化的時(shí)候不會(huì)執(zhí)行,但是如果設(shè)置immediate為true就可以了
num:{ immediate:true, handler:function(val){ this.nums = val*2 } }
我們?cè)诨氐缴厦娴膯栴},用監(jiān)聽器加上immediate屬性就可以做到該效果,但是大家可以看到的是邏輯稍稍有點(diǎn)復(fù)雜watch還可以通過實(shí)例對(duì)象直接使用:vm.$watch,返回一個(gè)取消監(jiān)聽的函數(shù),這個(gè)函數(shù)執(zhí)行之后會(huì)取消監(jiān)聽我們一般都會(huì)用到一個(gè)叫計(jì)算屬性的東西來解決:計(jì)算屬性就是在實(shí)例配置項(xiàng)中通過computed來為vm設(shè)置一個(gè)新的數(shù)據(jù),而這個(gè)新數(shù)據(jù)會(huì)擁有一個(gè)依賴(一條已經(jīng)存在的數(shù)據(jù)),當(dāng)依賴發(fā)送變化的時(shí)候,新數(shù)據(jù)也會(huì)發(fā)送變化與方法的方式相比,它性能更高,計(jì)算屬性是基于它們的依賴進(jìn)行緩存的。計(jì)算屬性只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值。相比之下,每當(dāng)觸發(fā)重新渲染時(shí),調(diào)用方法將總會(huì)再
次執(zhí)行函數(shù)。
與watch相比,寫起來簡單,邏輯性更清晰,watch一般多用于,根據(jù)數(shù)據(jù)的變化而執(zhí)行某些動(dòng)作,而至于這些動(dòng)作是在干什么其實(shí)無所謂,而計(jì)算屬性更有針對(duì)性,根據(jù)數(shù)據(jù)變化而更改
另一個(gè)數(shù)據(jù)
計(jì)算屬性也擁有g(shù)etter和setter,默認(rèn)寫的是getter,設(shè)置setter執(zhí)行可以當(dāng)此計(jì)算屬性數(shù)據(jù)更改的時(shí)候去做其他的一些事情,相當(dāng)于watch這個(gè)計(jì)算屬性
xm:{ get:function(){//getter 當(dāng)依賴改變后設(shè)置值的時(shí)候 return this.xing+'丶'+this.ming }, set:function(val){//setter 當(dāng)自身改變后執(zhí)行 this.xing = val.split('丶')[0] this.ming = val.split('丶')[1] } }
vue中可以設(shè)置filter(過濾器)來實(shí)現(xiàn)數(shù)據(jù)格式化,雙花括號(hào)插值和 v-bind 表達(dá)式中使用
vue1.0的有默認(rèn)的過濾器,但是在2.0的時(shí)候全部給去掉了
所以在vue中如果想要使用過濾器就需要自定義
自定義的方法有兩種:全局定義和局部定義,全局定義的過濾器在任意的實(shí)例、組件中都可以使用,局部定義就是在實(shí)例、組件中定義,只能在這個(gè)實(shí)例或組件中使用
全局定義
Vue.filter(name,handler)
name是過濾器的名字,handler是數(shù)據(jù)格式化處理函數(shù),接收的第一個(gè)參數(shù)就是要處理的數(shù)據(jù),返回什么數(shù)據(jù),格式化的結(jié)果就是什么
在模板中通過 | (管道符) 來使用,在過濾器名字后面加()來傳參,參數(shù)會(huì)在handler函數(shù)中第二個(gè)及后面的形參來接收
<p>{{msg | firstUpper(3,2)}}</p> Vue.filter('firstUpper',function (value,num=1,num2) { console.log(num2) return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase() })
局部定義
在實(shí)例、組件的配置項(xiàng)中設(shè)置 filters,鍵名為過濾器名,值為handler
filters:{ firstUpper:function (value,num=1,num2) { console.log(num2) return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase() } }
注意:
過濾器只能在mustache插值、v-bind里使用,其他的指令等地方都不能用
在Vue中可以使用v-if來控制模板里元素的顯示和隱藏,值為true就顯示,為false就隱藏
v-if控制的是是否渲染這個(gè)節(jié)點(diǎn)
當(dāng)我們需要控制一組元素顯示隱藏的時(shí)候,可以用template標(biāo)簽將其包裹,將指令設(shè)置在template上,等等vm渲染這一組元素的時(shí)候,不會(huì)渲染template
當(dāng)有else分支邏輯的時(shí)候,可以給該元素加上v-else指令來控制,v-else會(huì)根據(jù)上面的那個(gè)v-if來控制,效果與v-if相反,注意,一定要緊挨著
還有v-else-if指令可以實(shí)現(xiàn)多分支邏輯
<input type="text" v-model="mode"> <template v-if="mode=='A'"> <h1>1.title</h1> <p>我的第一個(gè)P標(biāo)簽</p> </template> <template v-else-if="mode=='B'"> <h1>2.title</h1> <p>我的第二個(gè)P標(biāo)簽</p> </template> <template v-else-if="mode=='C'"> <h1>3.title</h1> <p>我的第三個(gè)P標(biāo)簽</p> </template> <template v-else> <p>不好意思,輸入有誤</p> </template>
需要注意的另一個(gè)地方是:Vue 會(huì)盡可能高效地渲染元素,通常會(huì)復(fù)用已有元素而不是從頭開始渲染。這樣確實(shí)能使Vue變得更快,性能更高,但是有的時(shí)候我們需要讓實(shí)例去更新dom而不是
復(fù)用,就需要給dom加上不同的key屬性,因?yàn)関ue在判斷到底渲染什么的時(shí)候,包括哪些dom可以復(fù)用,都會(huì)參考key值,如果dom表現(xiàn)基本一致,符合復(fù)用的條件,但是key值不同,依然不會(huì)復(fù)
用
Vue還提供了v-show指令,用法和v-if基本一樣,控制的是元素的css中display屬性,從而控制元素的顯示和隱藏 , 不能和v-else配合使用,且不能使用在template標(biāo)簽上,因?yàn)閠emplate不
會(huì)渲染,再更改它的css屬性也不會(huì)渲染,不會(huì)生效
v-if 是“真正”的條件渲染,因?yàn)樗鼤?huì)確保在切換過程中條件塊內(nèi)的事件監(jiān)聽器和子組件適當(dāng)?shù)乇讳N毀和重建。
v-if 也是惰性的:如果在初始渲染時(shí)條件為假,則什么也不做——直到條件第一次變?yōu)檎鏁r(shí),才會(huì)開始渲染條件塊。
相比之下,v-show 就簡單得多——不管初始條件是什么,元素總是會(huì)被渲染,并且只是簡單地基于 CSS 進(jìn)行切換。
一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show 較好;如果在運(yùn)行時(shí)條件很少改變,則使用 v-if 較好。
在Vue中,我們可以通過定義多個(gè)mixin來實(shí)現(xiàn)代碼抽離復(fù)用,便于維護(hù),提升頁面的邏輯性
要注意的是:data屬性不要使用mixin,因?yàn)閺倪壿嬌蟻碚f,每一個(gè)實(shí)例、組件的數(shù)據(jù)都應(yīng)該是獨(dú)立的
一個(gè)mixin其實(shí)就是一個(gè)純粹的對(duì)象,上面掛載著抽離出來的配置,在某一個(gè)實(shí)例中,通過mixins選項(xiàng)(數(shù)組)導(dǎo)入后,此實(shí)例就擁有導(dǎo)入的mixin的配置
且導(dǎo)入的配置不會(huì)覆蓋原有的,而是合并到一起
頻繁且復(fù)雜的dom操作通常是前端性能瓶頸的產(chǎn)生點(diǎn),Vue提供了虛擬dom的解決辦法
虛擬的DOM的核心思想是:對(duì)復(fù)雜的文檔DOM結(jié)構(gòu),提供一種方便的工具,進(jìn)行最小化地DOM操作。這句話,也許過于抽象,卻基本概況了虛擬DOM的設(shè)計(jì)思想
(1) 提供一種方便的工具,使得開發(fā)效率得到保證
(2) 保證最小化的DOM操作,使得執(zhí)行效率得到保證
也就是說,虛擬dom的框架/工具都是這么做的:
這樣的話,就能大量減少真實(shí)dom的操作,提高性能
模塊化就是將系統(tǒng)功能分離成獨(dú)立的功能部分的方法,一般指的是單個(gè)的某一種東西,例如js、css
而組件化針對(duì)的是頁面中的整個(gè)完整的功能模塊劃分,組件是一個(gè)html、css、js、image等外鏈資源,這些部分組成的一個(gè)聚合體
優(yōu)點(diǎn):代碼復(fù)用,便于維護(hù)
劃分組件的原則:具有大量的布局結(jié)構(gòu)的,或者是獨(dú)立的邏輯的,都應(yīng)該分成組件
組件應(yīng)該擁有的特性:可組合,可重用,可測(cè)試,可維護(hù)
在vue中,我們通過Vue.extend來創(chuàng)建Vue的子類,這個(gè)東西其實(shí)就是組件
也就是說Vue實(shí)例和組件的實(shí)例有差別但是差別不帶,因?yàn)楫吘挂粋€(gè)是父類一個(gè)是子類
一般的應(yīng)用,會(huì)擁有一個(gè)根實(shí)例,在根實(shí)例里面都是一個(gè)一個(gè)的組件
因?yàn)榻M件是要嵌入到實(shí)例或者父組件里的,也就是說,組件可以互相嵌套,而且,所有的組件最外層必須有一個(gè)根實(shí)例,所以組件分為:全局組件和局部組件
全局組件在任意的實(shí)例、父級(jí)組件中都能使用,局部組件只能在創(chuàng)建自己的父級(jí)組件或者實(shí)例中使用
組件通過不同的注冊(cè)方法成為全局、局部組件
創(chuàng)建組件:
Vue.extend(options)
全局注冊(cè):
var App = Vue.extend({ template:"<h1>hello world</h1>" }) Vue.component('my-app',App)
組件通過template來確定自己的模板,template里的模板必須有根節(jié)點(diǎn),標(biāo)簽必須閉合
組件的屬性掛載通過:data方法來返回一個(gè)對(duì)象作為組件的屬性,這樣做的目的是為了每一個(gè)組件實(shí)例都擁有獨(dú)立的data屬性
因?yàn)関ue是mvvm的框架,所以當(dāng)數(shù)據(jù)變化的時(shí)候,視圖會(huì)立即更新,視圖層產(chǎn)生操作后會(huì)自動(dòng)通知vm來更改model,所以我們可以實(shí)現(xiàn)雙向數(shù)據(jù)綁定,而其中的原理就是實(shí)例會(huì)將設(shè)置的data逐
個(gè)遍歷利用Object.defineProperty給數(shù)據(jù)生成getter和setter,當(dāng)數(shù)據(jù)變化地方時(shí)候setter會(huì)監(jiān)聽到并且通知對(duì)應(yīng)的watcher工具進(jìn)行邏輯運(yùn)算會(huì)更新視圖
在vue中,我們可以先在vue實(shí)例中聲明數(shù)據(jù),然后通過{{}}等方式渲染在dom中
聯(lián)系客服