Notes
  • 速记
  • 前端面试
  • HTML / CSS
    • HTML
    • CSS
    • CSS Modules
      • CSS Modules
        • CSS Modules Usage
      • Stylus
      • Nunjucks
  • Javascript
    • 正则表达式
    • 代理(Proxy)和反射(Reflection)
    • 类型转换
    • 按位操作
    • 数据可视化
    • 数据采集
      • 无(全)埋点
      • 模块曝光事件
    • package
      • axios
    • Event Loop
    • React
      • React热身
      • VDOM和DOM-diff
    • Vue
    • Omi
    • MVVM
    • 百度小程序
    • AST抽象语法树
    • ServiceWorker
    • WebSocket
  • NodeJS
    • Assert 断言
    • chai.js 断言库
    • Node Global Obj And Var
    • CLI Writed By Nodejs
    • Framework
      • Hapi Js Framework
    • Electrode JS
      • Electrode Platform
      • Electrode Question
    • Redux
      • Redux Basic Usage
      • Middleware And Asynchronous
      • React-Redux 的用法
    • NPM
      • package.json
      • semver
    • Webpack
      • 编写插件
    • 同构渲染
    • 调用DLL
  • 服务端
    • Inotify
    • Linux
    • Nginx
      • Nginx简介
      • Nginx原理、安装预配置
    • TCP/IP 协议
    • HTTP 协议
      • 基础概念篇
      • 协议详解篇
    • Process
      • 阻塞与非阻塞
      • 进程与线程优性能
  • 数据库
    • GraphQL
  • 移动端
  • 微信小程序
    • 微信小程序安装(linux)
    • 小程序第三方框架
  • 开发工具
    • 开发工具安装
    • Vim Command Collection
    • Git
      • Git Rule
      • Git Submodule
      • gitignore
    • Lerna
    • Ubuntu开发环境安装
  • 运维测试
    • Docker
      • Docker Synopsis
      • docker.sock
    • Nightwatch
    • Jest
  • 算法/数学/架构
    • 设计模式
    • 架构设计经验分享
    • 前端架构
    • 基本数据结构
    • 函数式编程
  • 软件工程
    • 软件生命周期
Powered by GitBook
On this page
  • MVVM框架理解
  • MVC
  • MVVM的实现原理
  • reference

Was this helpful?

  1. Javascript

MVVM

MVVM框架理解

MVC

![mvc框架]('../static/images/mvc.png')

将整个前端页面分成View,Controller,Modal,视图上发生变化,通过Controller(控件)将响应传入到Model(数据源),由数据源改变View上面的数据 整个过程看起来是行云流水,业务逻辑放在Model当中,页面渲染逻辑放在View当中,但在实际运用上却存在一个问题:那就是MVC框架允许View和Model直接进行通信!! 背离了开发所应该遵循的“开放封闭原则”

面对这个问题,MVVM框架就出现了,它与MVC框架的主要区别有两点: 1. 实现数据与视图的分离 2. 通过数据来驱动视图,开发者只需要关心数据变化,DOM操作被封装了

![mvvm框架]("../static/images/mvvm.png") 可以看到MVVM分别指View,Model,View-Model,View通过View-Model的DOM Listeners将事件绑定到Model上,而Model则通过Data Bindings来管理View中的数据,View-Model从中起到一个连接桥的作用

MVVM的实现原理

MVVM的实现主要是三个核心点: 1. 响应式:vue如何监听data的属性变化 2. 模板解析:vue的模板是如何被解析的 3. 渲染:vue模板是如何被渲染成HTML的

响应式

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]) // 监听
                        return data[key]
                    },
                    set: function (newVal) {
                        console.log('set', newVal) // 监听
                        data[key] = newVal
                    }
                })
            })(key)
        }

模板解析

  1. 首先模板是什么? 模板本质上是一串字符串,它看起来和html的格式很相像,实际上有很大的区别,因为模板本身还带有逻辑运算,比如v-if,v-for等等,但它最后还是要转换为html来显示 模板在vue中必须转换为JS代码,原因在于:在前端环境下,只有JS才是一个图灵完备语言,才能实现逻辑运算,以及渲染为html页面

  2. render render函数中的核心就是with函数

    with函数将某个对象添加到作用域链的顶部,如果在 statement中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值

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

而在render函数中,with的用法是这样:

<div id="app">
  <div>
      <input v-model="title">
      <button v-on:click="add">submit</button>
  </div>
  <div>
      <ul>
          <li v-for="item in list">{{item}}</li>
      </ul>
  </div>
</div>
// 对应的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这个对象放在作用域链的顶部,因为在函数内部我们会多次调用vm内部的属性,所以使用with可以缩短变量长度,提供系统运行效率。

_c函数表示的是创建一个新的html元素, _v函数表示创建一个文本节点,_l函数表示创建一个数组

最终render函数返回的是一个虚拟DOM.

如何将模板渲染为html

模板渲染为html分为两种情况: 第一种是初次渲染的时候 第二种是渲染之后数据发生改变的时候,它们都需要调用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())
}

首先读取当前的虚拟DOM——vm._vnode,判断其是否为空,若为空,则为初次渲染,将虚拟DOM全部渲染到所对应的容器当中(vm.$el),若不为空,则是数据发生了修改,通过响应式我们可以监听到这一情况,使用diff算法完成新旧对比并修改

reference

PreviousOmiNext百度小程序

Last updated 5 years ago

Was this helpful?

MVVM框架理解及其原理实现