关于Vue的简单梳理-2

1. 关于 Vue 生命周期 

  • 什么是 Vue 生命周期

  Vue 实例从创建到销毁的过程就是生命周期。

  也就是从开始创建、初始化数据、编译模板、挂在 dom -> 渲染、更新 -> 渲染、卸载等一系列过程

  • Vue生命周期的作用是什么

  生命周期中有多个事件钩子,让我们在控制整个 Vue 实例的过程时更容易形成好的逻辑

  • Vue生命周期总共有几个阶段

  8个阶段:创建前/后 beforeCreated /  created、载入前/后 beforeMount / mounted、更新前/后beforeUpdate / beforeUpdate、销毁前/后 beforeDestroy / destroyed

  • 第一次页面加载会触发哪几个钩子

  第一次加载会触发 beforeCreate、created、beforeMount、mounted

  • 如果有嵌套组件,父子组件的生命周期的执行顺序是什么?

       父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

  • 在什么阶段才能访问操作DOM?

        在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM。

2. Vue 数据双向绑定的实现原理 / 响应式原理

  • Vue2.0 

       Vue 双向数据绑定是通过 Object.defineProperty()  方法 数据劫持 结合 发布订阅模式 Watcher 的方式来实现的。

Object.defineProperty(obj, prop, descriptor) 

// 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

// obj (要定义其上属性的对象) prop (要定义或修改的属性) descriptor (具体的改变方法)

        Vue 利⽤ Object.defineProperty 创建⼀个 observe 来劫持监听所有的属性,把这些属性全部转为 getter 和 setter  。

        Vue 中每个组件实例都会对应⼀个 watcher  实例,它会在组件渲染的过程中把使⽤过的数据属性通过  getter 收集为依赖。之后当依赖项的  setter 触发时,会通知  watcher ,从⽽使它关联的组件重新渲染。

Vue 主要通过以下 4 个步骤来实现数据双向绑定的:

实现一个监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。

实现一个解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。

实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。

实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。

  • Vue3.x响应式数据原理

        Vue3.x改⽤ Proxy 替代Object.defineProperty。因为 Proxy 可以直接监听对象和数组的变化,并且有多达13种拦截⽅法。并且作为新标准将受到浏览器⼚商重点持续的性能优化。

        Proxy 只会代理对象的第⼀层,Vue3 判断当前Reflect.get 的返回值是否为Object,如果是则再通过 reactive ⽅法做代理, 这样就实现了深度观测。

        监测数组的时候可能触发多次 get/set,我们可以判断 key 是否为当前被代理对象 target ⾃身属性,也可以判断旧值与新值是否相等,只有满⾜以上两个条件之⼀时,才有可能执⾏ trigger

  • Object.defineProperty 与  Proxy
  1. Object.defineProperty 只能劫持对象的属性,需要遍历对象的每个属性。Proxy 是直接代理对象。
  2. Object.defineProperty 对新增属性需要⼿动进⾏ Observe , 由于 劫持的是对象的属性,所以新增属性时,需要重新遍历对象,对其新增属性再使⽤  Object.defineProperty 进⾏劫持。 也正是因为这个原因,使⽤ Vue 给  data中的数组或对象新增属性时,需要使⽤  vm.$set 才能保证新增的属性也是响应式的。
  3.  Proxy ⽀持13种拦截操作,这是  defineProperty 所不具有的。
  4. 新标准性能红利Proxy 作为新标准,⻓远来看,JS引擎会继续优化  Proxy ,但  getter 和  setter 基本不会再有针对性优化。
  5. Proxy 兼容性差,Proxy是ES6新增的,IE浏览器不支持。 ⽬前并没有⼀个完整⽀持  Proxy 所有拦截⽅法的Polyfill ⽅案。Object.defineProperty兼容性好,支持 IE9。

3. v-model是如何实现双向绑定的?

  • Vue2.0 

        v-model 是⽤来在表单控件或者组件上创建双向绑定的,他的本质是  v-bind 和  v-on 的语法糖,在⼀个组件上使⽤  v-model ,默认会为组件绑定名为  value 的  prop 和名为  input 的事件。

  • v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
  1. text 和 textarea 元素使用 value 属性和 input 事件;
  2. checkbox 和 radio 使用 checked 属性和 change 事件;
  3. select 字段将 value 作为 prop 并将 change 作为事件。
  • Vue3.0 

        在 3.x 中,⾃定义组件上的  v-model 相当于传递了  modelValue prop 并接收抛出的
update:modelValue 事件

4. 关于Vue组件化

  • 定义: 组件是可复用的 Vue 实例,准确讲它们是 VueComponent 的实例,继承自Vue。
  • 优点:组件化可以增加代码的复用性、可维护性和可测试性
  • 什么时候使用组件?以下分类可作为参考:

  1. 通用组件:实现最基本的功能,具有通用性、复用性,例如按钮组件、输入框组件、布局组件等。

  2. 业务组件:它们完成具体业务,具有一定的复用性,例如登录组件、轮播图组件。

  3. 页面组件:组织应用各部分独立内容,需要时在不同页面组件间切换,例如列表页、详情页组件

  • 组件的本质:组件配置 => VueComponent实例 => render() => Virtual DOM=> DOM,组件的本质是产生虚拟DOM
  • 组件内的data为什么一定要是个函数(1.使每个组件闭包  2. 不容易互相影响) or : 为什么组件中的 data 必须是一个函数,然后 return 一个对象,而 new Vue 实例里,data 可以直接是一个对象?

        当data定义为对象后,这就表示所有的组件实例共⽤了⼀份data数据,因此,⽆论在哪个组件实例中修改了data,都会影响到所有的组件实例。 data是一个函数的时候,每一个实例的data属性都是独立的,不会相互影响了。

        实例化出来的根组件只有一个,你可以将它写成对象,或者是返回一个对象的函数。但是子组件不够健壮,容易在内存的地址中互相影响,就像我们常用的深浅拷贝所能解决的那样。所以为了防止意外的发生,是不被允许在子组件中使用对象来写data。

  • Vue 组件间通信有哪几种方式?

  1. props / $emit 适用 父子组件通信

  2. ref 与 $parent / $children 适用 父子组件通信

  3. EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信

  4. $attrs/$listeners provide / inject 适用于 隔代组件通信

  5. Vuex 适用于 父子、隔代、兄弟组件通信

5. vue3.0 相对于 vue2.x 有哪些变化

  1. 监测机制的改变(Object.defineProperty —> Proxy
  2. composition-api ( 更好的逻辑复用与代码组织,更好的类型推导 )
  3. 对象式的组件声明⽅式 (class)
  4. 使⽤ts
  5. 其它⽅⾯的更改:⽀持⾃定义渲染器、 ⽀持 Fragment(多个根节点)和 Protal(在 dom 其他部分渲染组建内容)组件、基于 treeshaking 优化,提供了更多的内置功能
  6. webpack打包的配置:vue-loader 依赖 "vue-template-compiler" 3.0 改为 @vue/compiler-sfc 需要在plugins里配置 VueLoaderPlugin

  7. vue-cli的支持:目前通过 vue-cli-plugin-vue-next 升级到vue3.0beta版 vue add vue-cli-plugin-vue-next

  8. v-if 与 v-for 的优先级对比:2.x 版本中在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用。3.x 版本中 v-if 总是优先于 v-for 生效

6. 关于 Vue的性能优化

  • 编码阶段
  1. 尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
  2. v-if 和 v-for不能连⽤,v-for 遍历必须为 item 添加 key
  3. 如果需要使⽤v-for给每项元素绑定事件时使⽤事件代理
  4. SPA ⻚⾯采⽤keep-alive缓存组件
  5. 在更多的情况下,使⽤v-if替代v-show
  6. key保证唯⼀
  7. 图⽚资源懒加载
  8. 使⽤路由懒加载、异步组件
  9. 防抖、节流
  10. 第三⽅模块按需导⼊
  11. 长列表性能优化,⻓列表滚动到可视区域动态加载
  • SEO,Web 技术的优化
  1. 预渲染
  2. 服务端渲染SSR
  3. 缓存(客户端缓存、服务端缓存)优化
  4. 使用Chrome Performance 查找性能瓶颈
  • 打包优化
  1. 压缩代码,服务端开启gzip压缩
  2. Tree Shaking/Scope Hoisting
  3. 使⽤cdn加载第三⽅模块
  4. 多线程打包happypack
  5. splitChunks抽离公共⽂件
  6. sourceMap优化
  • ⽤户体验
  1. ⻣架屏
  2. PWA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值