MVVM 和 VUE

来源:https://www.cnblogs.com/iceflorence/archive/2018/04/26/8949788.html
-Advertisement-
Play Games

一,使用jquery和使用vue的區別 二,對MVVM的理解 三,vue中如何實現響應式 四,vue如何解析模版 五,vue整個實現流程 一,使用jquery和使用vue的區別 jquery實現todo-list <!DOCTYPE html> <html lang="en"> <head> <me ...


一,使用jquery和使用vue的區別 二,對MVVM的理解 三,vue中如何實現響應式 四,vue如何解析模版 五,vue整個實現流程   一,使用jquery和使用vue的區別 jquery實現todo-list
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>todo-list-jquery</title>
</head>

<body>
    <div>
        <input type="text" id="txt-title">
        <button id="btn-submit">submit</button>
    </div>
    <ul id="ul-list"></ul>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
    var $txtTitle = $('#txt-title');
    var $btnSubmit = $('#btn-submit');
    var $ulList = $('#ul-list');
    $btnSubmit.click(function() {
        var title = $txtTitle.val();
        if (!title) {
            return;
        }
        var $li = $('<li>' + title + '</li>');
        $ulList.append($li);
        $txtTitle.val('');
    })
    </script>
</body>

</html>
vue實現todo-list
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>todo-list-vue</title>
    <script src="./vue-2.5.13.js"></script>
</head>

<body>
    <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>
    <script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: '',
            list: [],
        },
        methods: {
            add: function() {
                if (this.title) {
                    this.list.push(this.title);
                    this.title = '';
                }
            }
        }
    })
    </script>
</body>

</html> 
jquery和vue兩者的區別: 數據和視圖的分離-解耦(開放封閉原則) 以數據驅動視圖-只關心數據變化,DOM操作被封裝   二,對MVVM的理解 1,先說下MVC: M-Model 數據 V-VIew 視圖、界面 C-Controller 控制器、邏輯處理 兩種場景: 2,MVVM Model-模型、數據 View-視圖、模版(視圖和模型是分離的) ViewModel-連接Model和View,“橋”   3,關於ViewModel MVVM不算是一種創新-是微創新 但其中的ViewModel是一種創新 真正結合前端場景應用的創建       4,MVVM框架的三大要素(實現的三要素) 響應式:vue如何間聽到data的每個屬性變化? 模版引擎:vue的模版如何被解析,指令如何處理? 渲染:vue的模版如何被渲染成html?以及渲染過程   三,vue中如何實現響應式 1,什麼是響應式 修改data屬性之後,vue立刻監聽到 data屬性被代理到vm(this)上,data的屬性,同時也變成了this的屬性 例:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>vue-demo</title>
    <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>

<body>
    <div id="app">
        <p>{{name}}</p>
        <p>{{age}}</p>
    </div>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{
                name:'zs',
                age:20
            }
        })
        console.log(vm.age)
    </script>
</body>

</html>

 在控制台修改vm.age  或者vm.name,立刻會被監聽渲染出來

2,Object.defineProperty:直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。 語法:
Object.defineProperty(obj, prop, descriptor)

例子:

    var obj = {};
    var _name = 'zs';
    Object.defineProperty(obj,'name',{
        get:function(){
            console.log('get',_name);//監聽
            return _name;
        },
        set:function(newVal){
            console.log('set',newVal);//監聽
            _name = newVal;
        }
    });
3,模擬實現(監聽+代理)
    var vm = {};
    var data = {
        name: 'zs',
        age: 20
    };
    var key, value;
    for (key in data) {
        // 命中閉包,新建一個函數,保證key的獨立的作用域
        (function(key) {
            Object.defineProperty(vm, key, { //data屬性代理到vm上
                get: function() {
                    console.log('get', data[key]); //監聽
                    return data[key];
                },
                set: function(newVal) {
                    console.log('set', newVal); //監聽
                    data[key] = newVal;
                }
            })
        })(key)
    }
看下控制臺中,此時列印的vm   四,vue如何解析模版 1,模版是什麼 本質:字元串 有邏輯,如v-if,v-for等 與html格式很像,但有很大區別(html靜態的,沒有邏輯) 要轉換為html來顯示   模版最終必須要轉換成js代碼,原因如下: 有邏輯(v-if,v-for),前端必須用js才能實現(圖靈完備) 轉換為html渲染頁面,前端必須用js才能實現 因此,模版最終要轉換成一個js函數(render函數,即渲染函數)   2,render函數 render函數-with的用法(with可以瞭解下實現,但是實際開發中最好不要用,問題比較多) 先看下with的簡單用法:
    var obj = {
        name: 'xx',
        age:20,
        getAddress:function(){
            console.log('bj');
        }
    }
    // 不用with
    function fn(){
        console.log(obj.name);
        console.log(obj.age);
        obj.getAddress();
    }
    fn()

    // 使用with
    function fn1(){
        with(obj) {
            console.log(name);
            console.log(age);
            getAddress();
        }
    }
    fn1()
3,render函數 模版:
    <div id="app">
        <p>{{price}}</p>
    </div>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{
                price:100
            }
        })
    </script>

render函數如下:

    // 以下是手寫的 render 函數 使用 with ,代碼簡潔一些
    function render() {
        with(this) {
            return _c(
                'div', {
                    attrs: { "id", "app" }
                }, [
                    _c('p', [_v(_s(price))])
                ]
            )
        }
    }
    // 不用 with 的改寫的 render 函數
    function render1() {
        return vm._c(
            'div', {
                attrs: { "id", "app" }
            }, [
                vm._c('p', [_vm.v(vm._s(vm.price))])
            ]
        )
    }

    // 模版中所有信息都包含在了 render 函數中
    // this === vm
    // price 即 this.price 即vm.price, 即 data 中的 price
    // _c 即 this._c , 即 vm._c

看下控制台:

問題: 從哪裡可以看到render函數? 複雜一點的例子,render函數是什麼樣子的? v-if, v-for, v-on都是怎麼處理的?   回顧之前的demo
<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>

 對應的render函數:(通過在vue-2.5.13.js源碼中 console.log(code.render)得出)

    with(this){
            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(
                    'ul',
                        _l(
                            (list),function(item){
                                return _c(
                                    'li',
                                    [
                                        _v(
                                            _s(item)
                                        )   
                                    ]
                                )
                            }
                        )
                    )   
                ]
            )
        }
根據todo-list demo的render函數: v-model是怎麼實現的?:雙向數據綁定,既有get,又有set v-on:click是怎麼實現的?:渲染時綁定click事件 v-for是怎麼實現的?:對數組進行遍歷,li標簽,最後歸結為數組,作為ul的子元素   模版生成html   vm.c其實就相當於snabbdom中的h函數 render函數執行之後,返回的是vnode
vm._update(vnode) {
        const prevVnode = vm._vnode;
        vm._vnode = vnode;
        if (!prevVnode) {
            // 初次渲染
            vm.$el = vm.__patch__(vm.$el, vnode);
        } else {
            // re-render
            vm.$el = vm.__patch__(prevVnode, vnode);
        }

    }

    function updateComponent() {
        // vm._render即上面的render函數,返回vnode
        vm._update(vm._render())
    }

    // updateComponent實現了vdom的patch
    // 頁面首次渲染執行updateComponent(執行第一個patch)
    // data中每次修改屬性,執行updateComponent,修改data,set中可以執行updateComponent

 

vue如何解析模版: 模版:字元串(本質),有邏輯,嵌入js變數... 模版必須轉換為js代碼(有邏輯,渲染html,js變數)前端中,只有js才能處理邏輯和渲染html等 render函數: with語法,就是snabbdom里h函數的樣子 render函數執行是返回vnode updateComponent 首次渲染,非首次渲染(data屬性修改)   五,vue的整個實現流程 第一步:解析模版成render函數 with用法(瞭解即可,自己開發的時候,儘量避免使用) 模版中的所有信息都被render函數包含 模版中用到的data中的屬性,都變成了js變數 模版中的v-model,v-for,v-on都變成了js邏輯 render函數返回vnode   第二步:響應式開始監聽 Object.defineProperty中設置監聽 將data的屬性代理到vm上   第三步:首次渲染,顯示頁面,且綁定依賴 初次渲染,執行updateComponent,執行vm._render() 執行render函數,會訪問到vm.list和vm.title 會被響應式的get方法監聽到(後面詳細講) 執行updateComponent,會走到vdom的patch方法 patch將vnode渲染成DOM,初次渲染完成 疑問: 為何要監聽get,直接監聽set不行嗎? data中有很多屬性,有些被用到,有些可能不被用到 被用到的會走到get,不被用到的不會走到get 未走到get中的屬性,set的時候我們也無須關心 避免不必要的重覆渲染   第四步:data屬性變化,觸發rerender 修改屬性,被響應式的set監聽到 set中執行updateComponent (這裡是非同步的) updateComponent重新執行vm._render() 生成的vnode和prevVnode,通過patch進行對比 渲染到html中

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先簡單瞭解js的typeof,會返回六種類型 即 number string boolen function object undefined 也就是六種基本數據類型 顯示類型轉換大概有以下幾種: Number() 轉換為number類型 String() 轉換為string類型 Boolean( ...
  • 上節漏了幾個地方沒有講。 1、process_params 2、trim_prefix 3、done 分別是動態路由,深層路由與最終回調。 這節就只講這三個地方,案例還是express-generator,不過請求的方式更為複雜。 process_params 在講這個函數之前,需要先進一下path ...
  • 快遞地址寫錯了怎麼辦?快遞地址寫的不詳細怎麼辦?怎麼皮批量錄入收件人地址?微商怎麼批量錄入發件人地址?快寶地址清洗,有效的解決了寄送快遞時,批量錄入收件人信息、發件人信息時,糾正地址數據,不完整地址識別,地址信息不完整時補全,已經合併區縣的地址更正為最新的區縣等,並輸出結構化地址數據的一個有效方案。 ...
  • 錯誤一定會發生 當 JavaScript 引擎執行 JavaScript 代碼時,會發生各種錯誤: 可能是語法錯誤,通常是程式員造成的編碼錯誤或錯別字。 可能是拼寫錯誤或語言中缺少的功能(可能由於瀏覽器差異)。 可能是由於來自伺服器或用戶的錯誤輸出而導致的錯誤。 當然,也可能是由於許多其他不可預知的 ...
  • 可直接複製粘貼運行 <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <titl ...
  • 前言 最近接了一個外包的項目,其中有個需求是這樣的, 需要展示一個中國的統計地圖,要求每個省市區都是不一樣的顏色,必須特別區分開。以及隱藏南海部分。 看了Echats相關文檔,發現有類似的demo,但不是特別符合要求。於是自己仔細讀文檔研究。找到解決問題於是分享一下。 正文 廢話不多少,直接上代碼 ...
  • 項目中使用vue搭建前端頁面,並通過axios請求後臺api介面,完成數據交互。如果驗證口令token寫在在每次的介面中,也是個不小的體力活,而且也不靈活。這裡分享使用vue自帶攔截器,給每次請求的頭部添加token,而且相容了IE9。 寫在後面。因為我的token放在了緩存中,所以在每次請求前,我 ...
  • 頁面滾動插件 finger-mover https://github.com/HcySunYang/finger-mover https://fmover.hcysun.me/#/zh-cn/plugins/simulation-scroll-y 封裝vue組件 https://github.com ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...