Vue的生命周期
生命周期:Vue實例從開始創(chuàng)建、初始化數(shù)據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是Vue的生命周期,各個階段有相對應的事件鉤子。
beforeCreate(創(chuàng)建前),在數(shù)據觀測和初始化事件還未開始
created(創(chuàng)建后),完成數(shù)據觀測,屬性和方法的運算,初始化事件,$el屬性還沒有顯示出來
beforeMount(載入前),在掛載開始之前被調用,相關的render函數(shù)首次被調用。實例已完成以下的配置:編譯模板,把data里面的數(shù)據和模板生成html。注意此時還沒有掛載html到頁面上。
mounted(載入后),在el被新創(chuàng)建的vm.$el替換,并掛載到實例上去之后調用。實例已完成以下的配置:用上面編譯好的html內容替換el屬性指向的DOM對象。完成模板中的html渲染到html頁面中。此過程中進行ajax交互。
beforeUpdate(更新前),在數(shù)據更新之前調用,發(fā)生在虛擬DOM重新渲染和打補丁之前。可以在該鉤子中進一步地更改狀態(tài),不會觸發(fā)附加的重渲染過程。
updated(更新后),在由于數(shù)據更改導致的虛擬DOM重新渲染和打補丁之后調用。調用時,組件DOM已經更新,所以可以執(zhí)行依賴于DOM的操作。然而在大多數(shù)情況下,應該避免在此期間更改狀態(tài),因為這可能會導致更新無限循環(huán)。該鉤子在服務器端渲染期間不被調用。
beforeDestroy(銷毀前),在實例銷毀之前調用。實例仍然完全可用。
destroyed(銷毀后),在實例銷毀之后調用。調用后,所有的事件監(jiān)聽器會被移除,所有的子實例也會被銷毀。該鉤子在服務器端渲染期間不被調用。

注意:
created階段的ajax請求與mounted請求的區(qū)別:前者頁面視圖未出現(xiàn),如果請求信息過多,頁面會長時間處于白屏狀態(tài)。
mounted不會承諾所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染完畢,可以用 vm.$nextTick。
2. 單個組件的生命周期
初始化組件時,僅執(zhí)行了beforeCreate/Created/beforeMount/mounted四個鉤子函數(shù)
當改變data中定義的變量(響應式變量)時,會執(zhí)行beforeUpdate/updated鉤子函數(shù)
當切換組件(當前組件未緩存)時,會執(zhí)行beforeDestory/destroyed鉤子函數(shù)
初始化和銷毀時的生命鉤子函數(shù)均只會執(zhí)行一次,beforeUpdate/updated可多次執(zhí)行
3. 父子組件的生命周期
僅當子組件完成掛載后,父組件才會掛載
當子組件完成掛載后,父組件會主動執(zhí)行一次beforeUpdate/updated鉤子函數(shù)(僅首次)
父子組件在data變化中是分別監(jiān)控的,但是在更新props中的數(shù)據是關聯(lián)的
銷毀父組件時,先將子組件銷毀后才會銷毀父組件



4. 兄弟組件的生命周期
組件的初始化(mounted之前)分開進行,掛載是從上到下依次進行
當沒有數(shù)據關聯(lián)時,兄弟組件之間的更新和銷毀是互不關聯(lián)的


5. 宏mixin的生命周期
mixin中的生命周期與引入該組件的生命周期是僅僅關聯(lián)的,且mixin的生命周期優(yōu)先執(zhí)行


1、什么是vue生命周期?
答: Vue 實例從創(chuàng)建到銷毀的過程,就是生命周期。從開始創(chuàng)建、初始化數(shù)據、編譯模板、掛載Dom→渲染、更新→渲染、銷毀等一系列過程,稱之為 Vue 的生命周期。
2、vue生命周期的作用是什么?
答:它的生命周期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯。
3、vue生命周期總共有幾個階段?
答:它可以總共分為8個階段:創(chuàng)建前/后、載入前/后、更新前/后、銷毀前/銷毀后。
5、DOM 渲染在哪個周期中就已經完成?
答:DOM 渲染在 mounted 中就已經完成了。
Vue實現(xiàn)數(shù)據雙向綁定的原理:Object.defineProperty()
vue實現(xiàn)數(shù)據雙向綁定主要是:采用數(shù)據劫持結合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在數(shù)據變動時發(fā)布消息給訂閱者,觸發(fā)相應監(jiān)聽回調。當把一個普通 Javascript 對象傳給 Vue 實例來作為它的data選項時,Vue 將遍歷它的屬性,用 Object.defineProperty()將它們轉為getter/setter。用戶看不到 getter/setter,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。
vue的數(shù)據雙向綁定 將MVVM作為數(shù)據綁定的入口,整合Observer,Compile和Watcher三者,通過Observer來監(jiān)聽自己的model的數(shù)據變化,通過Compile來解析編譯模板指令(vue中是用來解析 {{}}),最終利用watcher搭起observer和Compile之間的通信橋梁,達到數(shù)據變化 —>視圖更新;視圖交互變化(input)—>數(shù)據model變更雙向綁定效果。
js實現(xiàn)簡單的雙向綁定:
<body>
<div id="app">
<input type="text" id="txt">
<p id="show"></p>
</div>
</body>
<script type="text/javascript">
var obj = {}
Object.defineProperty(obj, 'txt', {
get: function () {
return obj
},
set: function (newValue) {
document.getElementById('txt').value = newValue
document.getElementById('show').innerHTML = newValue
}
})
document.addEventListener('keyup', function (e) {
obj.txt = e.target.value
})
</script>
Vue組件間的參數(shù)傳遞
1、父組件與子組件傳值
父組件傳給子組件:子組件通過props方法接受數(shù)據;
子組件傳給父組件:$emit方法傳遞參數(shù)
2、非父子組件間的數(shù)據傳遞,兄弟組件傳值eventBus,就是創(chuàng)建一個事件中心,相當于中轉站,可以用它來傳遞事件和接收事件。項目比較小時,用這個比較合適。
Vue的路由實現(xiàn):hash模式 和 history模式
hash模式:在瀏覽器中符號“#”,#以及#后面的字符稱之為hash,用 window.location.hash 讀取。特點:hash雖然在URL中,但不被包括在HTTP請求中;用來指導瀏覽器動作,對服務端安全無用,hash不會重加載頁面。
history模式:history采用HTML5的新特性;且提供了兩個新方法: pushState(), replaceState()可以對瀏覽器歷史記錄棧進行修改,以及popState事件的監(jiān)聽到狀態(tài)變更。
Vue 實現(xiàn)前進刷新,后退不刷新的效果
需求一:
在一個列表頁中,第一次進入的時候,請求獲取數(shù)據。
點擊某個列表項,跳到詳情頁,再從詳情頁后退回到列表頁時,不刷新。
也就是說從其他頁面進到列表頁,需要刷新獲取數(shù)據,從詳情頁返回到列表頁時不要刷新。
解決方案
在 App.vue設置:
<keep-alive include="list">
<router-view/>
</keep-alive>
假設列表頁為list.vue,詳情頁為detail.vue,這兩個都是子組件。
我們在keep-alive添加列表頁的名字,緩存列表頁。
然后在列表頁的created函數(shù)里添加ajax請求,這樣只有第一次進入到列表頁的時候才會請求數(shù)據,當從列表頁跳到詳情頁,再從詳情頁回來的時候,列表頁就不會刷新。
這樣就可以解決問題了。
需求二:
在需求一的基礎上,再加一個要求:可以在詳情頁中刪除對應的列表項,這時返回到列表頁時需要刷新重新獲取數(shù)據。
我們可以在路由配置文件上對detail.vue增加一個meta屬性。
{
path: '/detail',
name: 'detail',
component: () => import('../view/detail.vue'),
meta: {isRefresh: true}
},
這個meta屬性,可以在詳情頁中通過this.$route.meta.isRefresh來讀取和設置。
設置完這個屬性,還要在App.vue文件里設置watch一下$route屬性。
watch: {
$route(to, from) {
const fname = from.name
const tname = to.name
if (from.meta.isRefresh || (fname != 'detail' && tname == 'list')) {
from.meta.isRefresh = false
// 在這里重新請求數(shù)據
}
}
},
這樣就不需要在列表頁的created函數(shù)里用 ajax 來請求數(shù)據了,統(tǒng)一放在App.vue里來處理。
觸發(fā)請求數(shù)據有兩個條件:
從其他頁面(除了詳情頁)進來列表時,需要請求數(shù)據。
從詳情頁返回到列表頁時,如果詳情頁 meta 屬性中的isRefresh為true,也需求重新請求數(shù)據。
當我們在詳情頁中刪除了對應的列表項時,就可以將詳情頁meta屬性中的isRefresh設為true。這時再返回到列表頁,頁面會重新刷新。
其它小知識點
1、css只在當前組件起作用
答:在style標簽中寫入scoped即可 例如: <style scoped></style>
2、v-if 和 v-show 區(qū)別
答:v-if按照條件是否渲染,v-show是display的block或none;
3、$route和$router的區(qū)別
答:$route是“路由信息對象”,包括path,params,hash,query,fullPath,matched,name等路由信息參數(shù)。而$router是“路由實例”對象包括了路由的跳轉方法,鉤子函數(shù)等。