成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

MVVM框架理解及其原理實現(xiàn)

DevWiki / 1436人閱讀

摘要:小白一枚,一直使用的是,想要多了解一些其它的框架,正好最近越來越火熱,上的數(shù)已經(jīng)超過了??蚣芾斫庹f起這個模型,就不得不說框架。函數(shù)表示創(chuàng)建一個文本節(jié)點,函數(shù)表示創(chuàng)建一個數(shù)組。

小白一枚,一直使用的是React,想要多了解一些其它的框架,正好最近Vue越來越火熱,Github上的Star數(shù)已經(jīng)超過了React。而其背后蘊含的MVVM框架思想也一直跟React的組件化開發(fā)思想并駕齊驅(qū),在這里也是本著兼收并蓄的思想,多了解一種開發(fā)模式。因此通過一些學(xué)習(xí)資料,寫一些自己對MVVM開發(fā)思想的理解。

廢話不多說,咱們進(jìn)入正題。

MVVM框架理解

說起這個MVVM模型,就不得不說MVC框架。

將整個前端頁面分成View,Controller,Modal,視圖上發(fā)生變化,通過Controller(控件)將響應(yīng)傳入到Model(數(shù)據(jù)源),由數(shù)據(jù)源改變View上面的數(shù)據(jù)。

整個過程看起來是行云流水,業(yè)務(wù)邏輯放在Model當(dāng)中,頁面渲染邏輯放在View當(dāng)中,但在實際運用上卻存在一個問題:那就是MVC框架允許View和Model直接進(jìn)行通信?。?/strong>

換句話說,View和Model之間隨著業(yè)務(wù)量的不斷龐大,會出現(xiàn)蜘蛛網(wǎng)一樣難以處理的依賴關(guān)系,完全背離了開發(fā)所應(yīng)該遵循的“開放封閉原則”

面對這個問題,MVVM框架就出現(xiàn)了,它與MVC框架的主要區(qū)別有兩點:
1、實現(xiàn)數(shù)據(jù)與視圖的分離
2、通過數(shù)據(jù)來驅(qū)動視圖,開發(fā)者只需要關(guān)心數(shù)據(jù)變化,DOM操作被封裝了。

可以看到MVVM分別指View,Model,View-Model,View通過View-Model的DOM Listeners將事件綁定到Model上,而Model則通過Data Bindings來管理View中的數(shù)據(jù),View-Model從中起到一個連接橋的作用。

MVVM的實現(xiàn)原理:

MVVM的實現(xiàn)主要是三個核心點:

響應(yīng)式:vue如何監(jiān)聽data的屬性變化

模板解析:vue的模板是如何被解析的

渲染:vue模板是如何被渲染成HTML的

響應(yīng)式:

對于MVVM來說,data一般是放在一個對象當(dāng)中,就比如這樣:

         var obj = {
             name: "zhangsan",
             age: 25
         }

當(dāng)我們訪問或修改obj的屬性的時候,比如:

         console.log(obj.name)  //訪問
         obj.age = 22            //修改

但是這樣的操作vue本身是沒有辦法感知到的,那么應(yīng)該如何讓vue知道我們進(jìn)行了訪問或是修改的操作呢?
那就要使用Object.defineProperty

        var vm = {}
        var data = {
            name: "zhangsan",
            age: 20
        }

        var key, value
        for (key in data) {
            (function (key) {
                Object.defineProperty(vm, key, {
                    get: function () {
                        console.log("get", data[key]) // 監(jiān)聽
                        return data[key]
                    },
                    set: function (newVal) {
                        console.log("set", newVal) // 監(jiān)聽
                        data[key] = newVal
                    }
                })
            })(key)
        }

通過Object.defineProperty將data里的每一個屬性的訪問與修改都變成了一個函數(shù),在函數(shù)get和set中我們即可監(jiān)聽到data的屬性發(fā)生了改變。

模板解析:

首先模板是什么?

模板本質(zhì)上是一串字符串,它看起來和html的格式很相像,實際上有很大的區(qū)別,因為模板本身還帶有邏輯運算,比如v-if,v-for等等,但它最后還是要轉(zhuǎn)換為html來顯示。

    
  • {{item}}

模板在vue中必須轉(zhuǎn)換為JS代碼,原因在于:在前端環(huán)境下,只有JS才是一個圖靈完備語言,才能實現(xiàn)邏輯運算,以及渲染為html頁面。

這里就引出了vue中一個特別重要的函數(shù)——render

render函數(shù)中的核心就是with函數(shù)。

with函數(shù)將某個對象添加到作用域鏈的頂部,如果在 statement中有某個未使用命名空間的變量,跟作用域鏈中的某個屬性同名,則這個變量將指向這個屬性值。

舉個例子:

       var obj = {
            name: "zhangsan",
            age: 20,
            getAddress: function () {
                alert("beijing")
            }
        }
        function fn1() {
            with(obj) {
                alert(age)
                alert(name)
                getAddress()
            }
        }
        fn1()

with將obj這個對象放在了自己函數(shù)的作用域鏈的頂部,當(dāng)執(zhí)行下列函數(shù)時,就會自動到obj這個對象去尋找同名的屬性。

而在render函數(shù)中,with的用法是這樣:

    
  • {{item}}
        // 對應(yīng)的js文件
        var data = {
            title: "",
            list: []
        }
        // 初始化 Vue 實例
        var vm = new Vue({
            el: "#app",
            data: data,
            methods: {
                add: function () {
                    this.list.push(this.title)
                    this.title = ""
                }
            }
        })

        
        with(this){  // this 就是 vm
            return _c(
                "div",
                {
                    attrs:{"id":"app"}
                },
                [
                    _c(
                        "div",
                        [
                            _c(
                                "input",
                                {
                                    directives:[
                                        {
                                            name:"model",
                                            rawName:"v-model",
                                            value:(title),
                                            expression:"title"
                                        }
                                    ],
                                    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",
                                _l((list),function(item){return _c("li",[_v(_s(item))])})
                            )
                        ]
                    )
                ]
            )
        }

在一開始,因為new操作符,所以this指向了vm,通過with我們將vm這個對象放在作用域鏈的頂部,因為在函數(shù)內(nèi)部我們會多次調(diào)用vm內(nèi)部的屬性,所以使用with可以縮短變量長度,提供系統(tǒng)運行效率。

其中的_c函數(shù)表示的是創(chuàng)建一個新的html元素,其基本用法為:

                _c(element,{attrs},[children...])

其中的element表示所要創(chuàng)建的html元素類型,attrs表示所要創(chuàng)建的元素的屬性,children表示該html元素的子元素。

_v函數(shù)表示創(chuàng)建一個文本節(jié)點,_l函數(shù)表示創(chuàng)建一個數(shù)組。

最終render函數(shù)返回的是一個虛擬DOM。

如何將模板渲染為html

模板渲染為html分為兩種情況,第一種是初次渲染的時候,第二種是渲染之后數(shù)據(jù)發(fā)生改變的時候,它們都需要調(diào)用updateComponent,其形式如下:

vm._update(vnode){
  const prevVnode = vm._vnode
  vm._vnode = vnode
  if (!prevVnode){
    vm.$el = vm.__patch__(vm.$el,vnode)
  } else {
    vm.$el = vm.__patch__(prevVnode,vnode)
  }
}

function updateComponent(){
  vm._update(vm._render())
}

首先讀取當(dāng)前的虛擬DOM——vm._vnode,判斷其是否為空,若為空,則為初次渲染,將虛擬DOM全部渲染到所對應(yīng)的容器當(dāng)中(vm.$el),若不為空,則是數(shù)據(jù)發(fā)生了修改,通過響應(yīng)式我們可以監(jiān)聽到這一情況,使用diff算法完成新舊對比并修改。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/96625.html

相關(guān)文章

  • 前端面試題總結(jié)

    摘要:工作中總結(jié)的一些比較重要的前端技能,覺得在面試中比較合適提問,即能查看出面試者的技術(shù)功底,又能考察其知識體系的廣度。異步編程的考察,其關(guān)鍵字的使用,與的關(guān)系,同時可以深入考察總共有幾種異步編程的方式。 工作中總結(jié)的一些比較重要的前端技能,覺得在面試中比較合適提問,即能查看出面試者的技術(shù)功底,又能考察其知識體系的廣度。適用于應(yīng)屆生和工作年限兩年下的同學(xué),掌握下面的知識基本滿足工作需求了。...

    wuyangnju 評論0 收藏0
  • 前端面試題總結(jié)

    摘要:工作中總結(jié)的一些比較重要的前端技能,覺得在面試中比較合適提問,即能查看出面試者的技術(shù)功底,又能考察其知識體系的廣度。異步編程的考察,其關(guān)鍵字的使用,與的關(guān)系,同時可以深入考察總共有幾種異步編程的方式。 工作中總結(jié)的一些比較重要的前端技能,覺得在面試中比較合適提問,即能查看出面試者的技術(shù)功底,又能考察其知識體系的廣度。適用于應(yīng)屆生和工作年限兩年下的同學(xué),掌握下面的知識基本滿足工作需求了。...

    yangrd 評論0 收藏0
  • 前端MVVM模式及其在Vue和React中的體現(xiàn)

    摘要:在模式中一般把層算在層中,只有在理想的雙向綁定模式下,才會完全的消失。層將通過特定的展示出來,并在控件上綁定視圖交互事件,一般由框架自動生成在瀏覽器中。三大框架的異同三大框架都是數(shù)據(jù)驅(qū)動型的框架及是雙向數(shù)據(jù)綁定是單向數(shù)據(jù)綁定。 MVVM相關(guān)概念 1) MVVM典型特點是有四個概念:Model、View、ViewModel、綁定器。MVVM可以是單向綁定也可以是雙向綁定甚至是不綁...

    沈建明 評論0 收藏0
  • vue中MVVM原理及其實現(xiàn)

    摘要:實現(xiàn)訂閱中心和之間通信的橋梁是訂閱中心,其主要職責(zé)是在自身實例化時往屬性訂閱器里面添加自己,與建立連接自身必須有一個方法,與建立連接當(dāng)屬性變化時,中通知,然后能調(diào)用自身的方法,并觸發(fā)中綁定的回調(diào),實現(xiàn)更新。 一. 什么是mvvm MVVM是Model-View-ViewModel的簡寫。它本質(zhì)上就是MVC 的改進(jìn)版。MVVM 就是將其中的View 的狀態(tài)和行為抽象化,讓我們將視圖 UI...

    Awbeci 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<