vue:基础:原理知识点

1、vue编译原理【将 template 转成 render 函数的过程。】

(1)原理

浏览器运行时会把 template 转化成 render 函数,webpack 则不需要,(因为 vue loader已转换完成)get数据收集是在render函数中执行的,每个computed函数都会生成一个watcher和data里的数据绑定,data 数据变化后watcher执行,(所以才有了缓存) ,每个组件都会生成一个渲染watcher,里面主要是做微任务部分,总之同步任务做数据收集,微任务做diff及dom渲染。

(2)详细:主要分3个流程

  • template 字符串转换成 ast 抽象语法树
  • 优化 ast 抽象语法树,主要标记一些节点内容不变的节点,静态节点和静态根节点,patch 更新对比的时候跳过这些节点比对和重新渲染
  • 将优化好的 ast 抽象语法树,通过递归的方式,拼接为 render 字符串,最后执行 new function,返回 render 方法

2、vue 双向绑定原理【另一种问法:响应式数据的原理/页面更新,vue底层是如何响应】

采用数据劫持结合发布者订阅模式,通过 Object.defineProperty() 来劫持各个属性的 getter、setter,在数据变动时发给订阅者,触发相应事件。

注)数据劫持(vue.js);发布者-订阅模式(backbone.js);脏值检查(angular.j

另一种回答:数据劫持 + 观察者模式

对象内部通过 defineReactive 方法,使用 Object.defineProperty 将属性进行劫持(只会劫持已存在的属性),数组则是通过重写数组来实现。当页面使用对应属性时,每个属性都拥有自己的 dep 属性,存在它所依赖的 watcher (依赖收集)get,当属性变化后会通知自己对应的 watcher 去更新(派发更新)set。

        1、Object.defineProperty 数据劫持

        2、使用 getter 收集依赖 ,setter 通知 watcher派发更新。

        3、watcher 发布订阅模式。

        2、$set 原理?

如果目标是数组,直接使用数组的 splice 方法触发相应式;

如果目标是对象,会先判读属性是否存在、对象是否是响应式,最终如果要对属性进行响应式处理,则是通过调用 defineReactive 方法进行响应式处理( defineReactive 方法就是 Vue 在初始化对象时,给对象属性采用 Object.defineProperty 动态添加 getter 和 setter 的功能所调用的方法)

3、nextTick 实现原理?

(1)nexTick 的作用:nextTick 中的回调是在下次 DOM 更新循环结束之后执行的延迟回调。

(2)使用场景:在修改数据之后立即使用这个方法,获取更新后的 DOM

(3)nextTick 实现原理:采用微任务优先的方式调用异步方法去执行 nextTick 包装的方法。

4、vue 事件绑定原理?

原生事件绑定是通过 addEventListener 绑定真实的元素,组件事件绑定是通过 on 实现的。

注)如果要在组件上使用原生事件,需要加.native修饰符,这样就相当于在父组件中把子组件当做普通的HTML标签,然后加上原生事件。on、$emit 是基于发布订阅模式的,维护一个事件中心,on的时候将事件按名称存在事件中心里,称之为订阅者,然后emit将对应的事件进行发布,去执行事件中心里的对应的监听器。

5、观察者模式和发布订阅者模式的区别?【发布 / 订阅模式和观察者模式的区别是什么?】

两者最大的区别:发布订阅者模式有一个调度中心,观察者模式每个被订阅的目标都会有一个被观察的对象;而发布订阅者模式则会有一个调度中心,取消了发布订阅者之间的依赖,在这个中心可以控制有些数据可以不传输给订阅者,可以增加权限等;

6、vue2 和 vue3 实现双向绑定的区别?【Object.defineProperty和Proxy的区别】

(0)vue3采用了 proxy 代理,和 vue 2 中Object.defineProxy 一样有两个属性:get/set。

(1)vue3中的proxy一次性给所有对象都添加set和get属性。Object.defineProxy 一次只能给一个对象添加属性。

(2)proxy 不兼容IE,Object.defineProperty 不兼容IE8以下的。

(3)proxy 调用递归时,Object.defineProperty 在一开始就全部递归。

(4)Proxy 使用上比Object.defineProperty 方便的多、性能也比他好。

(5)proxy 代理整个对象,Object.defineProperty 只能代理对象上的某个属性。

(6)数组新增/删除/属性时,proxy 可以监听,Object.defineProperty 不行。

(7)对象上定义新属性时,proxy 可以监听,Object.defineProperty 不行。

注)proxy: vue 3.x 版本以上使用的;语法:可以使用new来定义;或者使用Proxy.revocable 的静态方法。

        Object.defineProperty: vue 2.x 版本使用的,把内部解析成 observer、Dep,使用watch 相联。

7、vue2和vue3的区别,做了哪些优化?

(1)vue2 和 vue3 定义变量的方法不一样

        vue2:定义变量在data 中,方法写在 methods 中。

        vue3:定义的变量和方法都在 setup 中。

(2)vue2 和 vue3 生命周期钩子函数不同

  • 3.0 使用之前需要先引入
  • onRenderTracked:状态跟踪。会跟踪页面中响应式的变量和方法,return 出来的东西,都会更新。页面中有update 也跟踪。
  • 3.0 还增加两个勾子函数:onRenderTracked、onRenderTiggered 【07. vue中onRenderTracked()和 onRenderTriggered()钩子函数的使用-码云笔记
  • onRenderTiggered:状态触发。
  • onRenderTracked 和 onRenderTiggered 都写在 setup 里面。

vue2 生命周期 vue3 生命周期 beforeCreate -> setup // 组件创建之前 created -> setup // 组件创建立之后 beforeMount -> onBeforeMount // 组件加载 DOM 之前 Mounted -> onMounted // 组件加载 DOM 之后 beforeUpdate -> onBeforeUpdate // 组件更新 DOM 之前 updated -> onUpdated // 组件更新 DOM 之后 // 3.0 使用之前需要引入 import { reactive, toRefs, onMounted, onBeforeMount, onBeforeUpdate, onUpdated, } from "vue";

(3)vue3 支持 ts 更好。但是 2.0 也支持

8、为什么Vue3用了Proxy性能更好呢?

        Object.defineProperty 对对象自身做个性,proxy 在 Object 基础上加一层拦截,不修改原对象。2.0 监听不了数据变化,监听手段单一,只能监听set 和 get,Proxy 有10几种监听,必须把所有的属性添加 defineProperty ,Proxy整个对象都会进行拦截。

9、proxy 是什么?proxy的缺点是什么? proxy 为什么比Object.defineProperty快?

(1)定义:在目标对象之前设置的“拦截”,外界访问时,都需要通过这层拦截,因此提供了一种机制,可以对外界的访问过滤和改写。

(2)缺点:浏览器兼容性问题,不兼容IE。

(3)Proxy的优点如下:

        1. Proxy可以直接监听对象而非属性;

        2. Proxy可以直接监听数组的变化;

        3. Pxory有多种(13种)拦截方法,不限于apply、ownKeys、deleteProperty、has等等 是Object.defineProperty不具备的;

        4. Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改;

        5. Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

        Object.defineProperty的优点如下:

        1. 兼容性好,支持 IE9,而Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写

10、vue 组件通讯方式?

(1)props 和 emit。父组件向子组件传递数据是通过props传递的,子组件传递给父组件是通过emit。

(2)parent和parent 和 parent和children 获取单签组件的父组件和当前组件的子组件。

(3)父组件中通过 provide 来提供变量,然后在子组件中通过 inject 来注入变量。

【官方不推荐在实际业务中适用,但是写组件库时很常用。】

(4)$refs 获取组件实例

(5)events Bus 兄弟组件传参,就是中央事件总线。

(6)vuex 状态管理

(7)attrs和attrs 和 attrs和listeners A -> B -> C。Vue2.4开始提供了attrs和attrs和attrs和listeners来解决这个问题。

11、首页为什么会白屏?如何优化白屏?

(1)什么是白屏?

现在很多页面使用模版渲染,在网速不好的情况下,会导致出现loading 或者空白页,这种就叫白屏。

(2)白屏出现的原因【根本原因:网速 & 静态资源】

  • css 文件加载需要时间【解决:css 代码前置或者内联。】
  • 首屏内联js 会影响加载时间 【解决:尽量不在首屏中加载JS,或者放置内联脚本】
  • 首屏没有实质的数据,是通过接口异步加载进来的【解决:首屏直接同步渲染 html ,页面滚动时异步加载】

(3)解决方法(如何避免)

  • 使用模版引擎渲染所有页面,减少文件加载积压:css、js、html。
  • 提供一些友好的交互:比如假的滚动条。
  • 加快js 执行速度,比如常见的JS 滚动,在看的见的地方先渲染这部分东西。
  • 使用本地存储静态资源。

12、谈谈单页面应用与多页面应用的区别

(1)单页面(SPA):

  • 概念:只有一个html页面,所有跳转方式都是通过组件切换完成的。
  • 优点:页面之间跳转流畅、组件化开发、组件可复用、开发便捷、易维护。
  • 缺点:首屏加载较慢,当然这个问题现在已经基本被合理化解决了,加载整个项目中使用的css、js,SEO优化不好

(2)多页面(MPA):

  • 概念:整个项目有多个html,所有跳转方式都是页面之间相互跳转的。
  • 优点:首屏加载较快,只加载本页所使用的的css、js,SEO优化较好。
  • 缺点:页面跳转较慢。

13、在vue项目中你有没有做性能方面的优化,怎么做的?

        百分之八十的人都说会:js、css 这些,这些是都是必须要做的。

        性能优化过程中我们更多的需要考虑DMS解析、服务器缓存、浏览器缓存这些点。

(1)gzip

        前端项目基本都放在cdn上,gzip压缩是有必须的,能减少js文件大小两到三倍

        参考加速度nginx:gzip和缓存【nginx配置:在你对应的域名下,添加配置,重启服务 】

(2)服务器缓存(nginx 缓存)

(3)浏览器缓存

(4)vue 中的 keep-alive

        做大型项目的时候,有很多个router,在页面快速切换中,为了保证页面加载的效率,可以使用缓存机制,也可以使用 keep-alive 里面包着rourter-view。keep-alive 会缓存组件,方便快速切换。

        是否需要重新同步数据在vue-router 的钩子函数中判断。

(5)promise 请求(优点:1、减少回调;2、串并行处理;3、代码优雅)

        注)ES6在性能优化上可以使用promise、async/await 压缩请求时间

(6)预加载

猜你喜欢

转载自blog.csdn.net/u013592575/article/details/126703073