热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于vue.js:vueMVVM双向绑定

MV*模式MVCMVPMVVM1MVC一个利用分为三局部模型(Model):数据保留应用程序的数据、管制与批改这些数据的业务规定Model扭转时:告诉View,为View提供查问Model相干状态的能力,为Controller提供拜访封装在Model外部的应用程序性能的能力。视图(View):用户界面组织Model的内容Model扭转时:View负责保护数据体现的统一
MV*模式
  1. MVC
  2. MVP
  3. MVVM

1 MVC

一个利用分为三局部

  1. 模型 (Model):数据保留

    应用程序的数据、管制与批改这些数据的业务规定
    Model扭转时:告诉View,为View提供查问Model相干状态的能力,为Controller提供拜访封装在Model外部的应用程序性能的能力。

  2. 视图 (View):用户界面

    组织Model的内容
    Model扭转时:View负责保护数据体现的一致性,同时View将用户的申请告诉Controller

  3. 控制器 (Controller):业务逻辑

    应用程序的行为
    解释来自View的用户申请,把申请映射为行为,再由Model实现这些行为。

结构图:

  • View传送指令到Controller
  • Controller实现业务逻辑后,要求Model扭转状态
  • Model将新的数据发送到View,用户失去反馈

    承受指令的形式
    由View承受指令,传递给Controller
    Controller间接承受指令

2 MVP

  1. 模型(Model):提供数据
  2. 视图(View):用户界面
  3. 示意器(Presenter):逻辑的解决

结构图

  • View与Model无分割,都通过Presenter传递
  • View中不部署任何业务逻辑 – 被动视图
  • 所有逻辑都部署在Presenter

与MVC的区别
View不能间接从Model中读取数据

3 MVVM

基本上与MVP模式统一

  1. 模型(Model):保留数据
  2. 视图(View):用户界面
  3. 数据驱动(View-Model):业务逻辑

    VM负责转换Model中的数据对象

结构图

  • 操作View时,ViewModel感知变动,告诉Model产生相应的变动,若Model扭转时,ViewModel感知变动,告诉View进行更新
  • ViewModel与View双向数据绑定,Model通过接口申请数据交互,承前启后。
双向数据绑定
  1. Vue2:Object.defineProperty()
  2. Vue3:Proxy代理

1 Vue2双向绑定实现

Object.defineProperty(obj,prop,description)

原理简析,不做依赖收集

/**
 * 对Object.defineProperty()进行封装
 */
function defineReactive(obj, key, value) {
    //递归 - 对象的属性仍是对象
    observe(value);
    //变动侦测
    Object.defineProperty(obj, key, {
        get() {
            return value;
        },
        set(newVal) {
            if (newVal !== value) {
                updateView();
                value = newVal;
                observe(newVal)
            }
        }
    })
}

/**
 * 对一个对象所有属性的变动侦测
 */
function observe(target) {
    //非对象,间接返回
    if (typeof target !== 'object') {
        return target;
    }
    //将每个属性转换为getter和setter模式
    for (let key in target) {
        defineReactive(target, key, target[key])
    }
}
//模仿更新视图的办法
function updateView() {
    console.log("更新视图");
}

通过间接调用observe侦测对象属性的变动

存在的问题

  1. 性能较差
  2. 对象上新增属性无奈侦测
  3. 扭转数组的length属性无奈被侦测

2 Vue3双向绑定实现

Proxy是一种能够拦挡并扭转底层Javascript引擎操作的包装器,性能更优异
数组能够像对象一样触发get与set
【js】代理与反射(Proxy/Reflect)
【阮一峰】ES6规范-Proxy

原理简析,不做依赖收集

根本流程

cosnt o = {name:"张三"}
const proxy = new Proxy(o,{
    get(target,key,receiver){
        console.log("读取属性值")
    },
    set(target,key,value,receiver){
        console.log("设置属性值")
    },
    deleteProperty(target,key){
        console.log("删除属性")
    }
})
proxy.name; //读取属性值
proxy.name = "李四";//设置属性值
delete proxy[name] ;//删除属性

自定义的业务逻辑

//判断是否是对象
function isObj(val) {
    return val !== null && typeof val === "object"
}
//判断以后对象是否有指定属性
function hasOwn(target, key) {
    return target.hasOwnProperty(key)
}

//存储代理信息
const toProxy = new WeakMap()
const toRaw = new WeakMap()

/**
 *创立响应式对象
 */
function createReactiveObj(target) {
    //指标不是对象,间接返回target
    if (!isObj(target)) {
        return target
    }

    const proxy = toProxy.get(target)
    //如果指标对象已被代理,间接返回代理对象
    if (proxy) {
        return proxy
    }
    //如果指标对象是代理对象,并有对应的真的对象,间接返回
    if (toRaw.has(target)) {
        return target
    }

    //生成代理对象
    const observed = new Proxy(target, {
        get(target, key, receiver) {
            console.log("读取值");
            const result = Reflect.get(target, key, receiver)
            //为返回值增加代理
            return isObj(result) ? reactive(result) : result
        },
        set(target, key, value, receiver) {
            //判断指标对象是否曾经存在该属性
            const hasProperty = hasOwn(target, key)
            const oldVal = Reflect.get(target, key)
            if (!hasProperty) {
                console.log("新增属性");
            } else if (oldVal !== value) {
                console.log("批改属性");
            }
            return Reflect.set(target, key, value, receiver)
        },
        deleteProperty(target, key) {
            console.log("删除值");
            return Reflect.deleteProperty(target, key)
        }
    })
    //增加指标对象与代理对象到Map
    toProxy.set(target, observed)
    toRaw.set(observed, target)
    return observed
}
//响应式入口
function reactive(target) {
    return createReactiveObj(target)
}

与根本流程相比,自定义实现的性能

  • 解决多层对象侦测的问题,

    get中判断

  • 屡次代理

    用WeakMap存储代理信息,判断是否曾经被代理,或者自身是代理对象

  • 数组push产生两次get,一次属性一次length

    新旧值比照,在push元素后length曾经扭转,第二次的get不对length做任何批改,防止了增加一个值,视图更新两次

Proxy的handler中还能够写很多办法,以满足简单的业务


推荐阅读
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 本文提供了成为成功软件工程师的7条建议,包括不要低估自己、公司需要你、投资自己等。通过学习新技术、提升编码技能,软件工程师可以获得更好的职业机会和更高的薪水,同时也增强自信。投资自己是取得成功的关键。 ... [详细]
  • 本文介绍了获取关联数组键的列表的方法,即使用Object.keys()函数。同时还提到了该方法在不同浏览器的支持情况,并附上了一个代码片段供读者参考。 ... [详细]
author-avatar
蚁走天涯路
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有