MVVM

如何理解MVVM?

MVVM是由MVC创新而来。
MVC(Model,View,Controller)

  • M - Model 数据
  • V - View 视图、界面
  • C - Controller 控制器、逻辑处理

MVVM(Model,View,ViewMOdel)

  • M - Model 模型、数据
  • V - View 视图、模板(视图和模型是分离的)
  • VM - ViewModel 连接器,连接Model和View
    在这里插入图片描述

MVVM框架实现的三大要素?

  • 响应式:vue如何监听到data的每个属性变化?
  • 模板引擎:vue的模板如何被解析,指令如何处理?
  • 渲染:vue的模板如何被渲染成html?以及渲染过程

vue中如何实现响应式?

  • 通过Object.defineProperty
  • 将data的属性代理到vm上
var obj = {}
var _name = 'zhangsan'
Object.defineProperty(obj, '_name', {
	get: function(){
		console.log('get', _name)   // 监听
		return _name
	},
	set: function(newValue){
		console.log('set', _name)   // 监听
		return _name = newValue
	}
})

模拟vue

var vm = {}
var data = {
	name: 'zhangsan',
	age: 20
}
var key, value
for(key in data){
	(function(){
		Object.defineProperty(vm, key, {
			get: function(){
				console.log('get', key)
				return data[key]
			},
			set: function(newValue){
				console.log('set', newValue)
				return data[key] = newValue
			}
		})
	})(key)	
}

vue中如何解析模板?

模板是什么?

  • 本质:字符串
  • 有逻辑,如v-if,v-for等,可以嵌入JS变量
  • 与html格式很像,但有很大区别(html是静态的,vue模板是动态的)
  • 最终还要转换为html来显示
  • 模板最终必须转换成JS代码,因为:
  • 有逻辑(v-if, v-for),必须用JS才能实现
  • 转换为html渲染页面,必须用JS才能实现
  • 因此,模板最重要转换成一个JS函数(render函数)

render函数

// 模板中
<div id="app">
	<p>{{price}}</p>
</div>	
var vm = new Vue({
	el: '#app',
	data: {
		price: 100
	}
})
// render函数中
witch(this){
	return _c(
		'div',
		{
			attrs: {"id": "app"}
		},
		[
			_c('p', [_v(_s(price))])
		]
	)
}
  • 模板中所有信息都包含在了render函数中
  • this即vm
  • price即this.price即vm.price,即data中的price
  • _c即this._c即vm._c

render函数与vdom

  • vm._c其实就相当于snabbdom中的h函数
  • render函数执行之后,返回的是vnode
  • updateComponent中实现了vdom的patch
  • 页面首次渲染执行updateComponent
  • data中每次修改属性,执行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._render即上面的render函数,返回vnode
	vm._update(vm._render())
}

vue的整个实现流程

(1)解析模板成render函数

  • with的用法
  • 模板中的所有信息都被render函数包含
  • 模板中用到的data中的属性,都变成了JS变量
  • 模板中的v-model,v-for,v-on都变成了JS逻辑
  • render函数返回vnode

(2)响应式开始监听

  • 通过Object.defineProperty监听到get,set
  • 将data的属性代理到vm上

(3)首次渲染,显示页面,且绑定依赖

  • 初次渲染,执行updateComponent,执行vm._render()
  • 执行render函数,会访问到vm.list和vm.title
  • 会被响应式的get方法监听到
  • 执行updateComponent,会走到vdom的patch 方法
  • patch将vnode渲染成DOM,初次渲染完成

为何要监听get,直接监听set不行吗?

  • data中有很多属性,有些被用到,有些可能不被用到
  • 被用到的会走到get,不会用到的不会走到get
  • 未走到get中的属性,set的时候我们也无需关心
  • 避免不必要的重复渲染

(4)data属性变化,触发rerender

  • 修改属性,被响应式的set监听到
  • set中执行updateComponent
  • updateComponent会重新执行vm._render()
  • 生成的vnode和prevVnode,通过patch进行对比
  • 渲染到html中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值