1.元件
- Vue有兩大核心内容
- 指令
- 元件
- 什麼是元件化【為什麼要用元件?】
- 為了避免多人開發造成的沖突
- 為了加快開發效率
- 為了便利更新和維護
- 元件化:就是使用具有獨立公共的一個整體(元件)來進行項目開發的趨勢(流行)
- 什麼是元件?
- 元件是一個html css js img 等的一個聚合體
- 在Vue中使用了一個叫做單檔案元件的技術來實作元件
- 它是一個 xxx.vue 檔案
- 這個檔案在浏覽器中不能運作,必須經過編譯(gulp webpack )才能運作
-
Vue裡面是如何實作元件的?
Vue.extend()
- 通過執行個體化Vue構造器函數得到一個Vue執行個體,這個執行個體我們稱之為‘根執行個體’,它是最大的父級
- 這個根執行個體是以标簽的形式存在的,那麼我們也稱之為‘根元件’
- 根執行個體也是一個元件,但是我們得到的隻是根元件
- Vue.extend() 它就是對Vue功能的擴充,這個擴充就是元件
- Vue是通過Vue.extend() 來實作【擴充】Vue的功能的,這個功能就是元件
- 思考:Vue.extend() 如何使用?
- 通過new Vue.extend() 發現和 new Vue 一樣 —排除
- 元件就是一個以标簽化呈現的東西,是以應該像标簽一樣使用
- 但是無論是 HTML3 還是 HTML5 肯定不會同意它随意使用标簽的
- Vue會将元件編譯成 HTML 結構
- Vue這個處理過程,我們就稱之為‘元件注冊’
- 總結:
- Vue是通過Vue.extend() 來實作元件的
- Vue的元件使用時需要注冊
- Vue中是如何使用元件的?
- 組建注冊
- 全局注冊
//Vue.component(元件的名稱,元件的配置) const Hello = Vue.extend({ template:'<div>Hello 元件</div>' }) Vue.component('Hello',Hello) //簡寫 Vue.componen('Hello',{ template:'<div>Hello 元件</div>' })
-
局部注冊
局部注冊使用 components 選項來完成
局部注冊隻在目前注冊的執行個體範圍内有效
new Vue({ el:'#app', components:{//局部注冊元件的選項 //元件的名稱:元件的選項 'Hello':{ template:'<div>Hello 這裡是局部注冊</div>' } } })
- 全局注冊
- 元件的命名:一定要避免和原生标簽沖突 ,如:Header header 就不可以
-
大駝峰 HeadTitle
使用
-
小寫+橫杠 head-title
使用
- 一個單詞 Hello
<hello></hello> //或者 <Hello></Hello>//推薦
-
- 元件的使用規則
- 元件在父子級是有直接關系的标簽中是不能直接解析的,會出問題
- 直接父子級關系的标簽
ul li ol li table tr td dl dd dt select option
-
如何解決這個問題
使用 is 屬性 來解決
<div id="app"> <table border="1"> <tr> <td>1</td> <td>1</td> <td>1</td> </tr> <tr is = "Hello"></tr> </table> </div>
Vue.component('Hello',{ template:` <tr> <td>2</td> <td>2</td> <td>2</td> </tr> ` }) new Vue({ el:"#app" })
- 動态元件
- 業務: 點選開關切換兩個元件
- template寫在執行個體範圍内,會被直接解析,并且将來不會在html結構中出現
- template模闆内直接子元素有且僅有一個
- Vue提供了一個 component 元件
- 通過keep-alive元件實作動态元件的緩存,加快元件的切換速度
<div id="app"> <button @click="typeChange"> 點選 </button> <keep-alive> <component :is="type"></component> </keep-alive> </div> <template id="hello-box"> <div> <h3> 手機号登入 </h3> <input type="text" placeholder="請輸入手機号"/> </div> </template>
new Vue({ el:'#app', data:{ type:'PhoneLogin' }, methods:{ typeChange(){ this.type=(this.type === 'PhoneLogin') && 'UserLogin' || 'PhoneLogin' } }, components:{ 'PhoneLogin':{ template:'#hello-box' }, 'UserLogin':{ template:'<div>使用者名和密碼登入</div>' } } })
- 組建注冊
2.元件通信
- 元件的嵌套
- 子元件以标簽的形式要在父元件的模闆中使用
- 元件中資料的定義
-
為什麼元件中的data選項是一個函數,而根執行個體中是對象【面試】
原因:
- 元件是一個獨立的整體,那麼資料也應該是一個獨立的
- 多人開發,資料如果不是獨立的,那麼資料就會沖突
- javascript最大的特點:函數式程式設計,而函數本身就有一個獨立作用域
-
為什麼元件中的data函數要有傳回值,并且傳回值是一個對象,不能是其他嗎?
原因:因為data選項要經過ES5 Object.defineProperty 屬性進行getter和setter設定
- 資料中資料的使用
- 組建的資料,适用範圍隻能在元件的模闆中
-
- 元件通信
- 父子元件通信
- 父元件中定義一個資料
- 在父元件的模闆中,用v-bind将父元件的資料綁定在子元件身上
<Son :aa="money"></Son> //aa屬性為自定義
- 在子元件的選項中,通過props選項來接收這個屬性
- 這個屬性可以在子元件的模闆中以全局變量的形式使
<div id="app"> <Father/> </div> <!-- father 元件 start--> <template id="father"> <div> <h3> 這裡是 父元件 </h3> <hr/> <Son :aa="money"></Son> </div> </template> <!-- father 元件 end--> <!-- son 元件 start--> <template id="son"> <div> <h4> 這裡是子元件 </h4> <p> 老爸每月給我 {{ aa }} 生活費 </p> </div> </template> <!-- son 元件 end-->
Vue.component('Father',{ template:'#father', data(){ return { money:3000 } } }); Vue.component('Son',{ template:'#son', props:['aa'] })
- Props選項
- props屬性驗證
- props可以是一個對象
- props中的 validator 函數
- props 第三方屬性驗證 :vue-validator-help
- props屬性驗證
- 子父元件通信
- 自定義事件
this.$emit
- 子父通信流程
//1.先在子元件中定義一個資料 Vue.component('Son',{ tempalte:'#son', data(){ return { money:1000 } } }); //2. 在父元件中也定義一個資料,這個資料用來接收子元件傳遞過來的資料 Vue.component('Father',{ template: '#father', data () { return { bank: 1000 } } }) //3.在父元件中定義一個事件處理程式,用于改變父元件定義的資料,這個事件處理程式是有參數的,這個參數就是子元件傳遞過來的資料 Vue.component('Father',{ template:'#father', data(){ return { bank:1000 } }, methods:{ bankAdd( val ){//val就是子元件給的資料 this.bank += val; } } }); //4.将這事件處理程式用過事件綁定的形式綁定在子元件 <Son @aa="bankapp></Son> //5.在子元件中定義一個事件處理程式,這事件處理程式中通過this.$emit觸發自電子定義事件,并傳遞以參數 Vue.component('Son',{ template:'#son', data(){ return { money:1000 } }, methods:{ give(){ this.$emit('aa',this,mone y) } } }) <tempolate id="son"> <div> <h4> 這裡是子元件 </h4> <button @click="give" ></botton> </div> </template>
- 自定義事件
- 非父子元件通信
- ref
- bus事件總線
- 多元件狀态共享
- Vuex
- 父子元件通信
3.擴充
- 2.5 slot slot-scope
- slot 具名插槽 (必須會)
- slot-scope(了解)
- 2.6 v-slot(必須會)
4.元件的生命周期【組建的鈎子有哪些?】
- 為什麼要使用生命周期?
- 我們想要使用元件,那麼就得在元件的特定階段完成特定的任務(特定時間點完成特定任務)
- 名詞–鈎子:機遇
- 特定時間點,觸發一個方法
-
組建的而生命周期分為三個階段: 初始化 、運作中 、銷毀
8個鈎子函數(熟練掌握)
- 生命周期鈎子不允許寫成箭頭函數,因為箭頭函數會改變this指向
- 初始化
- beforeCreat () {}
- 元件即将建立
- 任務: 初始化事件,并且為整個生命周期的開始做準備 【舉例:相親–父母給你做準備和謀劃】
- 意義:
- 資料未擷取,真實DOM未拿到
- 資料請求,資料修改
- created () {}
- 元件建立結束
- 任務:進行資料的注入和資料的反應【舉例:父母告訴你了讓你相親】
- 意義:
- 資料拿到了,真實DOM未拿到
- 資料請求,資料修改
- beforeMount () {}
- 元件即将挂載
- 任務:判斷元件是否有el/template選項,如果有那麼使用
将template模闆中的jsx轉換成VDOM對象模型,如果沒有,需要我們使用render函數
手動挂載 【舉例:男女雙方互加微信,聊天】$mount/outerHTML
- 意義:
- 更多的是内部完成任務,我們外部就不幹預了
- 資料請求,資料修改
- mounted () {}
- 元件挂在結束
- 任務: 将VDOM渲染為真實DOM,然後挂載到頁面中,這個時候我們在頁面中可以看到内容了 【舉例:網絡約見面】
- 意義:
- 操作真實DOM【可以進行第三方庫執行個體化】
- 資料請求,資料修改
- 總結 :
- 我們常将資料請求寫在created中,因為created鈎子是第一次獲得資料的地方
- mounted鈎子函數可以進行DOM操作【第三方庫執行個體化(靜态資料)】
- beforeCreat () {}
- 運作中
- beforUpdate 元件更新前
- 觸發條件:元件的資料發生改變
- 任務 :VDOM重新生成,然後通過diff算法和以前的VDOM對比,生成patch更新檔對象【内部進行】【舉例:見面的結果】
- updated 元件更新結束
- 觸發條件:元件的資料發生改變
- 任務:将patch更新檔對象進行渲染生成真實DOM 【舉例:證明第一次相親失敗,換了一人】
- 意義:
- 可以操作DOM【第三方庫的執行個體化(動态資料)】
- 總結:平時大家使用updated進行第三方庫執行個體化
- beforUpdate 元件更新前
- 銷毀
- 意義: 用來完成善後工作【計時器,第三方庫執行個體,window.onscroll】
- 元件的銷毀有兩種形式
-
内部銷毀【舉例: 你可以将這個資訊告訴父親 】
$destroy
- 元件會被銷毀掉,但是元件的DOM外殼還在
- 外部銷毀 【舉例:你父母得知相親的結果是由别人告知的】
- 通過開關銷毀【推薦】
-
- 元件的銷毀會觸發兩個鈎子函數【 沒啥差别, 任意選擇一個使用 】
- beforDestroy () {} 銷毀前
- destroyed () {} 銷毀結束
5.自定義過濾器
- 注意點:
- 是對已有資料進行格式化
- 過濾器也可以傳遞參數
- 過濾器要使用管道符才能起作用
- 管道符 --回調函數中的傳回值是什麼,格式化後的資料就是什麼
- 分類
- 全局過濾器
Vue.filter(過濾器名稱,回調函數)
- 局部過濾器
filters:{ //過濾器名稱:回調函數 'dateFilter':(val,type) =>{//val就是要過濾的資料 var date = new Date(val) return date.getFullYear()+type+(date.getMonth()+1)+type+date.getDate() } }
- 全局過濾器