vue.js是什么
是一套構(gòu)建用戶界面的漸進(jìn)式框架
vue應(yīng)用組成
一個 Vue 應(yīng)用由一個通過new Vue創(chuàng)建的根 Vue 實例,以及可選的嵌套的、可復(fù)用的組件樹組成。
vue數(shù)據(jù)的響應(yīng)
當(dāng)一個 Vue 實例被創(chuàng)建時纸肉,它向 Vue 的響應(yīng)式系統(tǒng)中加入了其data對象中能找到的所有的屬性怎虫。當(dāng)這些屬性的值發(fā)生改變時,視圖將會產(chǎn)生“響應(yīng)”膳音,即匹配更新為新的值召衔。
實例生命周期
beforeCreat ?---->?創(chuàng)建vue實例前
created ---> ?創(chuàng)建vue實例完成后
beforeMount ?-----> ?DOM渲染前
mounted ?-----> ?DOM渲染后
beforeUpdate ?-----> ?數(shù)據(jù)更新前
updated ------> ?數(shù)據(jù)更新后
beforeDestroy -----> vue實例銷毀前
destroyed ?------> ? vue實例銷毀后
模板語法
vue模板為什么可以被瀏覽器解析?
Vue.js 使用了基于 HTML 的模板語法祭陷,允許開發(fā)者聲明式地將 DOM 綁定至底層 Vue 實例的數(shù)據(jù)苍凛。
底層是如何實現(xiàn)的?
Vue 將模板編譯成虛擬 DOM 渲染函數(shù)兵志。結(jié)合響應(yīng)系統(tǒng)醇蝴,在應(yīng)用狀態(tài)改變時,Vue 能夠智能地計算出重新渲染組件的最小代價并應(yīng)用到 DOM 操作上想罕。
計算屬性和觀察者
什么時候使用計算屬性悠栓?
1.對于需要任何復(fù)雜邏輯顯示的變量,就應(yīng)該使用計算屬性(computed);
2.當(dāng)有一些數(shù)據(jù)需要隨著其它數(shù)據(jù)變動而變動時惭适,使用計算屬性比watch監(jiān)聽更方便笙瑟;
計算屬性基本寫法
實例:
var vm =newVue({
?????el:'#example',
? ? ?data: {
? ? ?message:'Hello'
????},
????computed: {
????// 計算屬性的 getter
????reversedMessage:function(){
????// `this` 指向 vm 實例
????returnthis.message.split('').reverse().join('')
????}
????}
})
計算屬性與方法的區(qū)別
相同點:使用結(jié)果都是一樣的;
不同點:計算屬性只有在它的相關(guān)依賴發(fā)生改變時才會重新求值腥沽,否則會返回已緩存的值逮走;
? ? ? ? ? ? ? ?方法每當(dāng)觸發(fā)重新渲染時,調(diào)用方法將總會再次執(zhí)行函數(shù)今阳。
計算屬性的 setter
計算屬性默認(rèn)只有 getter 师溅,不過在需要時你也可以提供一個 setter;
注意:當(dāng)寫了setter后盾舌,運(yùn)行computed中的方法時墓臭,setter 會被調(diào)用;
偵聽器
當(dāng)需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時妖谴,使用watch是最合適的窿锉;
watch中可以處理一些異步的操作,計算屬性不可以膝舅;
Class 與 Style 綁定
*通過v-bind來綁定class和style嗡载;
class綁定的語法:
1.對象語法:v-bind:class="{ active: isActive, 'text-danger': hasError }"
2.數(shù)組語法:v-bind:class="[activeClass, errorClass]"
3.以上兩個語法都可以使用在組件中,動態(tài)綁定的class名不會覆蓋已存在的名;
style綁定的語法:
1.對象語法:v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"
2.數(shù)組語法:v-bind:style="[baseStyles, overridingStyles]"
style自動添加前綴
當(dāng)v-bind:style使用需要添加瀏覽器引擎前綴的 CSS 屬性時仍稀,如transform洼滚,Vue.js 會自動偵測并添加相應(yīng)的前綴。
多重值
2.3.0起技潘,新增了style可以寫多個值遥巴,如下:
:style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }
在渲染頁面時,只會顯示數(shù)組中享幽,瀏覽器支持的值铲掐,前兩種都不支持的情況下,會顯示flex值桩。
條件渲染
v-if摆霉、v-else、v-else-if(2.1.0新增)
基本使用方法如下:
<h1 v-if="ok">Yes</h1>
<h1 v-else-if="yesNo">noYes</h1>
<h1 v-else="no">No</h1>
以上案例只可以判斷有條件指令的元素身上奔坟;
條件渲染分組(template元素)
判斷多個元素需要使用<template>元素斯入,將需要判斷的元素包起來,方法如下:
<template v-if="ok">
<h1>h1</h1>
<p>p</p>
</template>
<template v-else="no">
<h2>h2</h2>
<span>span</span>
</template>
用管理可重用的元素key
案例說明:如果你允許用戶在不同的登錄方式之間切換蛀蜜;
不寫key屬性如下:
以上這樣的切換,input值中的值會相互影響增蹭;
通過key屬性處理上面問題:
給不同的key值滴某,就可以做到相互不影響,從而切換時,input中的值會單獨(dú)出來霎奢;
v-show條件渲染
v-show使用方法與v-if相同户誓;
v-show與v-if的區(qū)別:
1.v-show的元素始終會被渲染在DOM中,v-show幕侠,只是簡單的使用display屬性帝美,并且,v-show不支持v-else和<template>元素;?
2. v-if晤硕,只有在符合條件時悼潭,才會渲染元素,否則不渲染舞箍;
3.v-if舰褪,是“真正”的條件渲染,因為它會確保在切換過程中條件塊內(nèi)的事件監(jiān)聽器和子組件適當(dāng)?shù)乇讳N毀和重建疏橄。
如何選擇使用v-if和v-show
一般來說占拍,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷捎迫。因此晃酒,如果需要非常頻繁地切換,則使用 v-show 較好窄绒;如果在運(yùn)行時條件很少改變贝次,則使用 v-if 較好。
列表渲染
v-for語法:v-for="items in list" ?或者:v-for="items of list"
可以遍歷數(shù)組颗祝,也可以遍歷對象
對象遍歷:
v-for的第二個參數(shù):key ---- ?v-for="(value, key) in object"
key表示數(shù)據(jù)中的鍵名浊闪;
v-for中key參數(shù)說明?
盡量在v-for中加入key,除非遍歷輸出的 DOM 內(nèi)容非常簡單螺戳,或者是刻意依賴默認(rèn)行為以獲取性能上的提升搁宾。因為它是 Vue 識別節(jié)點的一個通用機(jī)制。
數(shù)組更新檢測
變異方法:會改變原有數(shù)組倔幼;如下:
push()盖腿、pop()、shift()损同、unshift()翩腐、splice()、sort()膏燃、reverse()
非變異方法:不會改變原有數(shù)組茂卦,會返回一個新數(shù)組;如下:
filter()组哩、concat()等龙、slice()
對象更改檢測注意事項
還是由于 JavaScript 的限制处渣,Vue 不能檢測對象屬性的添加或刪除:
可以使用:Vue.set(object, key, value) 方法來添加或刪除;也可以使用vue全局的Vue.$set
參數(shù)說明:
1.object:要修改的對象蛛砰;
2.key:要修改的key名罐栈;
3.value:要修改的value值;
說明:set方法不可以同時添加多個key泥畅,value荠诬;
同時添加多個key,value的方法,使用Object.assign()位仁;
//this.userProfile 是要添加的對象
this.userProfile =Object.assign({},this.userProfile, {
????????age:27,
????????favoriteColor:'Vue Green'
})
顯示過濾/排序結(jié)果
當(dāng)需要對數(shù)組進(jìn)行過濾或排序柑贞,但不需要改變原有數(shù)組,這時需要使用計算屬性(computed)障癌;
實例如下:
data: {
????numbers: [1,2,3,4,5]
},
computed: {
????evenNumbers:function(){
????????returnthis.numbers.filter(function(number){
????????????returnnumber %2===0
????????})
????}
}
說明:當(dāng)數(shù)組是嵌套在v-for中凌外,計算屬性就不適合了,需要使用method方法涛浙。
一段取值范圍的 v-for
v-for比v-if的優(yōu)先級高康辑,也就是,先循環(huán)后判斷轿亮。
如下(v-for與v-if是在同一個元素上):
如果需要先判斷后循環(huán),這種情況可以把判斷指令寫到循環(huán)指令外或者是template元素上我注;
組件中的v-for
*vue 2.2.0以上在組件中使用v-for必須要加key按咒;
案例:
<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"
></my-component>
for中的item,傳入組件中但骨,使用porps原因是為了for與組件之前的解藕励七,并能明確數(shù)據(jù)的來源,從而重復(fù)使用奔缠;
事件處理
監(jiān)聽事件
使用v-on指令監(jiān)聽事件
<div v-on:click="eventFn">點擊按鈕</div>
v-on冒號后面跟著的是事件掠抬,如click,mouseout等;
事件處理方法
事件的處理方法校哎,可以寫到methods中两波,將方法名寫入v-on="方法名",調(diào)用事件闷哆;
內(nèi)聯(lián)處理器中的方法
<div v-on:click="eventFn('vue')">點擊</div>
可以將事件寫在內(nèi)聯(lián)中進(jìn)行調(diào)用腰奋,并傳參;
當(dāng)遇到需要使用原生DOM事件抱怔,可以通過$event,傳入到事件中劣坊;
Vue.js 中提供的修飾符
事件修飾符
.stop:阻止單擊事件繼續(xù)傳播
.prevent:提交事件不再重載頁面
.capture:添加事件監(jiān)聽器時使用事件捕獲模式
.self:即事件不是從內(nèi)部元素觸發(fā)的
.once:點擊事件將只會觸發(fā)一次(2.1.4 新增)
按鍵修飾符
.enter、.tab屈留、.delete(捕獲“刪除”和“退格”鍵)局冰、.esc括儒、.space、.up锐想、.down、.left乍狐、.right
自動匹配按鍵修飾符
<input @keyup.page-down="onPageDown"/>
在上面的例子中赠摇,處理函數(shù)僅在$event.key === 'PageDown'時被調(diào)用。
系統(tǒng)修飾鍵
.ctrl浅蚪、.alt藕帜、.shift、.meta
以上按下相應(yīng)按鍵時才觸發(fā)鼠標(biāo)或鍵盤事件的監(jiān)聽器惜傲;
為什么在 HTML 中監(jiān)聽事件?
1.易讀洽故,一眼就可以看到對應(yīng)的方法;
2.與 DOM 完全解耦盗誊,更易于測試时甚;
3.當(dāng)一個 ViewModel 被銷毀時,所有的事件處理器都會自動被刪除哈踱;不需要自己刪除荒适;
表單輸入綁定
使用v-model指令綁定表單控件標(biāo)簽,可以實現(xiàn)監(jiān)聽效果开镣,輸入框的標(biāo)簽可以實現(xiàn)雙向數(shù)據(jù)綁定刀诬;
摘抄API
表單修飾符
.lazy:轉(zhuǎn)變input輸入框同步數(shù)據(jù)的事件;
<input v-model.lazy="msg" /> //這里表示邪财,添加了lazy陕壹,change事件中才會同步數(shù)據(jù);
.number:轉(zhuǎn)變input輸入框值的類型树埠,改變?yōu)閚umber類型(如果原值的轉(zhuǎn)換結(jié)果為 NaN 則返回原值)
.trim:去掉input值的首尾空格糠馆;
組件
什么是組件
組件是vue的功能之一,可以看成是自定義元素弥奸≌セ荩可以擴(kuò)展HTML元素,封裝可重用的代碼盛霎。組件也可以使用is赠橙,擴(kuò)展原生HTML元素;
注冊組件
1.全局注冊
使用Vue.component('組件標(biāo)簽名'愤炸,{組件的配置代碼})方法注冊期揪;
組件標(biāo)簽名,官網(wǎng)推薦使用烤串命名方法為最佳规个;
// 注冊
Vue.component('my-component', {
????????template:'<div>A custom component!</div>'
})
// 創(chuàng)建根實例
newVue({
????????el:'#example'
})
2.局部注冊
可以在vue實例下凤薛,components 中注冊組件姓建;
varChild = {
????????template:'<div>A custom component!</div>'
}
newVue({
????// ...將只在父組件模板中可用
????components: {
????????????// 將只在父組件模板中可用
????????????'my-component': Child
????????????}
})
DOM 模板解析注意事項
組件標(biāo)簽,會受到 HTML 本身的一些限制缤苫,因為 Vue 只有在瀏覽器解析速兔、規(guī)范化模板之后才能獲取其內(nèi)容;
例如:ul,select等活玲,這些內(nèi)部包含的元素有限制涣狗,組件標(biāo)簽會被視為無效;
解決方法
1.使用is來解決這個問題舒憾,如下:
<table>
? ? <tr is="my-component"></tr>
</table>
運(yùn)行后:
<table><my-component></my-component></table>
2.也可以使用字符串模版來處理镀钓,因為字符串模版沒有限制
<script type="text/x-template">
JavaScript 內(nèi)聯(lián)模板字符串
data 必須是函數(shù)
Vue.component('simple-counter', {
template:'<div></div>',
// 技術(shù)上 data 的確是一個函數(shù)了,因此 Vue 不會警告镀迂,
// 但是我們卻給每個組件實例返回了同一個對象的引用
????????data:function(){
????????????return ?{ ?//在data中的函數(shù)丁溅,必須返回return一個對象,這樣就就不會相互影響探遵。否則數(shù)據(jù)會同時影響到窟赏;
? ? ? ? ? ? ? ? list:[1,2,3]
????????????}
????????}
})
組件組合
組件的組合,批組件的嵌套配合使用别凤,常見父子組件之間的配合饰序,會遇到相互通信傳遞的問題;
父向子傳遞使用props规哪,向下傳遞求豫;
子向父傳遞使用自定義事件,向上傳遞诉稍;
props
使用props傳遞數(shù)據(jù)
props是專門綁定組件中自定義屬性的蝠嘉,也可以通過props傳遞數(shù)據(jù);
聲明方法
Vue.component('child', {
????????// 聲明 props
????????props: ['message']
})
<child message="data"></child>
camelCase(駝峰命名) vs. kebab-case(俗稱烤串命名)
在props中杯巨,命名要使用camelCase命名蚤告,在html中就可以使用kebab-case命名;
動態(tài)prop
prop的值可以是動態(tài)的數(shù)據(jù)服爷,這時就可以使用v-bind來動態(tài)綁定數(shù)據(jù);?
如下:
Vue.component('child', {
????// 聲明 props
????props: ['message']
})
<child :message="data"></child>
prop可以傳遞一個對象杜恰;
如下:
todo: {
????text:'Learn Vue',
????isComplete:false
}
<todo-item v-bind="todo"></todo-item>
**prop聲明的屬性不可以直接輸入字面量的值,
如:<child message="1"></child>
這里的1是字符串1仍源,不是一個數(shù)值心褐,如果需要是一個數(shù)值,則要通過v-bind動態(tài)綁定笼踩,這樣才是javascript的表達(dá)式逗爹;
單向數(shù)據(jù)流
prop是單向綁定的,父組件通過prop向子組件傳值后嚎于,子組件是不可以直接修改父傳過來的值掘而;這是為了防止子組件隨意修改父的數(shù)據(jù)挟冠,導(dǎo)致數(shù)據(jù)不準(zhǔn)確;
實際運(yùn)用中袍睡,會遇到子組件需要修改父組件的數(shù)據(jù)知染,解決辦法如下:
***如果 prop 是一個對象或數(shù)組,在子組件內(nèi)部改變它會影響父組件的狀態(tài)斑胜。
Prop 驗證
例:props:{
? ? ? ?自定義屬性名:{
????????????type:Number,//設(shè)置類型? ---->>type:[String,Number]//類型也可以是多種
????????????default:10,//設(shè)置默認(rèn)值[可填]
????????????required:true,//設(shè)置是否必填[可填]
????????}
}
自定義驗證:
????props:{
????????test(自定義屬性名):{
????????????validator:function(value){
????????????????retrun value>10;
????????????????//value,是test綁定對應(yīng)的數(shù)據(jù)的值持舆;
????????????????//return 驗證規(guī)則,直接寫retrun true驗證直接通過伪窖;如果寫規(guī)則邏輯就按邏輯走;
????????????}
????????}
}
非 prop 特性
指可以直接傳入組件居兆,而不需要定義相應(yīng)的 prop覆山。
如需要有個數(shù)據(jù)直接傳入組件,比如使用某個插件的某個屬性泥栖,可以直接可以直接將這個屬性寫入到組件元素上簇宽,賦值為'true'
替換/合并現(xiàn)有的特性
合并:遇到class、style時吧享,會合并值魏割,不會替換;
替換:遇到只能有一個值的數(shù)據(jù)钢颂,會被替換钞它;
自定義事件
當(dāng)子組件向父組件傳遞數(shù)據(jù),就可以通過自定義事件來傳殊鞭;
使用綁定自定義事件v-on
事件接口:
使用 $on(eventName) 監(jiān)聽事件
使用 $emit(eventName) 觸發(fā)事件
父組件用$on監(jiān)聽自定義事件遭垛,$emit觸發(fā)父組件所關(guān)心的自定義事件。
子組件向父組件傳遞方法步驟:
1>創(chuàng)建一個變量val在父組件中操灿,用于接收子組件的值锯仪;val='';
2>將val綁定到父組件要顯示的input中
<input :value="val"/>
3>子組件的自定義標(biāo)簽中,添加自定義事件趾盐;
<list-cus @receive='selectValue'></ist-cus>
4>子組件中的元素(li)加點擊事件庶喜,并通過vue自帶監(jiān)聽事件,監(jiān)聽并回調(diào)要傳的值救鲤;
methods:{
????????changeValue(item){
????????????????this.$emit('receive',item);
????????}
}
5>在父組件中的methods事件中寫selectValue方法久窟,方法中會傳入value的值
methods:{
????????selectValue(value){
????????????????this.val=value;
????????//將最終得到的選項值賦給val顯示到頁面中
????????}
}
備注:$emit(str1,[str2])
str1:自定義事件名
str2:要傳入的參數(shù),可以是多個
觸發(fā)當(dāng)前實例上的事件蜒简,附加參數(shù)都會傳給監(jiān)聽器回調(diào)瘸羡;
這里的監(jiān)聽器可以理解為,子組件標(biāo)簽身上的自定義事件搓茬;
給組件綁定原生事件
使用v-on事件名 .native犹赖,這樣綁定的就是原生事件了队他;
<my-component v-on:click.native="doTheThing"></my-component>
.sync 修飾符
這個修飾符在2.3.0時,重新被啟用峻村;
當(dāng)一個子組件改變了一個帶?.sync?的 prop 的值時麸折,這個變化也會同步到父組件中所綁定的值。這就是.sync的作用粘昨;
使用自定義事件的表單輸入組件
**自定義事件可以用來創(chuàng)建自定義的表單輸入組件垢啼,使用v-model來進(jìn)行數(shù)據(jù)雙向綁定**
vue雙向數(shù)據(jù)綁定的實現(xiàn)原理
vue數(shù)據(jù)雙向綁定是通過數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式來實現(xiàn)的,vue數(shù)據(jù)劫持是通過Object.defineProperty()來實現(xiàn)的张肾;
Object.defineProperty()是什么:可以控制一個對象屬性的一些特有操作芭析,比如讀寫權(quán)、是否可以枚舉吞瞪;
其中使用get和set兩個方法馁启,用來控制視圖-->數(shù)據(jù),數(shù)據(jù)<--視圖之間的修改更新芍秆,實現(xiàn)雙向數(shù)據(jù)綁定惯疙;
get是在讀取屬性值(數(shù)據(jù))時,觸發(fā)的函數(shù)妖啥;set是在設(shè)置屬性值(數(shù)據(jù))時霉颠,觸發(fā)的函數(shù);
雙向數(shù)據(jù)綁定實現(xiàn)思路
實現(xiàn)mvvm主要包含兩個方面荆虱,數(shù)據(jù)變化更新視圖蒿偎,視圖變化更新數(shù)據(jù);
視圖變化更新數(shù)據(jù):可以通過監(jiān)聽事件怀读;
數(shù)據(jù)變化更新視圖:這個可以通過Object.defineProperty()對屬性設(shè)置一個set函數(shù)酥郭,當(dāng)數(shù)據(jù)改變了就會來觸發(fā)這個函數(shù)