主頁 > 企業開發 > 【前端知識體系-JS相關】深入理解MVVM和VUE

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

2020-10-12 13:35:00 企業開發

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 = https://www.cnblogs.com/fecommunity/p/{
            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());
    }

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

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

3. Vue的整個實作流程原始碼解讀???(總結點)

3.1 決議模板成render函式

    <template></template> --->>> render 函式

[!NOTE]

  • with函式的使用
  • 模板中的所有資訊都被render函式包含
  • 模板中用到的data中的屬性,都變成了JS變數
  • 模板中的v-model v-for v-on都變成了JS邏輯
  • render函式回傳vnode

3.2 回應式開始監聽資料

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

3.3 首次渲染,顯示頁面,且系結依賴

[!NOTE]

  • 初次渲染,執行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]

  • 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]

  • 修改屬性,被回應式的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')

  2. data上面屬性值是陣列的時候,需要用陣列的方法操作陣列,而不能通過index或者length屬性去操作陣列,因為監聽不到屬性操作的動作,

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玩下,

    // 對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 = https://www.cnblogs.com/fecommunity/p/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那邊也需要加這行,

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 = https://www.cnblogs.com/fecommunity/p/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="https://www.cnblogs.com/fecommunity/p/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

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/169025.html

標籤:JavaScript

上一篇:【前端知識體系-JS相關】虛擬DOM和Diff演算法

下一篇:使用jqPrint.js呼叫瀏覽器列印界面,列印網頁中的某一部分該部分含有ECharts圖表

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more