理解vue原理以及实现流程

从 jquery 的操作 dom 到 vue,react等框架的vdom实现,大大减少了dom的操作,提高性能。前端的刀耕火种,到现在的模块化,前端的内容每天都在发生着变化,每天都有着进步。前端的发展中我们绕不过一个坎,那就是jquery,接下来我们会对比jquery和现在框架,来发现这些年前端取得的进步。

jquery与框架的区别:

jquery的本质还是操作dom,在处理dom的时候,也会导致数据和视图层的不分离,数据中有dom的操作。这是jquery淘汰的一个原因,因为他不符合基本的开闭原则(对修改关闭,对扩展开放)。

现在为我们熟知的框架,则是很好处理了这个问题。实现了数据和视图的分离,解耦了视图层和数据层,通过中间层来达到控制的目的,以数据驱动视图,只关心数据的变化,DOM的操作被封装。

理解MVVM:

提到MVVM不得不提他的老前辈MVC(Model + View + Controller)

MVC:原型+视图+控制器。用户通过操作视图。进而控制器去改变原型,进而改变视图显示。又或者用户直接操作控制器改变原型,进而改变视图层的显示。jquer就是基于此设计的

在MVC的基础上,前端创新的MVVM的VM(View Model),介于View层和Model层中间的VM层。他起着桥梁的作用。

视图层通过事件来绑定模型层(数据层),数据层通过数据绑定来改变视图层。VM就起着衔接的作用。我们就可以实现只关心数据的变化,不用去用控制器操作。

MVVM框架的三大要素:响应式,模板引擎,渲染

响应式:vue如何监听data的变化?

模板引擎:vue的模板如何被解析,指令如何变化

渲染:vue的模板如何被渲染成html?以及渲染过程

响应式:

这里的响应式是数据的响应式,数据的变化会被实时监听。而vue实现data数据实时监听的核心函数是Object.defineProperty

这是es5中对象上的方法,他能实现对对象属性get和set的监听。

//响应式数据的核心函数,监听数据改变
var vm = {};
var obj = {
  name: "xb",
  age: 18,
  // like
};
var key;
for (key in obj) {
  (function(key) {
    Object.defineProperty(vm, key, {
      get: function() {
        console.log("get", obj[key]); //监听
        return obj[key];
      },
      set: function(newVal) {
        console.log("set", newVal); //监听
        obj[key] = newVal
      }
    });
  })(key);
}

这里我们还可以提出一个问题,就是data中的数据如何挂载到Vue实例上去的,其实也就是这个方法。在Vue3.0版本以后,实现对数据的监听换成了新的方法,运用了es6的语法(这里不扩展)。

模板引擎:

模板是什么:在vue中,是字符串,他有逻辑,还嵌入了JS变量。本质其实就是字符串。逻辑对应的就是v-if,v-for等。他与html很像,但是区别很大,html是静态的,html中没有逻辑,没有JS变量。所以他可以按照浏览器指定好的规则去渲染,但是vue模板不能。他必须先解析。转化为html,才能渲染到页面。

这里提到的解析,应该就知道我们需要借用JS了,因为JS是前端中图灵完备的语言。(https://blog.csdn.net/robinsone/article/details/39004057

因此,模板最重要是转换成一个JS函数,在由JS转化成html(这里指的是render函数(泛指渲染函数))

render函数执行完会返回一个vnode(虚拟节点)

这里我们就要提到前面的vdom(虚拟dom)。

vdom:

提问;vdom是什么,为什么会存在。vdom如何应用,核心API是什么,

什么是vdom和为什么会存在:

用JS模拟dom结构,dom变化的对比放在JS层来做,存在的原因是提高重绘性能。

再次提出问题:为什么dom操作是‘昂贵’的。

我们创建一个dom元素。然后遍历这个dom元素,你会发现dom元素上有很多很多属性。

最主要的原因还是,每次操作dom,会调用cpu和gpu。页面的重排占用cpu的计算能力,页面的重绘占用了gup的图像处理能力。

这里还要说下gpu的分类。分为家用的和专业的。家用显卡也被称为游戏显卡。游戏显卡他擅长于做贴图,光影这些东西。专业显卡,擅长于画图,专业显卡的性能要比家用显卡好上几十倍。

我们每次页面的重排重绘都是相当于画图,而我们绝大部分的显卡都是家用显卡,所以在画图这方面性能并不好。

所以追寻到问题的本质,就是硬件的问题,导致操作dom显得那么‘昂贵’。

明白了操作dom为什么是‘昂贵’的,就明白了vdom为什么会存在。

vdom的应用:

介绍的是snabbdom

核心API:h函数和patch函数

h函数:定义一个dom节点——vnode(模拟dom节点)

patch函数:接收两个参数。初始的cantainer,和vnode

patch(container,vnode)//初次渲染
patch(vnode,newVnode) //再次渲染

patch函数就是一个对比函数,这里涉及到了diff算法。(不是新东西。早在git命令中就有,对比两个文本的差别)

vdom为何用diff算法:

dom的操作是‘昂贵’的,算法的目的找出本次dom必须更新的节点来更新,其他节点不更新。这个过程就叫diff算法。

render函数:

模板的所有信息都包含在render函数中

函数执行完返回一个vnode(模拟节点)

vue整个流程:四部曲

解析模板成render函数

  1. 内置用了with语法,使代码简洁
  2. 模板中所有的信息都被render函数包含
  3. 模板中用到的data的属性,都变成了JS变量
  4. 模板中的v-model,v-if等都变成了JS逻辑
  5. render函数返回一个vnode

响应式开始监听

  1. Object.defineProperty核心函数实现监听
  2. 将data属性代理到Vue实例上(跟with用法有很大关系)

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

  1. 初次渲染,执行updataComponent,执行vm.render(vm是Vue实例)
  2. 执行render函数,会访问到vm.list和vm.title
  3. 执行updataComponent,会走到vdom的pacth方法
  4. pacth将vnode渲染成DOM,初次渲染完成
  5. 会被响应式get方法监听到
  6. 为何要监听get,直接监听set不行吗?
  7. data中有很多属性,有些被用到,有些可能不被使用,被用到了会走get,不被用到不走get。没有走get的属性,set也没必要关心,这样就可以避免重复渲染了

data属性变化,触发rerender函数(二次渲染)

  1. 属性修改,被set监听到
  2. set中执行updataComponent(异步方法)
  3. updataComponent重新执行vm._render()
  4. 生成的vnode和prevVnode,通过patch进行对比
  5. 渲染到html中
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值