vue进阶6-diff算法
数据发生变化时,vue是怎么更新节点的我们先根据真实DOM生成一颗virtual DOM,当virtual DOM某个节点的数据改变后会生成一个新的Vnode,然后Vnode和oldVnode作对比,发现有不一样的地方就直接修改在真实的DOM上,然后使oldVnode的值为Vnode。diff的过程就是调用名为patch的函数,比较新旧节点,一边比较一边给真实的DOM打补丁。
分析Vue中 diff算法与虚拟dom
vue中diff核心策略平级比较,不考虑跨级比较节点的情况,内部采用深度优先递归 + 双指针(两端对比)策略进行比较Vue2的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作,展开来说
(观察主流的虚拟 DOM 库(snabbdom、virtual-dom),通常都有一个 h 函数,也就是 React 中的 React.createElement,以及 Vue 中的 render 方法中的 createElement,另外 React 是通过 babel 将 jsx 转换为 h 函数渲染的形式 ...
vue进阶5-virtual Dom
virtual Dom 是什么虚拟 DOM 其实就是js对象,通过对象的方式表示真实的 DOM 结构,将页面的状态抽象成js对象的形式
为什么需要虚拟dom频繁的操作 DOM 会使得网站的性能下降,为了保证性能,我们需要使得 DOM 的操作尽量精简,我们可以通过操作虚拟 DOM 的方法,去比较新旧节点的差异然后精确的获取最小的,最为必要的 DOM 集合,最终挂载到真实的 DOM 上。因为操作数据结构,远比我们直接修改 DOM 节点来的快,我们真实的 DOM 操作在最好的情况下,其实只需要在最后来那么一下,他们喊是patch补丁一下
保证各框架性能下限,在不进行手动优化的情况下,提供系统过得去的性能
跨平台,例如服务端渲染(这个能力的根本,是 Javascript 代码能低代价地在各个平台运行(得利于浏览器在各个平台的普及和 NodeJS),也就是常说的 Javascript 的优势之一是跨平台)
虚拟dom优缺点
优点是其抽象能力和常驻内存的特性,让vue/react框架能更容易实现更强大的 diff 算法(由于 Virtual DOM 的存在,diff 算法可以更方便且更强大)
...
vue进阶4-watch和computed
Dep.target什么时候存在Dep.target是由依赖赋值的。依赖又称为Watcher(侦听者)或者订阅者。在Vue中有三种依赖,其中两种是很常见的,就是watch(侦听器)和computed(计算属性)。还有一种隐藏的依赖———渲染Watcher,在模板首次渲染的过程中创建的。Dep.target是在依赖创建时被赋值,依赖是用构造函数Watcher创建。
123456789101112131415161718192021222324function Watcher(vm, expOrFn, cb, options, isRenderWatcher) { //... if (typeof expOrFn === 'function') { this.getter = expOrFn; } else { this.getter = parsePath(expOrFn); } this.value = this.lazy ? undefined : this.get(); ...
vue进阶3-数据绑定
defineProperty和proxy区别
谈谈对vue响应式原理的理解(Vue双向绑定如何实现的)1.数据劫持2.发布订阅
vue中的依赖收集是怎么处理的
vue如何检测数组变化(重写数组方法)
为何采用异步渲染(Vue中的数据多次变化但只会更新一次)
nextTick实现原理
v-model实现原理
defineProperty和proxy区别Vue3.x改用Proxy替代Object.defineProperty。因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。Proxy只会代理对象的第一层,Vue3是怎样处理这个问题的呢?判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。
Proxy 与 Object.definePro ...
vue进阶2-lifecycle生命周期
vue的初始化流程(vue2.x运行机制)Vue 2.x 的运行机制
vue组件的生命周期
描述组件渲染和更新过程
vue模板编译原理
vue运行机制初始化流程
创建vue实例
initMixin(Vue) 初始化生命周期,初始化事件中心、初始化渲染,执行beforeCreate钩子函数,初始化props/methods/data/computed/watch,执行created函数
初始化之后,调用vm.$mount(vm.$options.el)方法对实例进行挂载(挂载核心包括模板编译,渲染以及 更新三个过程)
如果没有在Vue实例上定义render方法而是定义了template,那么需要经历编译阶段。需要先将template 字符串通过 compileToFunctions函数 编译成 render function,template 字符串编译步骤如下:
parse正则解析template字符串形成AST描述符(抽象语法树,是源代码的抽象语法结构的树状表现形式)
optimize标记静态节点(跳过diff算法, vue Diff算法是逐层进行比对,只有同层级的节点 ...
vue进阶1-mvvm
介绍mvvm和mvcMVVM 是 Model-View-ViewModel 的缩写
Model: 代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。我们可以把Model称为数据层,因为它仅仅关注数据本身,不关心任何行为.
View: 用户操作界面(UI组件)。当ViewModel对Model进行更新的时候,会通过数据绑定更新到View
ViewModel:业务逻辑层,View需要什么数据,ViewModel要提供这个数据;View有某些操作,ViewModel就要响应这些操作,所以可以说它是Model for View. ViewModel把Model和View关联起来
MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
总结:MVVM模式简化了界面与业务的依赖,解决 ...
前端进阶-vue全面瓦解-2
尽力而为吧,作为每天都在用的工具,只是希望自己能了解的足够深一点,把用到的知识学好学精学神就好,对自己要求不高,尽力而为!!!
mvvm
mvvm,介绍一下mwvm,和mvc的区别,viewModel有什么好处
实现一个简易的mvvm框架
生命周期
vue的初始化流程(vue2.x运行机制)Vue 2.x 的运行机制
vue组件的生命周期
描述组件渲染和更新过程
vue模板编译原理
数据绑定
defineProperty和proxy区别
谈谈对vue响应式原理的理解(Vue双向绑定如何实现的)1.数据劫持2.发布订阅
vue中的依赖收集是怎么处理的
vue如何检测数组变化(重写数组方法)
为何采用异步渲染(Vue中的数据多次变化但只会更新一次)
nextTick实现原理
v-model实现原理
watch和computed
computed如何实现
watch如何实现
computed的时候阔以引用其他computed属性是如何实现的
Virtual Dom
virtual Dom 是什么
为什么需要虚拟dom
vue的虚拟dom
vue对Dom更新做了哪些标记优化处理
Di ...
前端基础: 设计模式
设计模式从架构层面考虑设计,从上往下看,而不是只顾往下看设计模式的定义:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。设计模式就是一种理念,通过一些设计思维来解决平时编写底层或业务代码时遇到的场景问题。比如早期业务中的一个封装类,同时带有一些封装方法。如果现在该类不能再满足全部业务场景,且不允许修改原方法,此时就需要装饰器或适配器模式来解决;又比如当设计一个场景,在调用一个固定对象时一定要先执行某些方法,比如验证登录、验证身份ID等场景,此时就应该用到代理模式。
介绍一下单一职责原则和开放封闭原则单一职责原则: 一个类只负责一个功能领域中的相应职责开放封闭原则: 软件实体(类、模块函数)是可扩展的但不可修改的
装饰者模式 Decorator特征在原来方法的基础上装饰一些针对特殊场景所适用的方法,即添加一些新功能,主要特征
为对象添加新功能
不改变原有的结构和功能,即原本的功能得继续用
实现 one1234567891011121314151617181920212223 class Circle { draw() { consol ...
前端基础:js原型链与继承(六种常见的继承)
继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实现继承则继承实际的方法.由于js中方法没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支持实现继承,而且其 实现继承 主要是依靠原型链来实现的.
概念简单回顾下构造函数,原型和实例的关系:每个构造函数(constructor)都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针(constructor),而实例(instance)都包含一个指向原型对象的内部指针(proto)
proto是隐式原型,prototype是显式原型
每个对象都有一个隐式原型,指向该对象的原型。实例化后通过proto属性指向构造函数的显式原型prototype,原型链是由各个原型对象组成,每个对象都有proto属性,指向创建该对象的构造函数的原型,通过隐式原型proto属性将对象链起来,组成原型链,用来实现属性方法继承和共享
继承原型链继承123456789101112131415function Parent() ...
前端基础-handWritng-series-updating
js基础手写const回到var和let/const的区别上:
var声明的变量会挂到window上,而let和const不会var声明的变量存在变量提升,而let和const不会let和const声明形成块作用域,只能在块作用域里访问,不能跨块访问,也不能跨函数访问同一作用域下let和const不能声明同名变量,而var可以暂时性死区,let和const声明的变量不能在声明前被使用
实现const的关键在于Object.defineProperty()这个API,这个API用于在一个对象上增加或修改属性。通过配置属性描述符,可以精确地控制属性行为。Object.defineProperty() 接收三个参数:Object.defineProperty(obj, key, desc)
123456789101112131415161718192021var __const = function __const (data, value) { window.data = value // 把要定义的data挂载到window下,并赋值value Object.define ...