MVVM框架理解
MVC框架
将整个前端页面分成View,Controller,Modal,视图上发生变化,通过Controller(控件)将响应传入到Model(数据源),由数据源改变View上面的数据。
整个过程看起来是行云流水,业务逻辑放在Model当中,页面渲染逻辑放在View当中,但在实际运用上却存在一个问题:那就是MVC框架允许View和Model直接进行通信!!
换句话说,View和Model之间随着业务量的不断庞大,会出现蜘蛛网一样难以处理的依赖关系,完全背离了开发所应该遵循的“开放封闭原则”。
面对这个问题,MVVM框架就出现了,它与MVC框架的主要区别有两点:
1、实现数据与视图的分离
2、通过数据来驱动视图,开发者只需要关心数据变化,DOM操作被封装了。
可以看到MVVM分别指View,Model,View-Model,View通过View-Model的DOM Listeners将事件绑定到Model上,而Model则通过Data Bindings来管理View中的数据,View-Model从中起到一个连接桥的作用。
MVVM的实现原理:
MVVM的实现主要是三个核心点:
- 响应式:vue如何监听data的属性变化
- 模板解析:vue的模板是如何被解析的
- 渲染:vue模板是如何被渲染成HTML的
小白一枚,一直使用的是React,想要多了解一些其它的框架,正好最近Vue越来越火热,Github上的Star数已经超过了React。而其背后蕴含的MVVM框架思想也一直跟React的组件化开发思想并驾齐驱,在这里也是本着兼收并蓄的思想,多了解一种开发模式。因此通过一些学习资料,写一些自己对MVVM开发思想的理解。
废话不多说,咱们进入正题。
MVVM框架理解
说起这个MVVM模型,就不得不说MVC框架。
将整个前端页面分成View,Controller,Modal,视图上发生变化,通过Controller(控件)将响应传入到Model(数据源),由数据源改变View上面的数据。
整个过程看起来是行云流水,业务逻辑放在Model当中,页面渲染逻辑放在View当中,但在实际运用上却存在一个问题:那就是MVC框架允许View和Model直接进行通信!!
换句话说,View和Model之间随着业务量的不断庞大,会出现蜘蛛网一样难以处理的依赖关系,完全背离了开发所应该遵循的“开放封闭原则”。
面对这个问题,MVVM框架就出现了,它与MVC框架的主要区别有两点:
1、实现数据与视图的分离
2、通过数据来驱动视图,开发者只需要关心数据变化,DOM操作被封装了。
可以看到MVVM分别指View,Model,View-Model,View通过View-Model的DOM Listeners将事件绑定到Model上,而Model则通过Data Bindings来管理View中的数据,View-Model从中起到一个连接桥的作用。
MVVM的实现原理:
MVVM的实现主要是三个核心点:
- 响应式:vue如何监听data的属性变化
- 模板解析:vue的模板是如何被解析的
- 渲染:vue模板是如何被渲染成HTML的
响应式:
var obj = {
name: 'zhangsan',
age: 25
}
当我们访问或修改obj的属性的时候,比如:
console.log(obj.name) //访问
obj.age = 22 //修改
但是这样的操作vue本身是没有办法感知到的,那么应该如何让vue知道我们进行了访问或是修改的操作呢?
那就要使用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)
}
通过Object.defineProperty将data里的每一个属性的访问与修改都变成了一个函数,在函数get和set中我们即可监听到data的属性发生了改变。
模板解析:
首先模板是什么?
模板本质上是一串字符串,它看起来和html的格式很相像,实际上有很大的区别,因为模板本身还带有逻辑运算,比如v-if,v-for等等,但它最后还是要转换为html来显示。
<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>
模板在vue中必须转换为JS代码,原因在于:在前端环境下,只有JS才是一个图灵完备语言,才能实现逻辑运算,以及渲染为html页面。
这里就引出了vue中一个特别重要的函数——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()
with将obj这个对象放在了自己函数的作用域链的顶部,当执行下列函数时,就会自动到obj这个对象去寻找同名的属性。
而在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>
with将obj这个对象放在了自己函数的作用域链的顶部,当执行下列函数时,就会自动到obj这个对象去寻找同名的属性。
而在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))])})
)
]
)
]
)
}
如何将模板渲染为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算法完成新旧对比并修改。
转载:https://segmentfault.com/a/1190000015895017?utm_source=tag-newest
MVVM框架理解的更多相关文章
- Vue的MVVM框架理解
图示 只上图,请不要怪楼主懒. 这是楼主梳理后画的,因为毕竟自己画的印象深刻,更觉得香啊. 黄线: 表示View->Model, 红线: 表示Model->View 具体代码,请查看Vue ...
- “老坛泡新菜”:SOD MVVM框架,让WinForms焕发新春
火热的MVVM框架 最近几年最热门的技术之一就是前端技术了,各种前端框架,前端标准和前端设计风格层出不穷,而在众多前端框架中具有MVC,MVVM功能的框架成为耀眼新星,比如GitHub关注度很高的Vu ...
- 不要听吹牛逼什么前端MVVM框架就是好,其实都是一帮没学好分层设计的搞出来的,让你彻底看清前端MVVM的本质
最近前端圈子里面,发现大家都在热炒概念,什么knockout,angularJs,都被捧成神了,鄙人不才,最近心情也不好,特地写这篇文章来找骂 写代码的码农都知道,Java社区虽然不是一个提出分层思想 ...
- 前端MVVM框架设计及实现
最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了 借鉴的自然还是从正美的Avalon开始了,我2013年写过一个关于MVC MV ...
- 轻量级前端MVVM框架avalon - 初步接触
迷你简单易用的MVVM框架 avalon的介绍http://rubylouvre.github.io/mvvm/ 按照作者的介绍,在HTML中添加绑定,在JS中用avalon.define定义View ...
- 使用MVVM框架(avalonJS)进行快速开发
背景 在运营活动开发中,因为工作的重复性很大,同时往往开发时间短,某些情况下也会非常紧急,导致了活动开发时间被大大压缩,同时有些活动逻辑复杂,数据或者状态变更都需要手动渲染,容易出错,正是因为这些问题 ...
- MVVM框架思想
1.MVVM是什么? M:模型 V:视图 VM:视图模型 简单理解:mvc是一个cell面向一个model开发 mvvm是一个cell面向一个viewModel开发, viewModel里面又包含mo ...
- MVVM 框架解析之双向绑定
更好的阅读体验,点击 原文地址 MVVM 框架 近年来前端一个明显的开发趋势就是架构从传统的 MVC 模式向 MVVM 模式迁移.在传统的 MVC 下,当前前端和后端发生数据交互后会刷新整个页面,从而 ...
- 【学习笔记】剖析MVVM框架,简单实现Vue数据双向绑定
前言: 学习前端也有半年多了,个人的学习欲望还比较强烈,很喜欢那种新知识在自己的演练下一点点实现的过程.最近一直在学vue框架,像网上大佬说的,入门容易深究难.不管是跟着开发文档学还是视频教程,按步骤 ...
随机推荐
- jdbc连接数据库(oracle、mysql)
很简单,直接贴代码吧!代码注释自认为足够理解! 第一步创建数据库连接类,数据库连接地址.数据库驱动.用户名.密码建议创建为公共变量,方便修改,一目了然. package db; import java ...
- 如何创建一个Maven项目(eclipse版本)
1 Maven概念 Maven是一个构建项目和管理项目依赖的工具 2 Maven运行原理 这里需要引入两个词汇,叫 本地仓库.中央仓库 本地仓库:就字面意思,存储在自己电脑上的文件夹(需要自己手动创建 ...
- 后端程序员之路 25、Redis Cluster
官方教程和功能介绍: REDIS cluster-tutorial -- Redis中文资料站 -- Redis中国用户组(CRUG)http://www.redis.cn/topics/cluste ...
- 五十:代码审计-PHP无框架项目SQL注入挖掘技巧
代码审计教学计划: 审计项目漏洞Demo->审计思路->完整源码框架->验证并利用漏洞 代码审计教学内容: PHP,JAVA网站应用,引入框架类开发源码,相关审计工具及插件使用 代码 ...
- Java 读取Word文本框中的文本/图片/表格
Word可插入文本框,文本框中可嵌入文本.图片.表格等内容.对文档中的已有文本框,也可以读取其中的内容.本文以Java程序代码来展示如何读取文本框,包括读取文本框中的文本.图片以及表格等. [程序环境 ...
- 【Arduino学习笔记02】第一个Arduino项目——点亮LED Blink.ino程序解读 Arduino程序基本结构 pinMode() digitalWrite() delay()
/* Blink Turns an LED on for one second, then off for one second, repeatedly. */// define variables ...
- Java8 BiFunction 简单用用
最近来了新公司,主要用到了ElasitcSearch,大家都知道在底层查询代码中往往需要判断传入某个参数是否为空来判断设置查询,例如下方代码: BoolQueryBuilder query = Que ...
- 2019 GDUT Rating Contest II : Problem F. Teleportation
题面: Problem F. Teleportation Input file: standard input Output file: standard output Time limit: 15 se ...
- python并发利器tomorrow
tomorrow是我最近在用的一个爬虫利器,该模块属于第三方的模块,使用起来非常的方便,只需要用其中的threads方法作为装饰器去修饰一个普通的函数,既可以达到并发的效果,本篇将用实例来展示tomo ...
- python之routes入门
一.入门 from routes import Mapper map = Mapper() # 创建一个mapper()路由实例对象 # connect注册路由信息 # 路由名称'zbj', 路径是 ...