浅谈MVC模式与MVVM模式

本文介绍了MVC和MVVM设计模式的区别,重点讲解了MVVM的核心思想——数据双向绑定。在Vue2.x的示例中,通过Object.defineProperty实现数据劫持,展示了数据变化如何驱动视图更新。而在Vue3.x中,使用Proxy对象对整个对象进行代理,提高了性能并解决了Vue2.x中的一些问题,如数组和新增属性的监听。
摘要由CSDN通过智能技术生成

1.MVC模式

MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。

  • Model(模型) - 代表数据
  • View(视图) - 代表用户可见的界面,用户可通过界面上的元素触发控制层的事件来改变Model然后控制层在数据更新时会更新视图
  • Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

 


// 模型层
  <script>
    var data = {
      title: '李焕英',
      age:'20',
      sex:'女'
    }


//控制层
    function render() {
      document.querySelector('#app').innerHTML = `
            <div>你好${data.title}今年${data.age}岁</div>
             <button id="btn" onclick = 'fn()'>按钮</button>`
    }
    render()
    function fn() {
      data.title = '贾玲'
      data.age = '25'
      render()
    }

2.MVVC模式

    MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。

『View』:视图层(UI 用户界面)
『ViewModel』:业务逻辑层(一切 js 可视为业务逻辑)
『Model』:数据层(存储数据及对数据的处理如增删改查)

  • MVVM 将数据双向绑定(data-binding)作为核心思想,View 和 Model 之间没有联系,它们通过 ViewModel 这个桥梁进行交互。

  • Model 和 ViewModel 之间的交互是双向的,因此 View 的变化会自动同步到 Model,而 Model 的变化也会立即反映到 View 上显示。

  • 当用户操作 View,ViewModel 感知到变化,然后通知 Model 发生相应改变;反之当 Model 发生改变,ViewModel 也能感知到变化,使 View 作出相应更新。

2.1在vue2.0中MVVC模式应用


 // Model
    var data = {
      name: '李焕英'
    }

// View-Model
    var name = data.name
    Object.defineProperty(data, 'name', {
      get() {
        console.log("执行了get");
        return name
      },
      set(newVal) {
        name = newVal
        console.log("执行了set");
        watch()
      }
    })


    function watch() {
      render()
    }

    function render() {
      document.querySelector('#app').innerHTML = ` 
          <p> 你好,${data.name}</p>
          <button onclick = 'fn()'> 点我改名 </button>
       `
    }
    function fn() {
      data.name = '贾玲'
    }


    render()

  在vue2.0中 , 通过 Object.defineProperty 将 data返回的对象中的属性劫持 ,后面的代码需要读取data中的数据时 ,会直接执行get函数,读取到get函数的返回值。 而在劫持的属性更改时,则会调用set函数 , set函数会将更新的值以参数的新式传入,然后赋值给缓存的副本,之后通知观察者,观察者在数据更新时会触发渲染函数,渲染的过程中会读取,所以会再调用一次get函数,从而实现视图的实时更新与数据绑定。

然而Object.definePropety有许多缺点:

 1. 一次只能劫持一个属性,劫持所有属性需要遍历,比较消耗性能

2.用下标的方式向数组内增加元素时观察者无法观察到此次数据的改变

3.data.属性名的方式添加新属性或删除属性时观察者也无法观察到此次数据的改变

于是在vue3.0中 ,采取了更优秀的方案

     const newData = new Proxy(data, ({
      get(target, key) {
        console.log('读取')
        return target[key]
       },
       set(target, key, newValue) {
        console.log('修改');
        target[key] = newValue
         watch();
       }
     }))

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

该函数可以一次性劫持整个对象,无需遍历。

proxy是可以监听到数组的变化

proxy还可以监听到添加新属性的变化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值