面試官常問——vue篇

1.vue生命週期
2.vue 雙向綁定原理
3.vue router原理
4.vue router動態路由javascript

1.vue 生命週期鉤子

clipboard.png

注意:全部的生命週期鉤子自動綁定this上下文到實例中,所以你能夠訪問數據,對屬性和方法進行運算。這意味着你不能使用箭頭函數來定義一個生命週期方法(例如:created:() => this.fetchTodos() )。這是由於箭頭函數綁定了父級上下文,所以this與你期待的vue實例不一樣,this.fetchTodos的行爲未定義。html

beforeCreate
在實例初始化以後,數據觀測(data observer)和 event/watcher事件配置以前被調用。
created
在實例建立完成後被當即調用.在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的運算,watch/event 事件回調。然而,掛載階段還沒開始,$el屬性目前不可見。
beforeMount
在掛載開始以前被調用:相關的 render 函數首次被調用。該鉤子在服務器端渲染期間不被調用。該鉤子在服務器渲染期間不被調用。
mounted
el被新建立的 vm.$el 替換,病掛載到實例上去以後調用該鉤子。若是root實例掛載了一個文檔內元素,當 mounted
被調用時 vm.$el 也在文檔內。 注意: mounted 不會承諾全部子組件也都一塊兒被掛載。若是你但願等到整個視圖都渲染完畢,能夠用
vm.$nextTick 替換調 mounted:(該鉤子在服務器端渲染期間不被調用)
mounted:function() {
        this.$nextTick(function () {
        //code that will run only after the 
        //entire view has been rendered
   }) }
beforeUpdate
數據更新時調用,發生在虛擬 DOM 打補丁以前。這裏適合在更新以前訪問現有的DOM,好比
手動移除已經添加的事件監聽器。
該鉤子在服務器端渲染期間不被調用,由於只有初次渲染會在服務端進行。
updated
因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。

當這個鉤子被調用時,組件DOM已經更新,因此你如今能夠執行依賴於DOM的操做。然而在大多數狀況下,你應該避免在此期間更改狀態。若是要相應狀態改變,一般最好使用計算屬性或watcher取而代之。前端

注意 updated 不會承諾全部的子組件都一塊兒被重繪。若是你但願等到整個視圖都重繪完畢,能夠用vm.$nextTick 替換調
mounted:(該鉤子在服務器端渲染期間不被調用)vue

mounted:function() {
    this.$nextTick(function () {
    //code that will run only after the 
    //entire view has been rendered
}) }
activated
keep-alive 組件激活時調用。該鉤子在服務器端渲染期間不被調用。
構建組件 keep-alive
動態組件 keep-alive
deactivated
keep-alive組件停用時調用。 該鉤子在服務器端渲染期間不被調用
構建組件 keep-alive
動態組件 keep-alive
beforeDestory
實例銷燬以前調用。在這一步,實例仍然徹底可用。
該鉤子在服務器端渲染期間不被調用。
destoryed
vue實例銷燬後調用。調用後,vue實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
該鉤子在服務器端渲染期間不被調用。

2.vue 雙向綁定原理

Object.defineProperty是ES5新增的一個API,其做用是給對象的屬性增長更多的控制
Object.defineProperty(obj,prop,descriptor)
參數:java

obj: 須要定義屬性的對象(目標對象)
 prop:須要定義或修改的屬性名(對象上的屬性或方法)
 對於setter和getter,個人理解是它們是一對鉤子hook函數,當你對一個對象的某個屬性賦值時,則會自動調用相應的setter函數;
 而當獲取屬性時,則調用getter函數。這也是實現雙向數據綁定的關鍵。

clipboard.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue 雙向綁定</title>
</head>
<body>
    <div id="app">
        <input type="text" id="txt">
        <p id="show-txt"></p>
    </div>
</body>
<script type="text/javascript">
    var obj = {};
    Object.defineProperty(obj, 'txt', {
        get: function () {

        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show-txt').innerHTML = newValue
        }
    })

    document.addEventListener('keyup',function (e) {
        obj.txt = e.target.value
    })
</script>
</html>

3.vue router原理

路由這個概念最早是後端出現的。在之前用模板引擎開發頁面時,常常會看到這樣git

http://www.xxx.com/login

大體流程能夠當作這樣:github

1.瀏覽器發出請求
2.服務器監聽到80端口(或443)有請求過來,並解析url路徑
3.根據服務器路由配置,返回相應的信息(能夠是html字串,也能夠是json數據,圖片等)
4.瀏覽器根據數據包`Content-Type`來決定如何解析數據

簡單來講路由就是用來跟後端服務器進行交互的一種方式,經過不一樣的路徑,來請求不一樣的資源,請求不一樣的頁面是路由的其中一種功能。ajax

前端路由
1.hash模式
隨着ajax的流行,異步數據請求交互運行在不刷新瀏覽器的狀況下進行。而異步交互體驗的更高級版本就是SPA——單頁應用。單頁應用不只僅在頁面交互是無刷新的,連頁面跳轉都是無刷新的,爲了實現單頁應用,因此就有了前端路由。
相似於服務器路由,前端路由實現起來其實也很簡單,就是匹配不一樣的url路徑,進行解析,而後動態的渲染出區域html內容。可是這樣存在一個問題,就是URL每次變化的時候,都會形成頁面的刷新。那解決問題的思路即是在改變URL的狀況下,保證頁面的不刷新。在2014年以前,你們是經過hash來實現路由,URL hash 就是相似於:vue-router

http://www.xxx.com/login

這種#。後面hash值的變化,並不會致使瀏覽器向服務器發出請求,瀏覽器不發出請求,也就不會刷新頁面。另外每次hash值的變化,還會觸發
hashchange這個事件,經過這個事件咱們就能夠知道hash值發生了哪些變化。而後咱們即可以監聽hashchang來實現更新頁面部份內容的操做:json

function matchAndUpdate () {
    // todo 匹配 hash 作 DOM 更新
}
window.addEventListener('hashchange',matchAndUpdate)

2.history 模式
14年後,由於HTML5標準發佈。多了兩個API,pushStatereplaceState,經過這兩個API 能夠改變url地址且不會發送請求。同時還有 popState 事件。經過這些就能用另外一種方式來實現前端路由了,但原理都是跟 hash 實現相同的。用了 HTML5 的實現,單頁路由的 url 就不會多出一個#,變得更加美觀。但由於沒有 # 號,因此當用戶刷新頁面之類的操做時,瀏覽器仍是會給服務器發送請求。爲了不出現這種狀況,因此這個實現須要服務器的支持,須要把全部路由都重定向到根頁面。

function matchAndUpdate () {
    // todo 匹配 hash 作 DOM 更新
}
window.addEventListener('popstate',matchAndUpdate)

vue router實現
咱們在使用vue-router的時候,主要有如下幾步:

<div id="app">
    <!-- 路由匹配到的組件將渲染在這裏 -->
    <router-view></router-view>
</div>


// 1. 安裝 插件
Vue.use(VueRouter);

// 2. 建立router對象
const router = new VueRouter({
    routes // 路由列表 eg: [{ path: '/foo', component: Foo }]
});

// 3. 掛載router
const app = new Vue({
    router
}).$mount('#app');

vue-router 實現 -- install
理解Object.defineProperty的做用

相關文章
相關標籤/搜索