MVVM相关概念


Mvvm 前端数据流框架精讲

1) MVVM典型特点是有四个概念:Model、View、ViewModel、绑定器。MVVM可以是单向绑定也可以是双向绑定甚至是不绑定
2) 绑定器:声明性的数据和命令,存在于ViewModel之中,让ViewModel和Model二者进行自动或手动通信,接下来的“MVVM在React中对应关系”小节有举例说明。
3) MVVM本质上是M- V-C-VM,它是在MVC的基础上增加了一层VM,只不过C变弱了,被并入到M概念中,VM用于分离V和M,并且让用户避免由于直接操作V层的DOM而带来的繁琐和效率低下,MVVM使开发更高效,结构更清晰,增加代码的复用性。
4) 在不同的GUI(图形用户界面)上进行展示时,Model、Controller、View-Model能够复用,只需把View层进行替换。
5) 在不同类型的UI(用户界面)上进行展示时,Model、Controller能够复用,只需把View-Model、View层进行替换。比如:假设我们开发的是一款针对盲人的应用,那么输出设备或许我们需要考虑使用扬声器来代替显示器,输入设备使用麦克风,这时我们只需将上述的View-Model替换为Audio-Model作为语音模型,将 V(iew)层替换为Audio层用于播放语音和接收语音输入。
6) 个人认为:在基于MVVM框架的项目中,不管是双向数据绑定还是单向数据绑定,你在开发中实际要面对的都是ViewModel和M(odel)层之前的通信,因为V(iew) 和ViewModel层之间的映射和通信都是由框架自动完成的,

MVVM四层结构


1) M(odel)层:模型,定义数据结构。
2) C(ontroller)层:实现业务逻辑,数据的增删改查。在MVVM模式中一般把C层算在M层中,(只有在理想的双向绑定模式下,Controller 才会完全的消失。这种理想状态一般不存在)
3) ViewModel层:顾名思义是视图View的模型、映射和显示逻辑(如if for等,非业务逻辑),另外绑定器也在此层。ViewModel是基于视图开发的一套模型,如果你的应用是给盲人用的,那么也可以开发一套基于Audio的模型AudioModel。
4) V(iew)层:将ViewModel通过特定的GUI展示出来,并在GUI控件上绑定视图交互事件,V(iew)一般由MVVM框架自动生成在浏览器中。

MVVM在React中对应关系


1) M(odel):对应组件的方法或生命周期函数中实现的业务逻辑和this.state中保存的本地数据,如果React集成了redux +react-redux,那么组件中的业务逻辑和本地数据可以完全被解耦出来单独存放当做M层,如业务逻辑放在Reducer和Action中。
2) V(iew)-M(odel):对应组件中的JSX,它实质上是Virtual DOM的语法糖。React负责维护 Virtual DOM以及对其进行diff运算,而React-dom 会把Virtual DOM渲染成浏览器中的真实DOM
3) View:对应框架在浏览器中基于虚拟DOM生成的真实DOM(并不需要我们自己书写)以及我们书写的CSS
4)绑定器:对应JSX中的命令以及绑定的数据,如className={ this.props.xxx }、{this.props.xxx}等等

MVVM的双绑和单绑区别


1) 一般,只有UI表单控件才存在双向数据绑定,非UI表单控件只有单向数据绑定。
2) 单向数据绑定是指:M的变化可以自动更新到ViewModel,但ViewModel的变化需要手动更新到M(通过给表单控件设置事件监听)
3) 双向数据绑定是指念:M的变化可以自动更新到ViewModel,ViewModel的变化也可以自动更新到M
4) 双向绑定 = 单向绑定 + UI事件监听。双向和单向只不过是框架封装程度上的差异,本质上两者是可以相互转换的。
5) 优缺点:在表单交互较多的情况下,单向数据绑定的优点是数据更易于跟踪管理和维护,缺点是代码量较多比较啰嗦,双向数据绑定的优缺点和单向绑定正好相反。

三大框架的异同


1) 三大框架都是数据驱动型的框架
2) vue及angular是双向数据绑定;react是单向数据绑定。React貌似使用的也是Object.defineProperty监控数据,只是没有进一步把表单控件的事件封装进v-model
3) Vuex、Redux都是单项数据绑定的,即M的变化可以自动更新到V,但V的变化必须手动触发事件更新到M,这种单项数据绑定使数据更易于跟踪管理和维护。
4) 未完待续……

Vue双向绑定原理


1) Vue的双向数据绑定是通过Object.defineProperty的get/set对M层数据进行监控,当数据发生变化时,自动更新VM层绑定的数据,而当用户更改了VM层表单控件的数据时,通过v-model自动更新到M层(v-model是对表单控件的事件的封装)
精简示例:

<div id="demo"></div>
<input type="text" id="inp">
<script>
var obj = {}
var demo = document.querySelector('#demo')
var inp = document.querySelector('#inp')
Object.defineProperty(obj, 'name', { // 看起来数据name只是作为数据中转的作用,真正要更新到view层的数据操作在set方法里。
get: function() {
return 0
},
set: function (newVal) {
inp.value = newVal
demo.innerHTML = newVal
}
})
inp.addEventListener('input', function(e) {
obj.name = e.target.value // 给obj的name属性赋值,进而触发该属性的set方法,
})
obj.name = 'fei'// 在给obj设置name属性的时候,触发了set这个方法
</script>

2)我们已经知道Vue是双向数据绑定(通过v-model),Vuex是单向数据绑定,那么问题来了,在基于Vue+ Vuex的项目中,Vuex中的数据是不允许Vue的v-model对其进行更改的,会报错,有如下三种解决方案:

  • 依然使用v-model,数据不放进Vuex中,而是放在组件自身的data属性中
  • 依然使用v-model,不过取值不再是Vuex中的数据,而是组件自身的一个computed(getter/setter)或watch,通过computed或watch里的回调来把数据变化提交(commit)到Vuex
    组件模板:

    <template>
    <div>
    <input type="text" v-model="newName"/>
    <p>{{newName}}</p>
    </div>
    </template>

    组件VUE实例:

    computed: {
    newName: {
    get () {
    return this.$store.state.name
    },
    set (val) {
    this.$store.commit('changeName', val) //当newName 值发生改变时,提交一个mutation:changeName,用于改变store中的name/
    }
    }
    }

    mutation:

     changeName (state, val) {
    state.name = val
    }
  • 不使用v-model,通过UI事件监听触发一个回调,然后手动把数据变化提交(commit)到Vuex

3)Vue的双向数据绑定和Vue的prop的单项数据流是两个不同的概念,数据绑定的前提是有数据流,但有数据流不一定有数据绑定。prop的单项数据流是指:prop可以把父组件的数据传递给子组件并且子组件不能对该数据进行直接修改更不能回流到父组件(当然,得益于Vue对所有数据使用了Object.defineProperty,所以prop传递的数据是绑定的,即父组件中该数据一旦发生变化,子组件中的也跟着变化)

前端MVVM模式及其在Vue和React中的体现的更多相关文章

  1. 在vue或者react中使用express框架

    在react 或者 vue项目中使用express框架 1.创建vue或者 react 项目 2.在项目中创建server文件夹,创建server.js //require()方法引入express模 ...

  2. vue、react中循环遍历为什么会有key,key有什么作用?

    先讲一下,vue和react都是在操作虚拟dom,并且根据diff算法进行新旧dom对比,从而更新dom,以vue举例: vue官方文档中写到有 key 的特殊属性主要用在 Vue 的虚拟 DOM 算 ...

  3. 前端必读2.0:如何在React 中使用SpreadJS导入和导出 Excel 文件

    最近我们公司接到一个客户的需求,要求为正在开发的项目加个功能.项目的前端使用的是React,客户想添加具备Excel 导入/导出功能的电子表格模块. 经过几个小时的原型构建后,技术团队确认所有客户需求 ...

  4. 代理模式及其在spring与struts2中的体现

    代理模式 代理模式有三个角色组成: 1.抽象主题角色:声明了真实主题和代理主题的共同接口. 2.代理主题角色:内部包含对真实主题的引用,并且提供和真实主题角色相同的接口. 3.真实主题角色:定义真实的 ...

  5. 从DOM操作看Vue&React的前端组件化,顺带补齐React的demo

    前言 接上文:谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo 上次写完博客后,有朋友反应第一内容有点深,看着迷迷糊糊:第二是感觉没什么使用场景,太过业务化,还不如直接写Vue ...

  6. angular中的MVVM模式

    在开始介绍angular原理之前,我们有必要先了解下mvvm模式在angular中运用.虽然在angular社区一直将angular统称为前端MVC框架,同时angular团队也称它为MVW(What ...

  7. Vue与React的异同

    众所周知,前端现在最火的两个框架是Vue和React了.通过一段时间的学习与项目上的实践,我想通过比较他们之间的异同点来发现以后在项目的技术选型中知道怎么抉择用哪个.有一点说明的是他们各自有自己的优势 ...

  8. Vue vs React: Javascript 框架之战

    https://baijiahao.baidu.com/s?id=1608210396818353443&wfr=spider&for=pc    原文档 正如我们之前提到的,Word ...

  9. Vue与REACT两个框架的区别和优势对比

    VUE和REACT两个JavaScript框架都是当下比较受欢迎的,他们两者之间的区别有那些,各自的优缺点是什么,本文将为你呈现. 简单介绍 除非你最近一直不关注前端的发展,不然你肯定听说过由Face ...

随机推荐

  1. easyui---datalist相关知识

    datalist 笔记: class:class="easyui-datalist" //对应标准元素:ul 表格线:lines="true" 远程数据绑定: ...

  2. POJ3178 计算几何+DP

    //一些点一些圆,过圆不能连线,相邻点不能连线,问最多连几条线 //计算几何模板+区间dp //关键是判断圆和线段是否相交 #include <cstdio> #include <c ...

  3. 得到web.xml中servletContext的context-param

    import org.springframework.web.context.ContextLoader; // web.xml文件中已经启用数据权限 String enableDataSecurit ...

  4. .net core实现的全程序跟踪

    Ocelot中使用Butterfly实践 ocelot   Ocelot + Consul实践   Ocelot中使用Butterfly实践   Ocelot监控     Ocelot统一权限验证   ...

  5. 关于Nginx对于PHP支持的问题

    因为使用的mediawiki是用php写的,所以就遇上了一个问题,怎么让Nginx支持php,记得当时使用apache2的时候是安装了一个叫 “ libapache2-mod-php5 ”的mod , ...

  6. (转)nginx应用总结(1)--基础认识和应用参数优化配置

    在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结. 一.nginx服务简介Nginx是一个高性能的HTTP和反向代理服务 ...

  7. 再谈WPF

    前几天初步看了一下WPF,按照网上说的一些方法,实现了WPF所谓的效果.但,今天我按照自己的思路设计了一个登陆界面,然后进行登陆验证,对WPF算是有进一步的理解,记录下来,以备后期查看. 首先,在WP ...

  8. sqlserver 数据库 的数据库个数统计 表个数统计 表的数据量统计(转载)

    http://www.cnblogs.com/qinche/archive/2012/08/09/app.html 由于今天要监控数据,急需统计实例中1有多少库2库里有多少表3每个表有多少数据 --将 ...

  9. AnyCAD OpenSource 版本下载和编译

    下载: SVN下载地址:https://anycad.svn.codeplex.com/svn 或者直接下载:http://anycad.codeplex.com/SourceControl/late ...

  10. JAVA基础之基本类型包装类、System类、Math类、Arrays类及大数据运算

    个人理解: 为了方便运算及调用一些方法,我们需要将基本类型的数值转换为对象:不过转换的时候需要特别注意好它们的类型到底是什么,需要调用方法的类名是哪个!特别注意是Byte常量池的相关问题(==):gc ...