vue的响应式原理
首先vue会通过object.defineprodefineProperty为data中的每个对象以及属性重写get和set,并未每个属性新增一个dep收集类,然后在进行render渲染的时候,使用哪些变量就会触发响应的get函数,然后当前实例的watcher就会收集当前使用了的属性的dep,dep也会收集触发了自己的watcher放到一个队列中,当某个变量更新的时候,重新notify通知当前dep依赖的多个watcher进行update更新视图,更新完视图后清空dep和watcher的依赖,然后重新收集dep和watcher依赖进行下一次的视图更新准备。
发布-订阅模式
首先vue会把用户的template通过completoFunction转换成AST语法树,然后把AST语法树转成虚拟DOM并返回一个render方法,再对数据进行observe数据劫持,通过Object.defineprodefineProperty为每个属性进行get和set的重写,并未每个属性创建一个dep依赖收集类,当第一次调用render的时候,模板中使用了的变量的get就会触发收集依赖,watcher会收集一个deps列表,dep也会收集一个调用自己的watcher列表,当变量发生改变时,就会通过当前变量的收集的watcher重新执行自己的update重新渲染,重新渲染完毕后,会清空dep和watcher依赖,并根据当前渲染重新进行dep和watcher的依赖收集下次使用。
使用Object.defineprodefineProperty进行数据劫持的优缺点
无法监听到对象的属性新增和删除的变化,无法监听到数组的下标修改、新增删除、修改自身方法的修改,
MVVM
modal view viewModal
数据层、视图层,视图根据数据的改变而改变
好处:用户的重点只需要处理数据的变化,不需要个人操作视图层的变化,
computed和watch
底层都是使用的watcher类来进行数据监听的,
computed但是是进行懒加载,当依赖的数据不发生变化的时候不会执行
computed只能同步操作,立即返回异步操作
watch
不支持缓存,数据变化,就会触发响应的操作
可以进行异步操作,因为不需要立即返回一个值
可以监听到更新前后的值
有两个属性一个deep,一个immediate,深度遍历和立即执行,immediate会在进行watcher绑定的时候立马执行,所以他的执行顺序会在created之前
slot是vue的内容分发的,用来进行父子组件传递内容使用,分为三个
默认插槽、具名插槽、作用域插槽,
默认插槽就是name默认为default
具名插槽:具有独立的name名称,进行内容分发
作用域插槽:可以通过标签属性,进行两边的字段传参
vm上面有个实例叫vm.$slot,可以看到当前组件使用了哪些slot进行针对性显示
localstorage,
sessionStorage
cookie
第三个只有4k的代码,请求接口的时候cookie会放到请求头一起携带到后端,所以一般都是放一些用户信息,进行鉴权使用
lo:5M,长期有效
sess:当次打开浏览器存在
路由的query和params进行传值,也能进行信息的临时缓存
stop,.once,.prevent,.captrue
v-if和v-show的区别
v-if是通过completeToFunction进行编译的时候就会进行渲染判断,当条件满足渲染当前实例,而v-show的话是个指令,当你show依赖的变量变化,他会把之前的display缓存起来,当你重新为true的时候显示,只是css样式层的显示和渲染
v-html的话则是直接替换当前全部的子元素
v-model只是vue帮忙实现的一个语法糖,通过v-model绑定变量,其实就是传递了一个value值和一个input事件,当你修改值得时候触发emit进行值的变动,就实现了双向数据绑定
keep-alive有三个参数,include和exclude,max,分别表示缓存哪些组件,哪些组件黑名单,以及最大缓存数,他实现的原理是缓存你当前组件的vnode
$nexttick的原理
将nexttick中的cb回调函数缓存起来,当同步任务跑完了之后统一进行cb的调用,会优先判断你当前环境是否有promise微任务,然后是immed,process.next、然后才是宏任务settimeout,再统一调用cb回调函数
当你什么都不传的时候,他则是会返回一个promise成功,让你进行链式调用
$set的原理
会判断你当前是进行数组还是对象,如果是数组的添加修改删除的话,直接调用重写后的splice方法进行响应式数据更新,如果是对象的话,则是修改之后重新通过observer进行全部数据的依次数据更新。、
vue重写了会改变自身方法的函数,修改了proto的指向先指向自己重写后的方法, 然后再执行原来数组的prototype
七个重写数组的方法
push,pop,shift,unshift,splice,sort,reverse
template到render
先获取到el指向元素的template模板,然后通过compileToFunction进行正则匹配转换成了AST语法树,然后再把AST语法树转成成了一个虚拟DOM,最后是根据这个虚拟DOM生成一个render渲染函数,当调用渲染函数的时候会返回一个当前数据的最新的虚拟DOM,然后进行path DIFF算法比较,进行头尾交叉 比较key和tag标签,达到相同虚拟DOM复用,节约性能,
使用with修改字符串模板的变量使用指向data
不会,会把要更新的通过内容的nexttick放到异步队列,然后同步全部跑完后一次性更新
mixin和extends
先进行Analyzer进行性能分析,观察哪些文件比较大加载比较慢
然后去除生产环境时的sourcemap源码,进行组件内别名设置,减少整个项目中路径过长比较多的情况,去掉一些默认预加载,但是首屏加载时用不到的东西,然后使用minimizer进行js,css,html的代码压缩,使用cssAssets插件进行冗余css过滤,然后对大文件进行splitChunks分包,权重多线程加载,抽离大文件的加载
然后安装gzip进行静态图片,images,font的压缩,一些没必要的图片就放到CDN,减少打包的时间,一些小图则转换成BASE64使用,一些静态图片和静态资源,进行nginx内存缓存,
main.js进行减负,一些没必要的不需要main中直接挂载,一些功能比较大,导致加载慢的页面应该增加loading动画,
hashChange
beforeCreate, created,beforeMoutned,mounted,beforeUpdate,updated,beforeDestory,destoryd,actived,deactived,errorCapted,
父子传参
props,$emits
new Vue() 事件总线 on emit
provide inject
$root,$parent,$children
$attrs,$listens
$refs
() => import
require