【前端知識體系-JS相關】深刻理解MVVM和VUE

1. v-bind和v-model的區別?

  1. v-bind用來綁定數據和屬性以及表達式,縮寫爲':'
  2. v-model使用在表單中,實現雙向數據綁定的,在表單元素外使用不起做用

2. Vue 中三要素的是什麼?

2.1 響應式

// 如何讓實現響應式的呢?
    let obj = {};
    let name = 'zhangsan';
    Object.defineProperties(obj, name, {get : function() {
      console.log('name' , name)
    }, set : function() {
        console.log('name' , name)
    }})
    
    
    // 1. 關鍵是理解Object.defineProperty
    // 2. 將data的屬性代理到vm上面的
    let mv = {};
        let data = {
            price: 100,
            name: 'zhangsan'
        };
        for (let key in data) {
            (function (key) {
                Object.defineProperty(mv, key, {
                    get: function () {
                        console.log('get val');
                        return data[key];
                    },
                    set: function (val) {
                        console.log('set val');
                        data[key] = val;
                    }
                })
            })(key);
        }

2.2 Vue中如何解析模板?

2.2.1 模板是什麼?

<div id="app">
        <div>
            <input v-model="title">
            <button v-on:click="add">submit</button>
        </div>
        <ul>
            <li v-for="item in list">{{item}}</li>
        </ul>
    </div>
// 1(*****). 模板實際上就是一個字符串………………(vue中的模板的本質)
 // 2. 模板有邏輯,如v-if, v-for
 // 3. 與html格式很像,可是有很大的區別
 // 4. 最終仍是要轉換爲html來顯示
 // 5(*****). 模板最終必須轉換成JS代碼,由於:
 //   (1)有邏輯(v-if v-for):必須用JS才能實現(圖靈完備)
 //    (2) 轉換成HTML來渲染頁面,必須用JS才能實現
 //    (3) 所以,模板最終要轉換成爲一個JS函數(render函數)

2.3 render函數?

2.3.1 with的用法
var obj = {
    name: 'zhangsan',
    age: 20,
    getAddress(){
        alert('shanghai');
    }
}

// 不使用with
function fn() {
  alert(obj.name);
  alert(obj.age);
  obj.getAddress();
}

// 使用with(代碼不易維護!!!)
function fn1() {
  with(obj){
      alert(name);
      alert(age);
      getAddress();
  }
}

fn();
fn1();
2.3.2 render函數的實現機制?
<div id='app'>
    <p>{{price}}</p>
</div>

// 使用with限制這個做用域裏面的this
with(this) {
    return _c(                          // this._c
        'div',
        {
            attrs: {"id" : "app"}       // id=app
        },
        [
            _c('p', [_v(_s(price))])    // this._c('p', [_v(_s(price))])
        ]
    )
}


// 實現一個本身的render函數
var vm = new Vue({
        el: '#app',
        data: {
            price: 100
        }
    });

    function render() {
        with (vm) {
            return _c(
                'div',
                {
                    attrs: {'id': 'app'}
                },
                [
                    _c('p', [_v(_s(price))])
                ]
            );
        }
    }

    function render() {
        return vm._c(
            'div',
            {
                attrs: {'id': 'app'}
            },
            [
                // vm._v 轉換爲一個文本節點
                // vm._s 轉換爲一個字符串
                // vm._c 轉換爲一個DOM節點
                vm._c('p', [vm._v(vm._s(price))])
            ]

        );
    }

2.3.3 render函數與vdom?

<div id="app">
        <div>
            <input type="text" v-model="title">
            <button @click="add">submit</button>
        </div>
        <div>
            <ul>
                <li v-for="item in list">{{item}}</li>
            </ul>
        </div>
    </div>
with (this) {
    // this 就是vm
    return _c(
        'div',
        {attrs: {"id": "app"}},
        [
            _c('div',
                [
                    _c('input', {
                        directives: [{
                            name: "model",
                            rawName: "v-model",
                            value: (title),
                            expression: "title"
                        }],
                        attrs: {"type": "text"},
                        domProps: {"value": (title)},
                        on: {
                            "input": function ($event) {
                                if ($event.target.composing) return;
                                title = $event.target.value
                            }
                        }
                    }),
                    _v(" "),
                    _c('button',
                        {
                            on: {
                                "click": add
                            }
                        },
                        [_v("submit")]
                    )
                ]
            ),
            _v(" "),
            _c('div',
                [
                    _c(
                        'ul',
                        // 這裏返回的是一個數組(li標籤組成的數組)
                        _l((list), function (item) {
                            return _c('li', [_v(_s(item))])
                        }), 0
                    )
                ]
            )
        ]
    )
}

// view --->  data ---> 使用input的事件綁定 ---> 更新頁面數據到data
// data --->  view ---> defineProperty --->  同步數據到頁面

2.3.4 vm._c是什麼,render函數返回了什麼?

  1. vdom: 使用js模擬DOm結構
  2. snabbdom: h函數和patch函數
    Vue中的v_c:就是至關於snabbdom函數的h函數
    patch函數:
vm._update(vnode) {
        const prevNode = vm._vnode;
        vm._vnode = vnode;
        if (!prevNode) {
            // 首次渲染的時候
            vm.$el = vm.__patch__(vm.$el, vnode);
        }
        else{
            vm.$el = vm.__patch__(prevNode, vnode);
        }
    }
    
    // 開始更新vue組件(修改data的屬性的時候,Object.defineProperty)
    function updateComponent() {
      vm._update(vm._render());
    }

******(問題總結)html

    1. vue模板:字符串,有邏輯,嵌入JS變量……
    1. 模板必須轉換爲JS代碼(有邏輯的,渲染html,js變量)
    1. render函數是什麼樣子的
    1. render函數的執行結果是返回的vnode
    1. updateComponent

3. Vue的整個實現流程源碼解讀???(總結點)

3.1 解析模板成render函數

<template></template> --->>> render 函數

[!NOTE]vue

  • with函數的使用
  • 模板中的全部信息都被render函數包含
  • 模板中用到的data中的屬性,都變成了JS變量
  • 模板中的v-model v-for v-on都變成了JS邏輯
  • render函數返回vnode

3.2 響應式開始監聽數據

  • Object.defineProperty
  • 將data的屬性代理到vm上
with(vm) {
        
    }

3.3 首次渲染,顯示頁面,且綁定依賴

[!NOTE]node

  • 初次渲染,執行updateComponent, 執行vm._render()
  • 執行render函數,會訪問到vm.list和vm.title屬性
  • 會被響應式的get方法監聽到(Object.defineProperty)
Object.defineProperty(mv, key, {
        get: function() {
          return data[key];
        }
    })
  • 執行updateComponent, 會執行vdom的patch方法
  • patch將vnode渲染成DOM,初次渲染完成

3.4 爲什麼要監聽get, 直接監聽set不行嗎?

[!NOTE]react

  • data中有不少屬性,有些會被用到,有些可能不被用到
  • 被用到的會走到get, 不被用到的不會走到get
  • 未走到get中的屬性,set的時候咱們也無需關心
  • 避免沒必要要的重複渲染(關鍵點)
vm._update(vnode) {
        const prevNode = vm._vnode;
        vm._vnode = vnode;
        if (!prevNode) {
            // 首次渲染的時候
            vm.$el = vm.__patch__(vm.$el, vnode);
        }
        else{
            vm.$el = vm.__patch__(prevNode, vnode);
        }
    }
    
    // 開始更新vue組件(修改data的屬性的時候,Object.defineProperty)
    function updateComponent() {
      vm._update(vm._render());
    }

3.5 data屬性變化,觸發rerender函數

Object.defineProperty(mv, key, {
        set: function(newVal) {
          data[key] = newVal;
          // 開始執行
          updateComponnet()
        }
    })

[!NOTE]jquery

  • 修改屬性,被響應式的set監聽到
  • set中執行updateComponnet
  • updateComponent從新執行vm._render()
  • 生成的vnode和preVnode, 經過patch進行對比
  • 渲染到html中去

4. 說一下從使用jQuery和使用框架的區別?

  1. 數據和視圖的分離(代碼解耦)---開房封閉原則
  2. 數據驅動視圖,只關係數據變化,DOM操做被封裝

5. 說一下對MVVM的理解?

  1. MVC
  2. MVVM
  3. 關於ViewModel

6. Vue中如何實現響應式的呢?

  1. 響應式
  2. 模板引擎
  3. 渲染(首次渲染,後面的渲染)
  • Object.defineProperty
  • data的屬性代理到vm上面(with)

7. Vue中是如何解析模板的呢?

  1. 模板的本質就是字符串(有邏輯)
  2. 模板必需要轉換爲JS代碼
  3. render函數的實現(返回的是一個vnode)
  4. updateComponnet(patch函數)

8. 說一下Vue的總體實現流程?

  1. 解析模板成爲render函數
  2. 響應式開始監聽數據
  3. 首次渲染,顯示頁面,且綁定依賴
  4. data屬性數據發生變化,從新觸發惹人的人、函數

9. vue的數據劫持以及操做數組的坑?

  1. 給data添加新屬性的時候vm.$set(vm.info,'newKey','newValue')webpack

  2. data上面屬性值是數組的時候,須要用數組的方法操做數組,而不能經過index或者length屬性去操做數組,由於監聽不到屬性操做的動做。ios

10. 談一下對mvvm和mvc的理解?

  1. mvc實際上是model view Model傳統全部邏輯在controller,難以維護。用戶輸入 => 控制器 => 數據改變,若是數據變了須要獲取dom,操做屬性,再渲染到視圖上。
  2. mvvm實際上是model view viewModel數據變化驅動視圖。數據變了,不須要你獲取dom,而後改變dom的內容。這邊數據變了,vm負責監聽,視圖那邊自動發生變化。最明顯的是不須要document.querySelector之類的了。

11. vm的實質?

[!NOTE]
上面說了vm負責讓數據變了,視圖能自動發生變化。這麼神奇魔術背後的原理是Object.defineProperty。其實就是屬性的讀取和設置操做都進行了監聽,當有這樣的操做的時候,進行某種動做。來一個demo玩下。web

// 對obj上面的屬性進行讀取和設置監聽
    let obj = {
        name:'huahua',
        age:18
    }
    function observer(obj){
        if(typeof obj === 'object'){
            for (const key in obj) {
                defineReactive(obj,key,obj[key])
            }
        }
    }
    // get的return的值纔是最終你讀取到的值。因此設的值是爲讀取準備的。
    // set傳的參數是設置的值,注意這裏不要有obj.name = newVal 這樣又觸發set監聽,會死循環的。
    function defineReactive(obj,key,value){
        Object.defineProperty(obj,key,{
            get:function(){
                console.log('你在讀取')
                // happy的話這邊能夠value++,這樣你發現讀取的值始終比設置的大一個,由於return就是讀取到的值
                return value
            },
            set:function(newVal){
                console.log('數據更新了')
                value = newVal
            }

        })
    }
    observer(obj)
    obj.age = 2
    console.log(obj.age)

12. defineReactive的實現(響應式手寫實現)?

[!NOTE]
在瀏覽器執行的時候,控制檯隨手也能夠obj.name="hua1"相似的操做,發現都監聽到了。可是若是更深一步,obj.name={firstname:'hua',lastname:'piaoliang'};obj.name.lastname='o'就不能監聽到屬性修改了。由於並無將新的賦值對象監聽其屬性。因此函數須要改進。面試

須要在defineReactive的第一行加上observer(value)。設置值的時候若是是對象的話,也須要將這個對象數據劫持。同理,set那邊也須要加這行。ajax

12.1 基礎實現

function defineReactive(obj,key,value){
       // 注意這裏!!!!!!!
        observer(value)
        Object.defineProperty(obj,key,{
            get:function(){
                return value
            },
            set:function(newVal){
                // 注意這裏!!!!!!!
                observer(newVal)
                console.log('數據更新了')
                value = newVal
            }

        })
    }

12.2 數組方法的劫持

若是obj.name=[1,2,3];obj.name.push(4)發現又沒有通知了,這是由於Object.defineProperty不支持監聽數組變化。因此須要重寫數組上面的方法。

// 把數組上大部分方法重寫了,這裏不一一列舉。可是若是你 [1,2].length--,這是捕捉不到的
        let arr = ['push','slice','split']
        arr.forEach(method=>{
            let oldPush = Array.property[method]
            Array.property[method] = function(value){
                console.log('數據更新')
                oldPush.call(this, value)
            }
        })

12.3 vue 的雙向綁定的原理是什麼(常考)

vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,經過 Object.defineProperty()來劫持各個屬性的 setter,getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。

  1. 第一步:須要 observe 的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter 和 getter 這樣的話,給這個對象的某個值賦值,就會觸發 setter,那麼就能監聽到了數據變化

  2. 第二步:compile 解析模板指令,將模板中的變量替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,更新視圖

  3. 第三步:Watcher 訂閱者是 Observer 和 Compile 之間通訊的橋樑,主要作的事情是:
    • 在自身實例化時往屬性訂閱器(dep)裏面添加本身
    • 自身必須有一個 update()方法
    • 待屬性變更 dep.notice()通知時,能調用自身的 update() 方法,並觸發 Compile 中綁定的回調,則功成身退。
  4. 第四步:MVVM 做爲數據綁定的入口,整合 Observer、Compile 和 Watcher 三者,經過 Observer 來監聽本身的 model 數據變化,經過 Compile 來解析編譯模板指令,最終利用 Watcher 搭起 Observer 和 Compile 之間的通訊橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據 model 變動的雙向綁定效果。

13. Vue如何監聽數組數據變化?

13.1 vm.\(set方法 由於是一開始就數據劫持了。因此後來若是新綁定屬性,是沒有數據劫持的。若是須要調用 vm.\)set(vm.info,'newKey','newValue'),vm是vue的實例。

13.2 使用數組的方法

當屬性值是數組,數組變化的時候,跟蹤不到變化。由於數組雖然是對象,可是Object.defineProperty不支持數組,因此vue改寫了數組的全部方法,當調用數組方法的時候,就調動變更事件。可是不能經過屬性或者索引控制數組,好比length,index。

[!NOTE]
總結:data上,綁定全部屬性避免後期加新屬性。若是是數組,只能經過數組方法修改數組。以下例子,控制檯vm.arr--發現視圖並不會變化,vm.arr.push(4)就能變化

<div id="app">{{msg}}{{arr}}</div>
        <script src="node_modules/vue/dist/vue.js"></script>
        <script>
        let vm = new Vue({
            el:'#app',
            // template加上以後會替換掉#app這個標籤
            // template:'<h1>en</h1>',
            data:{msg:'msg',arr:[1,2,3]}
        })
        vm.msg = 'msg'
        </script>

14. vue 的優勢和缺點是什麼?

14.1 優勢

  1. 低耦合。視圖(View)能夠獨立於 Model 變化和修改,一個 ViewModel 能夠綁定到不一樣的"View"上,當 View 變化的時候 Model 能夠不變,當 Model 變化的時候 View 也能夠不變。
  2. 可重用性。你能夠把一些視圖邏輯放在一個 ViewModel 裏面,讓不少 view 重用這段視圖邏輯。
  3. 獨立開發。開發人員能夠專一於業務邏輯和數據的開發(ViewModel),設計人員能夠專一於頁面設計,使用 Expression Blend 能夠很容易設計界面並生成 xml 代碼。
  4. 可測試。界面素來是比較難於測試的,而如今測試能夠針對 ViewModel 來寫。

14.2 缺點(面試常考)

  1. 網站SEO問題
  2. 瀏覽器兼容性問題
  3. 海量數據節點的渲染問題

15. 請詳細說下你對 vue 生命週期的理解?

總共分爲 8 個階段建立前/後,載入前/後,更新前/後,銷燬前/後。

  1. 建立前/後: 在 beforeCreate 階段,vue 實例的掛載元素 el 尚未, created階段。
  2. 載入前/後:在 beforeMount 階段,vue 實例的$el 和 data 都初始化了,但仍是掛載以前爲虛擬的 dom 節點,data.message 還未替換。在 mounted 階段,vue 實例掛載完成,data.message 成功渲染。
  3. 更新前/後:當 data 變化時,會觸發beforeUpdateupdated方法。
  4. 銷燬前/後:在執行 destroy 方法後,對 data 的改變不會再觸發周期函數,說明此時 vue 實例已經解除了事件監聽以及和 dom 的綁定,可是 dom 結構依然存在

16. Vue組件之間的傳值?

16.1. 父組件與子組件傳值

//父組件經過標籤上面定義傳值
<template>
    <Main :obj="data"></Main>
</template>
<script>
    //引入子組件
    import Main form "./main"

    exprot default{
        name:"parent",
        data(){
            return {
                data:"我要向子組件傳遞數據"
            }
        },
        //初始化組件
        components:{
            Main
        }
    }
</script>


//子組件經過props方法接受數據
<template>
    <div>{{data}}</div>
</template>
<script>
    exprot default{
        name:"son",
        //接受父組件傳值
        props:["data"]
    }
</script>

16.2 子組件向父組件傳遞數據

//子組件經過$emit方法傳遞參數
<template>
   <div v-on:click="events"></div>
</template>
<script>
    //引入子組件
    import Main form "./main"

    exprot default{
        methods:{
            events:function(){

            }
        }
    }
</script>


//

<template>
    <div>{{data}}</div>
</template>
<script>
    exprot default{
        name:"son",
        //接受父組件傳值
        props:["data"]
    }
</script>

17. Vue路由相關問題

17.1 active-class 是哪一個組件的屬性?

vue-router 模塊的 router-link 組件。

17.2 嵌套路由怎麼定義?

在實際項目中咱們會碰到多層嵌套的組件組合而成,可是咱們如何實現嵌套路由呢?所以咱們須要在 VueRouter 的參數中使用 children 配置,這樣就能夠很好的實現路由嵌套。
index.html,只有一個路由出口

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

main.js,路由的重定向,就會在頁面一加載的時候,就會將 home 組件顯示出來,由於重定向指向了 home 組件,redirect 的指向與 path 的必須一致。children 裏面是子路由,固然子路由裏面還能夠繼續嵌套子路由。

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

//引入兩個組件

import home from "./home.vue"
import game from "./game.vue"
//定義路由
const routes = [
    { path: "/", redirect: "/home" },//重定向,指向了home組件
    {
        path: "/home", component: home,
        children: [
            { path: "/home/game", component: game }
        ]
    }
]
//建立路由實例
const router = new VueRouter({routes})

new Vue({
    el: '#app',
    data: {
    },
    methods: {
    },
    router
})

home.vue,點擊顯示就會將子路由顯示在出來,子路由的出口必須在父路由裏面,不然子路由沒法顯示。

17.3 路由之間跳轉?

  • 聲明式(標籤跳轉) <router-link :to="index">
  • 編程式( js 跳轉) router.push('index')

17.4 懶加載(按需加載路由)(常考)

webpack 中提供了 require.ensure()來實現按需加載。之前引入路由是經過 import 這樣的方式引入,改成 const 定義的方式進行引入。

17.4.1 不進行頁面按需加載引入方式

import  home   from '../../common/home.vue'

17.4.2 進行頁面按需加載的引入方式

const  home = r => require.ensure( [], () => r (require('../../common/home.vue')))

17.5 vue-router 有哪幾種導航鉤子?

  1. 全局導航鉤子
  • router.beforeEach(to, from, next),
  • router.beforeResolve(to, from, next),
  • router.afterEach(to, from ,next)
  1. 組件內鉤子
  • beforeRouteEnter,
  • beforeRouteUpdate,
  • beforeRouteLeave
  1. 單獨路由獨享組件
  • beforeEnter

18. Vux相關問題

18.1 vuex 是什麼?怎麼使用?哪一種功能場景使用它?

vue 框架中狀態管理。在 main.js 引入 store,注入。新建了一個目錄 store,….. export 。場景有:單頁應用中,組件之間的狀態。音樂播放、登陸狀態、加入購物車

// 新建 store.js
import vue from 'vue'
import vuex form 'vuex'
vue.use(vuex)
export default new vuex.store({
    //...code
})

//main.js
import store from './store'
...

18.2 vuex 有哪幾種屬性?

有 5 種,分別是 state、getter、mutation、action、module

18.3 vuex 的 store 特性是什麼

  • vuex 就是一個倉庫,倉庫裏放了不少對象。其中 state 就是數據源存放地,對應於通常 vue 對象裏面的 data
  • state 裏面存放的數據是響應式的,vue 組件從 store 讀取數據,如果 store 中的數據發生改變,依賴這相數據的組件也會發生更新
  • 它經過 mapState 把全局的 state 和 getters 映射到當前組件的 computed 計算屬性

18.4 vuex 的 getter 特性是什麼

  • getter 能夠對 state 進行計算操做,它就是 store 的計算屬性
  • 雖然在組件內也能夠作計算屬性,可是 getters 能夠在多給件之間複用
  • 若是一個狀態只在一個組件內使用,是能夠不用 getters

18.5 vuex 的 mutation 特性是什麼

  • action 相似於 muation, 不一樣在於:action 提交的是 mutation,而不是直接變動狀態
  • action 能夠包含任意異步操做

18.6 vue 中 ajax 請求代碼應該寫在組件的 methods 中仍是 vuex 的 action 中

若是請求來的數據不是要被其餘組件公用,僅僅在請求的組件內使用,就不須要放入 vuex 的 state 裏

若是被其餘地方複用,請將請求放入 action 裏,方便複用,幷包裝成 promise 返回

18.7 不用 vuex 會帶來什麼問題

  • 可維護性會降低,你要修改數據,你得維護 3 個地方
  • 可讀性降低,由於一個組件裏的數據,你根本就看不出來是從哪裏來的
  • 增長耦合,大量的上傳派發,會讓耦合性大大的增長,原本 Vue 用 Component 就是爲了減小耦合,如今這麼用,和組件化的初衷相背

18.8 vuex 原理

vuex 僅僅是做爲 vue 的一個插件而存在,不像 Redux,MobX 等庫能夠應用於全部框架,vuex 只能使用在 vue 上,很大的程度是由於其高度依賴於 vue 的 computed 依賴檢測系統以及其插件系統,

vuex 總體思想誕生於 flux,可其的實現方式完徹底全的使用了 vue 自身的響應式設計,依賴監聽、依賴收集都屬於 vue 對對象 Property set get 方法的代理劫持。最後一句話結束 vuex 工做原理,vuex 中的 store 本質就是沒有 template 的隱藏着的 vue 組件;

18.9 擴展問題

18.9.1 使用 Vuex 只需執行 Vue.use(Vuex),並在 Vue 的配置中傳入一個 store 對象的示例,store 是如何實現注入的?

美團

Vue.use(Vuex) 方法執行的是 install 方法,它實現了 Vue 實例對象的 init 方法封裝和注入,使傳入的 store 對象被設置到 Vue 上下文環境的\(store 中。所以在 Vue Component 任意地方都可以經過 this.\)store 訪問到該 store。

18.9.2 state 內部支持模塊配置和模塊嵌套,如何實現的?

美團

在 store 構造方法中有 makeLocalContext 方法,全部 module 都會有一個 local context,根據配置時的 path 進行匹配。因此執行如 dispatch('submitOrder', payload)這類 action 時,默認的拿到都是 module 的 local state,若是要訪問最外層或者是其餘 module 的 state,只能從 rootState 按照 path 路徑逐步進行訪問。

18.9.3 在執行 dispatch 觸發 action(commit 同理)的時候,只需傳入(type, payload),action 執行函數中第一個參數 store 從哪裏獲取的?

美團

store 初始化時,全部配置的 action 和 mutation 以及 getters 均被封裝過。在執行如 dispatch('submitOrder', payload)的時候,actions 中 type 爲 submitOrder 的全部處理方法都是被封裝後的,其第一個參數爲當前的 store 對象,因此可以獲取到 { dispatch, commit, state, rootState } 等數據。

18.9.4 Vuex 如何區分 state 是外部直接修改,仍是經過 mutation 方法修改的?

美團

Vuex 中修改 state 的惟一渠道就是執行 commit('xx', payload) 方法,其底層經過執行 this._withCommit(fn) 設置_committing 標誌變量爲 true,而後才能修改 state,修改完畢還須要還原_committing 變量。外部修改雖然可以直接修改 state,可是並無修改_committing 標誌位,因此只要 watch 一下 state,state change 時判斷是否_committing 值爲 true,便可判斷修改的合法性。

18.9.5 調試時的"時空穿梭"功能是如何實現的?

美團

devtoolPlugin 中提供了此功能。由於 dev 模式下全部的 state change 都會被記錄下來,'時空穿梭' 功能其實就是將當前的 state 替換爲記錄中某個時刻的 state 狀態,利用 store.replaceState(targetState) 方法將執行 this._vm.state = state 實現。

19. 指令相關

19.1 自定義指令(v-check, v-focus) 的方法有哪些? 它有哪些鉤子函數? 還有哪些鉤子函數參數

  • 全局定義指令:在 vue 對象的 directive 方法裏面有兩個參數, 一個是指令名稱, 另外一個是函數。
  • 組件內定義指令:directives
  • 鉤子函數: bind(綁定事件出發)、inserted(節點插入時候觸發)、update(組件內相關更新)
  • 鉤子函數參數: el、binding

19.2 說出至少 4 種 vue 當中的指令和它的用法

v-if(判斷是否隱藏)、v-for(把數據遍歷出來)、v-bind(綁定屬性)、v-model(實現雙向綁定)

20. axios

20.1 axios 是什麼?怎麼使用?描述使用它實現登陸功能的流程

[!NOTE]
思路:使用Vue的router.beforeEach鉤子函數結合axios的攔截器功能來實現。

20.2 axios與ajax, fetch的區別和優缺點?

  • 參考文章:https://blog.csdn.net/qq_36407875/article/details/84642060
相關文章
相關標籤/搜索