vue总结

207 阅读20分钟

1.vue组件通信,Vue 的单向数据流

Vue 组件间通信是面试常考的知识点之一,这题有点类似于开放题,你回答出越多方法当然越加分,表明你对 Vue 掌握的越熟练。Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,下面我们分别介绍每种通信方式且会说明此种方法可适用于哪类组件间通信。

  • props / $emit 适用 父子组件通信 这种方法是 Vue 组件的基础,相信大部分同学耳闻能详,所以此处就不举例展开介绍。
  • ref 与 parent/parent / children 适用 父子组件通信 ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例 parent/parent / children:访问父 / 子实例
  • EventBus (emit/emit / on) 适用于 父子、隔代、兄弟组件通信 这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件。
  • attrs/attrs/listeners 适用于 隔代组件通信 attrs:包含了父作用域中不被prop所识别(且获取)的特性绑定(classstyle除外)。当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定(classstyle除外),并且可以通过vbind="attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 ( class 和 style 除外 )。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外 ),并且可以通过 v-bind="attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。 listeners:包含了父作用域中的(不含.native修饰器的)von事件监听器。它可以通过von="listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="listeners" 传入内部组件
  • provide / inject 适用于 隔代组件通信 祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。 provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
  • Vuex 适用于 父子、隔代、兄弟组件通信 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。

Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

Vue 的单向数据流

  • 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
  • 额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。
  • 有两种常见的试图改变一个 prop 的情形
  1. 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。 在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值
  2. 这个 prop 以一种原始的值传入且需要进行转换。 在这种情况下,最好使用这个 prop 的值来定义一个计算属性

2.v-model,vue指令

我们在 vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定,我们知道 v-model 本质上不过是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件: text 和 textarea 元素使用 value 属性和 input 事件; checkbox 和 radio 使用 checked 属性和 change 事件; select 字段将 value 作为 prop 并将 change 作为事件。

.lazy 在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步: <!-- 在“change”时而非“input”时更新 --> <input v-model.lazy="msg" >

.number 如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符: <input v-model.number="age" type="number"> 这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

.trim 如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符: <input v-model.trim="msg">

.native 加.native的原因就是为了转成原生,如element+keyup

事件修饰符 阻止单击事件继续传播 <a v-on:click.stop="doThis"></a>

提交事件不再重载页面 <form v-on:submit.prevent="onSubmit"></form>

修饰符可以串联 <a v-on:click.stop.prevent="doThat"></a>

只有修饰符 <form v-on:submit.prevent></form>

添加事件监听器时使用事件捕获模式 即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 <div v-on:click.capture="doThis">...</div>

只当在 event.target 是当前元素自身时触发处理函数 即事件不是从内部元素触发的 <div v-on:click.self="doThat">...</div>

点击事件将只会触发一次 <a v-on:click.once="doThis"></a> 注意: 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

3.slot与slot-scope

slot:

  • 创建组件虚拟节点时,会将组件儿子的虚拟节点保存起来。当初始化组件时,通过插槽属性将儿子进行分类 {a:[vnode],b[vnode]}
  • 渲染组件时会拿对应的 slot 属性的节点进行替换操作。(插槽的作用域为父组件) slot-scope
  • 作用域插槽在解析的时候不会作为组件的孩子节点。会解析成函数,当子组件渲染时,会调用此函数进行渲染。
  • 普通插槽渲染的作用域是父组件,作用域插槽的渲染作用域是当前子组件。 v-slot
  • 在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。

4.生命周期

生命周期是什么?

  • Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。 什么时候被调用?
  • beforeCreate :实例初始化之后,数据观测之前调用
  • created:实例创建万之后调用。实例完成:数据观测、属性和方法的运算、 watch/event 事件回调。无 $el .
  • beforeMount:在挂载之前调用,相关 render 函数首次被调用
  • mounted:了被新创建的vm.$el替换,并挂载到实例上去之后调用改钩子。
  • beforeUpdate:数据更新前调用,发生在虚拟DOM重新渲染和打补丁,在这之后会调用改钩子。
  • updated:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用改钩子。
  • activited:keep-alive 专属,组件被激活时调用
  • deactivated:keep-alive 专属,组件被销毁时调用
  • beforeDestroy:实例销毁前调用,实例仍然可用。
  • destroyed:实例销毁之后调用,调用后,Vue实例指示的所有东西都会解绑,所有事件监听器和所有子实例都会被移除 每个生命周期内部可以做什么?
  • created:实例已经创建完成,因为他是最早触发的,所以可以进行一些数据、资源的请求。
  • mounted:实例已经挂载完成,可以进行一些DOM操作。
  • beforeUpdate:可以在这个钩子中进一步的更改状态,不会触发重渲染。
  • updated:可以执行依赖于DOM的操作,但是要避免更改状态,可能会导致更新无线循环。
  • destroyed:可以执行一些优化操作,清空计时器,解除绑定事件。

5.minxin,filter,自定义指令

minxin:

  • 创建好混入文件,并导出。
  • .vue文件中引入 filter
  • 调用: {{msg | mimi('12','5')}} 自定义指令
  • Vue.directive

6.vue.component,vue.extend

Vue.extend({})

  • 使用vue.extend返回一个子类构造函数,也就是预设部分选项的vue实例构造器。 vue.component
  • vue.component用于全局注册组件

7. Computed watch 和 method

computed:

  • 默认computed也是一个watcher具备缓存,只有当依赖的数据变化时才会计算, 当数据没有变化时, 它会读取缓存数据。如果一个数据依赖于其他数据,使用 computed watch:
  • 每次都需要执行函数。 watch 更适用于数据变化时的异步操作。如果需要在某个数据变化时做一些事情,使用watch。 method:
  • 只要把方法用到模板上了,每次一变化就会重新渲染视图,性能开销大

8.template,render,jsx

template

  • 语法简单明了,数据操作与视图分离,开发体验友好。但是在某些特定场合中,会限制一些功能的扩展,如动态使用过滤器、解析字符串类型的模板文件等。以上功能的实现可以借助vue的render语法,render语法比template更偏底层,允许在HTML中使用js语法,可以极大的扩展HTML的能力。 render函数
  • 注入了一个参数createElement,用来创建我们所需要的标签内容,有三个参数:HTML标签(elementTag),标签属性(option),子元素(children);从createElement的参数列表里面可以看出,如果组件内部结构嵌套比较深,render的语法写起来会比较繁琐,需要不断的调用createElement, jsx
  • jsx无疑是一种很好的选择,区别在于jsx可以像我们写HTML文件一样写业务代码,借助于babel,会将jsx语法转换成render语法,没有什么副作用。
  • jsx并不能解析vue指令,因此template转jsx语法时,每一部分的对应写法和vue官网文档一致

9.data,props

props

  • props(或properties)是我们将数据从父组件向下传递到其子组件的方式。
  • 数据从根组件(位于最顶端的组件)沿着树向下流动。就像基因是如何代代相传的一样,父组件也会将自己的props传给了他们的孩子。
  • 当我们从组件内部访问props时,我们并不拥有它们,所以我们不能更改它们.但是有些情况我们需要改变变量,所以 data 就派上用场了。 data
  • data是每个组件的内存,这是存储数据和希望跟踪的任何其他变量的地方。

10.name属性应用

  • 当使用组件递归调用时,被递归调用的组件必须定义name属性,因为在组件里面调用自己时,不是使用的在components里注册的组件,而是使用根据name属性查找组件
  • keep-alive包裹动态组件时,会缓存不活动的组件实例,会出现include和exclude属性,包含或者排除指定name组件
  • vue-tools插件调试时没有name属性会报错或警告

11.keep-alive

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,其有以下特性:

  • 一般结合路由和动态组件一起使用,用于缓存组件;
  • 提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;
  • 对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。

12.vue实现动画

  • vue内置组件transition,元素出现和消失都呈现动画。 v-enter,v-enter-to,v-leave,v-leave-to。其中v-enter,v-leave-to代表开始以及结束时的状态。v-enter-active,v-leave-active代表动画的过程。
  • animate.css插件

13.key属性作用

  • key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速。Vue 的 diff 过程可以概括为:oldCh 和 newCh 各有两个头尾的变量 oldStartIndex、oldEndIndex 和 newStartIndex、newEndIndex,它们会新节点和旧节点会进行两两对比,即一共有4种比较方式:newStartIndex 和oldStartIndex 、newEndIndex 和 oldEndIndex 、newStartIndex 和 oldEndIndex 、newEndIndex 和 oldStartIndex,如果以上 4 种比较都没匹配,如果设置了key,就会用 key 再进行比较,在比较的过程中,遍历会往中间靠,一旦 StartIdx > EndIdx 表明 oldCh 和 newCh 至少有一个已经遍历完了,就会结束比较。
  • 所以 Vue 中 key 的作用是:key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速
  • 更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。
  • 更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快,源码如下:

WeChat6f8ba193a95f69ad437a29f5cbef4634.png

14.vue-router

  1. hash模式 早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容。

hash 路由模式的实现主要是基于下面几个特性:

  • URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送;
  • hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash 的切换;
  • 可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变;或者使用  JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值;
  • 我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)。
  1. history模式 HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState() 和 history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记

history 路由模式的实现主要基于存在下面几个特性:

  • pushState 和 repalceState 两个 API 来操作实现 URL 的变化 ;
  • 我们可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染);
  • history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)。
  1. abstract 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式.

15.路由守卫

  • 全局守卫
  1. router.beforeEach((to,from,next)=>{})
  2. 回调函数中的参数,to:进入到哪个路由去,from:从哪个路由离开,next:函数,决定是否展示你要看到的路由页面。
  3. router.js中设置全局守卫,判断to.path当前将要进入的路径是否为登录或注册,如果是就执行next(),展示当前界面。如果不是,就弹出alert,然后移至登录界面。这样就可实现,用户在未登录状态下,展示的一直是登录界面。
  • 组件内的守卫
  1. 到达这个组件时,beforeRouteEnter:(to,from,next)=>{}
  2. 离开这个组件时,beforeRouteLeave:(to,from,next)=>{},,点击其他组件时,可以判断是否确认离开。确认执行next();取消执行next(false),留在当前页面。

16.vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  2. 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。 主要包括以下几个模块:
  • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
  • Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
  • Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
  • Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
  • Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。 vuex分模块
  1. 项目中创建好store仓库目录,将store分割为多个模块,更好更清晰的管理自己的项目。每个module都有自己的state、mutation、action、getter。
  2. 创建store(index.js文件中) WeChat72edf685a26dd4fb78f44c563f59dc2a.png

17.vue.use

使用别人的组件时,会用到 Vue.use() 。例如:Vue.use(VueRouter)、Vue.use(ElementUI)

18.vue组件

  1. 在components文件内创建一个文件
  2. 全局引用或在需要文件引用(components)

19.vue.config.js

vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。你也可以使用 package.json 中的 vue 字段,但是注意这种写法需要你严格遵照 JSON 的格式来写。 WeChat926fd4c7bef5e515bb9277a41f81e854.png

20.axios

创建实例: axios.create() WeChata63e96d82a8f701d39ef763b1612d20b.png 全局配置(优先级最低):如

  • axios.default.timeout = 3000
  • axios.default.baseURL = 3000 请求拦截器 WeChatc5ccc29eafc4d7735e09fc1e6d748ae8.png 响应拦截器 WeChat4f58a7d019f56ec44c7e815eae1f0bbf.png

21.常用库

element,vant

22.webpack

23.css预处理工具

scss:

  1. 安装依赖:npm install node-sass sass-loader -D

  2. package.json文件 "devDependencies": { "node-sass": "^4.9.3", "sass-loader": "^7.1.0", },

  3. webpack.base.conf.js文件 WeChat8468df9e0dd2aeca1e98df9c5b8b62ae.png

24.ssr,pwa

  • ssr SSR大致的意思就是vue在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。

  • 服务端SSR渲染的优点:

  1. 更好的 SEO: 因为 SPA 页面的内容是通过 Ajax 获取,而搜索引擎爬取工具并不会等待 Ajax 异步完成后再抓取页面内容,所以在 SPA 中是抓取不到页面通过 Ajax 获取到的内容;而 SSR 是直接由服务端返回已经渲染好的页面(数据已经包含在页面中),所以搜索引擎爬取工具可以抓取渲染好的页面;
  2. 更快的内容到达时间(首屏加载更快): SPA 会等待所有 Vue 编译后的 js 文件都下载完成后,才开始进行页面的渲染,文件下载等需要一定的时间等,所以首屏渲染需要一定的时间;SSR 直接由服务端渲染好页面直接返回显示,无需等待下载 js 文件及再去渲染等,所以 SSR 有更快的内容到达时间;
  • 服务端渲染的缺点:
  1. 更多的开发条件限制: 例如服务端渲染只支持 beforCreate 和 created 两个钩子函数,这会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行;并且与可以部署在任何静态文件服务器上的完全静态单页面应用程序 SPA 不同,服务端渲染应用程序,需要处于 Node.js server 运行环境;
  2. 更多的服务器负载:在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用CPU 资源 (CPU-intensive - CPU 密集),因此如果你预料在高流量环境 ( high traffic ) 下使用,请准备相应的服务器负载,并明智地采用缓存策略。
  • pwa PWA全称Progressive Web App,即渐进式WEB应用。

一个 PWA 应用首先是一个网页, 可以通过 Web 技术编写出一个网页应用. 随后添加上 App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能。 解决了哪些问题?

  • 可以添加至主屏幕,点击主屏幕图标可以实现启动动画以及隐藏地址栏
  • 实现离线缓存功能,即使用户手机没有网络,依然可以使用一些离线功能
  • 实现了消息推送

25.单元测试

vue单元测试

26.mvvm

全称: Model-View-ViewModel , Model 表示数据模型层。 view 表示视图层, ViewModel 是 View 和 Model 层的桥梁,数据绑定到 viewModel 层并自动渲染到页面中,视图变化通知 viewModel 层更新数据。

vue既是mvvm也不是mvvm框架,它借鉴了官网mvvm框架的思想,但是可能在实现的时候有自己独特的架构。 WeChatd8790885bbf4b84cfdbb36a5785bc404.png

27.nextTick

异步方法,异步渲染最后一步,与JS事件循环联系紧密。主要使用了宏任务微任务(setTimeout、promise那些),定义了一个异步方法,多次调用nextTick会将方法存入队列,通过异步方法清空当前队列。

28.vue组件初渲染

WeChatbe04ac752a4c901712dc46b306661174.png

  • 解析模板为 render 函数 这部分是说vue 编译相关,也就是说把 vue 语法编译 成 js 语法,通过执行 vue-template-compiler 的 compiler 函数,得到 render 
  • 触发响应式 响应式关键 Object.defineProperty(),将模版初次渲染使用到的变量绑定到 Object.defineProperty() 中,首次渲染会 触发 getter 
  • 执行render 函数 第一点说到已经得到render函数,现在要执行render函数, 将 vue 语法转成 h 函数的结果,也就是 vNode,后续进行一系列操作

29.vue响应式

  • Vue2 Object.defineProperty 重新定义 data 中所有的属性, Object.defineProperty 可以使数据的获取与设置增加一个拦截的功能,拦截属性的获取,进行依赖收集。拦截属性的更新操作,进行通知。
  • vue3 Proxy代理拦截:reactive函数执行,会将传入的target对象通过Proxy包装,拦截它的get,set等,并将代理的target缓存到targetMap,targetMap.set(target, new Map())。 代理的get的时候会调用一个track函数,而set会调用一个triger函数。分别对应依赖收集和触发更新。

30.虚拟dom

  • 虚拟 DOM 的实现原理主要包括以下 3 部分:
  1. 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
  2. diff 算法 — 比较两棵虚拟 DOM 树的差异;
  3. pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。
  • 如何从真实DOM到虚拟DOM
  1. 将模板转换成 ast 树, ast 用对象来描述真实的JS语法(将真实DOM转换成虚拟DOM)
  2. 优化树
  3. 将 ast 树生成代码
  • 虚拟 DOM 的优缺点 优点: 保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限; 无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率; 跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。

缺点: 无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。

31.diff算法

  • 时间复杂度: 个树的完全 diff 算法是一个时间复杂度为 O(n*3) ,vue进行优化转化成 O(n) 。 理解:
  1. 最小量更新, key 很重要。这个可以是这个节点的唯一标识,告诉 diff 算法,在更改前后它们是同一个DOM节点
  2. 扩展 v-for 为什么要有 key ,没有 key 会暴力复用,举例子的话随便说一个比如移动节点或者增加节点(修改DOM),加 key 只会移动减少操作DOM。
  3. 只有是同一个虚拟节点才会进行精细化比较,否则就是暴力删除旧的,插入新的。
  4. 只进行同层比较,不会进行跨层比较。
  • diff算法的优化策略:四种命中查找,四个指针
  1. 旧前与新前(先比开头,后插入和删除节点的这种情况)
  2. 旧后与新后(比结尾,前插入或删除的情况)
  3. 旧前与新后(头与尾比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧后之后)
  4. 旧后与新前(尾与头比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧前之前)

32.vue性能优化

  • 编码优化:
  1. 事件代理
  2. keep-alive
  3. 拆分组件
  4. key 保证唯一性
  5. 路由懒加载、异步组件
  6. 防抖节流
  • Vue加载性能优化
  1. 第三方模块按需导入( babel-plugin-component )
  2. 图片懒加载
  • 用户体验
  1. app-skeleton 骨架屏
  2. shellap p壳
  3. pwa
  • SEO优化
  1. 预渲染