推广 热搜: 行业  机械  设备    系统  教师  经纪  参数    蒸汽 

梳理Vue常考面试题

   日期:2024-11-10     移动:http://changmeillh.xhstdz.com/mobile/quote/66452.html

完整版推荐在线阅读 https://interview2.poetries.top/

梳理Vue常考面试题

MVVM是Model-View-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据。

  • MVVM 是 Model-View-ViewModel 的缩写
  • Model: 代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。我们可以把Model称为数据层,因为它仅仅关注数据本身,不关心任何行为
  • View: 用户操作界面。当ViewModel对Model进行更新的时候,会通过数据绑定更新到View
  • ViewModel: 业务逻辑层,View需要什么数据,ViewModel要提供这个数据;View有某些操作,ViewModel就要响应这些操作,所以可以说它是Model for View.
  • 总结: MVVM模式简化了界面与业务的依赖,解决了数据频繁更新。MVVM 在使用当中,利用双向绑定技术,使得 Model 变化时,ViewModel 会自动更新,而 ViewModel 变化时,View 也会自动变化。

答:总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后

生命周期是什么

Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是Vue的生命周期


什么是vue生命周期?

  • 答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

vue生命周期的作用是什么?

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

vue生命周期总共有几个阶段?

  • 答:它可以总共分为个阶段:创建前/后、载入前/后、更新前/后、销毁前/销毁后。

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

  • 答:会触发下面这几个、、、 。

DOM 渲染在哪个周期中就已经完成?

  • 答: 渲染在 中就已经完成了
  • 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 来劫持各个属性的,,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 对象传给 Vue 实例来作为它的 选项时,Vue 将遍历它的属性,用 将它们转为 。用户看不到 ,但是在内部它们让 追踪依赖,在属性被访问和修改时通知变化。
  • vue的数据双向绑定 将作为数据绑定的入口,整合,和三者,通过来监听自己的的数据变化,通过来解析编译模板指令(中是用来解析 ),最终利用搭起和之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化()—>数据变更双向绑定效果。

父组件与子组件传值

父组件传给子组件:子组件通过方法接受数据;

  • 子组件传给父组件: 方法传递参数

非父子组件间的数据传递,兄弟组件传值

,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适(虽然也有不少人推荐直接用,具体来说看需求)

  • 模式:在浏览器中符号,#以及#后面的字符称之为,用 读取。特点:虽然在中,但不被包括在请求中;用来指导浏览器动作,对服务端安全无用,不会重加载页面。
  • 模式:h采用的新特性;且提供了两个新方法: , 可以对浏览器历史记录栈进行修改,以及事件的监听到状态变更

keep-alive可以实现组件缓存,当组件切换时不会对当前组件进行卸载

  • 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染

比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染

  • 常用的两个属性,允许组件有条件的进行缓存
  • 两个生命周期,用来得知当前组件是否处于活跃状态

提供一个在页面上已存在的 元素作为 实例的挂载目标.可以是 CSS 选择器,也可以是一个 实例,

  • 采用的语法或的方法引入插件
  • 使用全局方法使用插件,可以传入一个选项对象
  • : 实例已经创建完成之后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, 事件回调. 然而, 挂载阶段还没有开始, 属性目前还不可见
  • : 被新创建的 替换,并挂载到实例上去之后调用该钩子。如果 实例挂载了一个文档内元素,当 被调用时 也在文档内。
  • : 组件激活时调用

问题一:构建的 vue-cli 工程都到了哪些技术,它们的作用分别是什么?

  • :工程的核心,主要特点是 双向数据绑定 和 组件系统。
  • :官方推荐使用的路由框架。
  • :专为 应用项目开发的状态管理器,主要用于维护组件间共用的一些 变量 和 方法。
  • ( 或者 、 ):用于发起 、或 等 请求,基于 设计。
  • 等:一个专为设计的移动端UI组件库。
  • 创建一个文件,用于事件机制的管理。
  • :模块加载和工程打包器。

问题二:vue-cli 工程常用的 npm 命令有哪些?

  • 下载 资源包的命令:

  • 启动 开发环境的 npm命令:

  • 生成 生产环境部署资源 的 命令:

  • 用于查看 生产环境部署资源文件大小的 命令:

在浏览器上自动弹出一个 展示 工程打包后 、、 文件里面所包含代码的页面。可以具此优化 生产环境部署的静态资源,提升 页面 的加载速度

可以让我们在下次 DOM 更新循环结束之后执行延迟回调,用于获得更新后的

  • 低耦合。视图()可以独立于变化和修改,一个可以绑定到不同的上,当View变化的时候Model可以不变,当变化的时候也可以不变
  • 可重用性。你可以把一些视图逻辑放在一个里面,让很多重用这段视图逻辑
  • 可测试。界面素来是比较难于测试的,而现在测试可以针对来写

声明式(标签跳转)


编程式( js跳转)


其基本实现原理

  • 作为客户端与服务端的公用入口,导出 根实例,供客户端 与服务端 使用。客户端 主要作用挂载到 上,服务端 除了创建和返回实例,还进行路由匹配与数据预获取。
  • 为客服端打包一个 ,为服务端打包一个 。
  • 服务器接收请求时,会根据 ,加载相应组件,获取和解析异步数据,创建一个读取 的 ,然后生成 发送给客户端。
  • 客户端混合,客户端收到从服务端传来的 与自己的生成的 DOM 进行对比,把不相同的 激活,使其可以能够响应后续变化,这个过程称为客户端激活 。为确保混合成功,客户端与服务器端需要共享同一套数据。在服务端,可以在渲染之前获取数据,填充到 里,这样,在客户端挂载到 之前,可以直接从 里取数据。首屏的动态数据通过 发送到客户端

的实现,主要就是把 的组件输出成一个完整 , 就是干这事的

  • 需要做的事多点(输出完整 HTML),除了,还需如数据获取填充至 、客户端混合()、缓存等等。 相比于其他模板引擎(, 等),最终要实现的目的是一样的,性能上可能要差点
  • 每个组件都是 的实例。
  • 组件共享 属性,当 的值是同一个引用类型的值时,改变其中一个会影响其他
  • 建立与其他属性(如:、 )的联系;
  • 属性改变后,通知计算属性重新计算

实现时,主要如下

  • 初始化 , 使用 把这些属性全部转为 。
  • 初始化 , 遍历 里的每个属性,每个 属性都是一个 实例。每个属性提供的函数作为属性的 ,使用 转化。
  • 依赖收集。用于依赖发生变化时,触发属性重新计算。
  • 若出现当前 计算属性嵌套其他 计算属性时,先进行其他的依赖收集
  • 模板解析这种事,本质是将数据转化为一段 ,最开始出现在后端,经过各种处理吐给前端。随着各种 的兴起,模板解析交由前端处理。
  • 总的来说, 是将 转化成一个 字符串。

可以简单理解成以下步骤:

  • 过程,将 利用正则转化成 抽象语法树。
  • 过程,标记静态节点,后 过程跳过静态节点,提升性能。
  • 过程,生成 字符串

用 工具。 大意是通过 来查看每个函数的调用时常,定位出哪个函数的问题,从而能判断哪个组件出了问题

  • :一般用在表达输入,很轻松的实现表单控件和数据的双向绑定
  • : 更新元素的
  • 与 : 条件渲染, 注意二者区别

使用了v-if的时候,如果值为false,那么页面将不会有这个html标签生成。 v-show则是不管值为true还是false,html元素都会存在,只是CSS中的display显示或隐藏

  • : : 可以简写为,绑定一个事件。如果事件触发了,就可以指定事件的处理函数
  • :基于源数据多次渲染元素或模板块
  • : 当表达式的值改变时,将其产生的连带影响,响应式地作用于

语法:简写:

Object.defineProperty() 的问题主要有三个:

  • 不能监听数组的变化
  • 必须遍历对象的每个属性
  • 必须深层遍历嵌套的对象

Proxy 在 ES2015 规范中被正式加入,它有以下几个特点

  • 针对对象:针对整个对象,而不是对象的某个属性,所以也就不需要对 keys 进行遍历。这解决了上述 Object.defineProperty() 第二个问题
  • 支持数组:Proxy 不需要对数组的方法进行重载,省去了众多 hack,减少代码量等于减少了维护成本,而且标准的就是最好的。

除了上述两点之外,Proxy 还拥有以下优势:

  • Proxy 的第二个参数可以有 13 种拦截方法,这比起 Object.defineProperty() 要更加丰富
  • Proxy 作为新标准受到浏览器厂商的重点关注和性能优化,相比之下 Object.defineProperty() 是一个已有的老方法。
  • 全局守卫
  • 路由独享守卫
  • 路由组件内的守卫

全局守卫

vue-router全局有三个守卫

  • 全局前置守卫 进入路由之前
  • 全局解析守卫(2.5.0+) 在调用之后调用
  • 全局后置钩子 进入路由之后

路由独享守卫

如果你不想全局配置守卫的话,你可以为某些路由单独配置守卫


路由组件内的守卫

  • beforeRouteEnter 进入路由前, 在路由独享守卫后调用 不能 获取组件实例 this,组件实例还没被创建
  • beforeRouteUpdate (2.2) 路由复用同一个组件时, 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 this
  • beforeRouteLeave 离开当前路由时, 导航离开该组件的对应路由时调用,可以访问组件实例 this

组件之间通讯分为三种: 父传子、子传父、兄弟组件之间的通讯

1. 父组件给子组件传值

  • 使用,父组件可以使用向子组件传递数据。
  • 父组件模板:

子组件vue模板child.vue:


2. 子组件向父组件通信

父组件向子组件传递事件方法,子组件通过触发事件,回调给父组件

父组件vue模板father.vue:


子组件vue模板child.vue:


3. 非父子, 兄弟组件之间通信

vue2中废弃了broadcast广播和分发事件的方法。父子组件中可以用props和$emit()。如何实现非父子组件间的通信,可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,然后通过分别调用Bus事件触发和监听来实现通信和参数传递。Bus.js可以是这样:


在需要通信的组件都引入Bus.js:


另一个组件也import Bus.js 在钩子函数中监听on事件


Vue与AngularJS的区别

  • Angular采用Typescript开发, 而Vue可以使用javascript也可以使用Typescript
  • AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。
  • AngularJS社区完善, Vue的学习成本较小

Vue与React的区别

  • vue组件分为全局注册和局部注册,在react中都是通过import相应组件,然后模版中引用;
  • props是可以动态变化的,子组件也实时更新,在react中官方建议props要像纯函数那样,输入输出一致对应,而且不太建议通过props来更改视图;
  • 子组件一般要显示地调用props选项来声明它期待获得的数据。而在react中不必需,另两者都有props校验机制;
  • 每个Vue实例都实现了事件接口,方便父子组件通信,小型项目中不需要引入状态管理机制,而react必需自己实现;
  • 使用插槽分发内容,使得可以混合父组件的内容与子组件自己的模板;
  • 多了指令系统,让模版可以实现更丰富的功能,而React只能使用JSX语法;
  • Vue增加的语法糖computed和watch,而在React中需要自己写一套逻辑来实现;
  • react的思路是all in js,通过js来生成html,所以设计了jsx,还有通过js来操作css,社区的styled-component、jss等;而 vue是把html,css,js组合到一起,用各自的处理方式,vue有单文件组件,可以把html、css、js写到一个文件中,html提供了模板引擎来处理。
  • react做的事情很少,很多都交给社区去做,vue很多东西都是内置的,写起来确实方便一些, 比如 redux的combineReducer就对应vuex的modules, 比如reselect就对应vuex的getter和vue组件的computed, vuex的mutation是直接改变的原始数据,而redux的reducer是返回一个全新的state,所以redux结合immutable来优化性能,vue不需要。
  • react是整体的思路的就是函数式,所以推崇纯组件,数据不可变,单向数据流,当然需要双向的地方也可以做到,比如结合redux-form,组件的横向拆分一般是通过高阶组件。而vue是数据可变的,双向绑定,声明式的写法,vue组件的横向拆分很多情况下用mixin
  • vuex 就是一个仓库,仓库里放了很多对象。其中 state 就是数据源存放地,对应于一般 vue 对象里面的 data
  • state 里面存放的数据是响应式的,vue 组件从 store 读取数据,若是 store 中的数据发生改变,依赖这相数据的组件也会发生更新
  • 它通过 mapState 把全局的 state 和 getters 映射到当前组件的 computed 计算属性

state

使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据

mutations

定义的方法动态修改Vuex 的 store 中的状态或数据。

getters

类似vue的计算属性,主要用来过滤一些数据

action

  • actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。
  • vuex 一般用于中大型 web 单页应用中对应用的状态进行管理,对于一些组件间关系较为简单的小型应用,使用 vuex 的必要性不是很大,因为完全可以用组件 prop 属性或者事件来完成父子组件之间的通信,vuex 更多地用于解决跨组件通信以及作为数据中心集中式存储数据。
  • 使用Vuex解决非父子组件之间通信问题 vuex 是通过将 state 作为数据中心、各个组件共享 state 实现跨组件通信的,此时的数据完全独立于组件,因此将组件间共享的数据置于 State 中能有效解决多层级组件嵌套的跨组件通信问题
  • vuex 作为数据存储中心 vuex 的 State 在单页应用的开发中本身具有一个“数据库”的作用,可以将组件中用到的数据存储在 State 中,并在 Action 中封装数据读写的逻辑。这时候存在一个问题,一般什么样的数据会放在 State 中呢? 目前主要有两种数据会使用 vuex 进行管理: 1、组件之间全局共享的数据 2、通过后端异步请求的数据 比如做加入购物车、登录状态等都可以使用Vuex来管理数据状态

一般面试官问到这里vue基本知识就差不多了, 如果更深入的研究就是和你探讨关于vue的底层源码;或者是具体在项目中遇到的问题,下面列举几个项目中可能遇到的问题:

  • 开发时,改变数组或者对象的数据,但是页面没有更新如何解决?
  • vue弹窗后如何禁止滚动条滚动?
  • 如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件

computed:

  • computed是计算属性,也就是计算值,它更多用于计算值的场景
  • computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算 computed适用于计算比较消耗性能的计算场景

watch:

  • 更多的是「观察」的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作
  • 无缓存性,页面重新渲染时值不变化也会执行

小结:

  • 当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed
  • 如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化

利用Object.defineProperty劫持对象的访问器,在属性值发生变化时我们可以获取变化,然后根据变化进行后续响应,在vue3.0中通过Proxy代理对象进行类似的操作。


  • 在自身实例化时往属性订阅器 () 里面添加自己
  • 待属性变动 通知时,调用自身的 方法,并触发 中绑定的回调

Vue3.x响应式数据原理

改用P替代。因为P可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。

只会代理对象的第一层,那么又是怎样处理这个问题的呢?

判断当前返回值是否为,如果是则再通过方法做代理, 这样就实现了深度观测。

监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?

我们可以判断是否为当前被代理对象自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行

本质上是语法糖,在内部为不同的输入元素使用不同的属性并抛出不同的事件

  • 和 元素使用 value 属性和 input 事件
  • 和 使用 checked 属性和 change 事件
  • 字段将 value 作为 prop 并将 change 作为事件

所以我们可以v-model进行如下改写:


  • 这个语法糖必须是固定的,也就是说属性必须为,方法名必须为:。
  • 知道了的原理,我们可以在自定义组件上实现

虽然避免了组件间样式污染,但是很多时候我们需要修改组件中的某个样式,但是又不想去除属性

  1. 使用

  1. 使用两个style标签

  • 获取元素
  • 获取子组件中的
  • 调用子组件中的方法
  1. 当页面中有某些数据依赖其他数据进行变动的时候,可以使用计算属性computed
  • : 即将要进入的目标(路由对象)
  • : 当前导航正要离开的路由
  • : 一定要调用该方法来 这个钩子。(一定要用这个函数才能去到下一个路由,如果不用就拦截)
  • 执行效果依赖 next 方法的调用参数。
  • : 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
  • :取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)

路由独享的守卫 你可以在路由配置上直接定义 守卫


组件内的守卫你可以在路由组件内直接定义以下路由导航守卫


  • :阻止事件的冒泡
  • :阻止事件的默认行为
  • :只触发一次
  • :只触发自己的事件行为时,才会执行
  • 不要在模板里面写过多表达式
  • 循环调用子组件时添加key
  • 频繁切换的使用v-show,不频繁切换的使用v-if
  • 尽量少用float,可以用flex
  • 按需加载,可以用require或者import()按需加载需要的组件
  • 路由懒加载
  • 是构造一个组件的语法器。 然后这个组件你可以作用到Vue.component这个全局注册方法里还可以在任意vue模板里使用组件。 也可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件。
  • 你可以创建 ,也可以取组件。
  • 减少入口文件体积
  • 静态资源本地缓存
  • 开启Gzip压缩
  • 使用SSR,nuxt.js

当时的思路是头部(Header)一般分为左、中、右三个部分,分为三个区域来设计,中间为主标题,每个页面的标题肯定不同,所以可以通过vue props的方式做成可配置对外进行暴露,左侧大部分页面可能都是回退按钮,但是样式和内容不尽相同,右侧一般都是具有功能性的操作按钮,所以左右两侧可以通过vue slot插槽的方式对外暴露以实现多样化,同时也可以提供default slot默认插槽来统一页面风格

Proxy的优势如下:

  • Proxy可以直接监听对象而非属性
  • Proxy可以直接监听数组的变化
  • Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具备的
  • Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改
  • Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利

Object.defineProperty的优势如下:

  • 任何一个 Vue Component 都有一个与之对应的 Watcher 实例。
  • Vue 的 data 上的属性会被添加 getter 和 setter 属性。
  • 当 Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这一过程被称为依赖收集)
  • data 被改动时(主要是用户操作), 即被写, setter 方法会被调用, 此时 Vue 会去通知所有依赖于此 data 的组件去调用他们的 render 函数进行更新。

现代前端框架有两种方式侦测变化,一种是pull一种是push

  • pull: 其代表为React,我们可以回忆一下React是如何侦测到变化的,我们通常会用setStateAPI显式更新,然后React会进行一层层的Virtual Dom Diff操作找出差异,然后Patch到DOM上,React从一开始就不知道到底是哪发生了变化,只是知道「有变化了」,然后再进行比较暴力的Diff操作查找「哪发生变化了」,另外一个代表就是Angular的脏检查操作。
  • push: Vue的响应式系统则是push的代表,当Vue程序初始化的时候就会对数据data进行依赖的收集,一但数据发生变化,响应式系统就会立刻得知,因此Vue是一开始就知道是「在哪发生变化了」,但是这又会产生一个问题,如果你熟悉Vue的响应式系统就知道,通常一个绑定一个数据就需要一个Watcher,一但我们的绑定细粒度过高就会产生大量的Watcher,这会带来内存以及依赖追踪的开销,而细粒度过低会无法精准侦测变化,因此Vue的设计是选择中等细粒度的方案,在组件级别进行push侦测的方式,也就是那套响应式系统,通常我们会第一时间侦测到发生变化的组件,然后在组件内部进行Virtual Dom Diff获取更加具体的差异,而Virtual Dom Diff则是pull操作,Vue是push+pull结合的方式进行变化侦测的

考点: Vue的变化侦测原理

前置知识: 依赖收集、虚拟DOM、响应式系统

根本原因是Vue与React的变化侦测方式有所不同

  • React是pull的方式侦测变化,当React知道发生变化后,会使用Virtual Dom Diff进行差异检测,但是很多组件实际上是肯定不会发生变化的,这个时候需要用shouldComponentUpdate进行手动操作来减少diff,从而提高程序整体的性能.
  • Vue是pull+push的方式侦测变化的,在一开始就知道那个组件发生了变化,因此在push的阶段并不需要手动控制diff,而组件内部采用的diff方式实际上是可以引入类似于shouldComponentUpdate相关生命周期的,但是通常合理大小的组件不会有过量的diff,手动优化的价值有限,因此目前Vue并没有考虑引入shouldComponentUpdate这种手动优化的生命周期.
  • key是为Vue中的vnode标记的唯一id,通过这个key,我们的diff操作可以更准确、更快速
  • diff算法的过程中,先会进行新旧节点的首尾交叉对比,当无法匹配的时候会用新节点的key与旧节点进行比对,然后超出差异.

diff程可以概括为:oldCh和newCh各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦StartIdx>EndIdx表明oldCh和newCh至少有一个已经遍历完了,就会结束比较,这四种比较方式就是首、尾、旧尾新头、旧头新尾.

  • 合理使用 和
  • 区分 和 的使用
  • 遍历为 添加
  • 遍历避免同时使用
  • 通过 添加的事件在组件销毁时要用 手动移除这些事件的监听
  • 图片懒加载
  • 路由懒加载
  • 第三方插件按需引入
  • 服务端渲染,首屏加载速度快,效果好

Webpack 层面优化:

  • 对图片进行压缩
  • 使用 插件提取公共代码
  • 提取组件的 CSS
  • 优化
  • 构建结果输出分析,利用 可视化分析工具

可以让我们在下次 更新循环结束之后执行延迟回调,用于获得更新后的

主要使用了宏任务和微任务。根据执行环境分别尝试采用

  • 如果以上都不行则采用

定义了一个异步方法,多次调用会将方法存入队列中,通过这个异步方法清空当前队列

使用了函数劫持的方式,重写了数组的方法,将中的数组进行了原型链重写,指向了自己定义的数组原型方法。这样当调用数组api时,可以通知依赖更新。如果数组中包含着引用类型,会对数组中的引用类型再次递归遍历进行监控。这样就实现了监测数组变化。

接口请求一般放在中,但需要注意的是服务端渲染时不支持,需要放到中

一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。如果是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间d不冲突,data必须是一个函数

本质就是一个语法糖,可以看成是方法的语法糖。 可以通过属性的和属性来进行自定义。原生的,会根据标签的不同生成不同的事件和属性

原生事件绑定是通过绑定给真实元素的,组件事件绑定是通过自定义的实现的

简单说,的编译过程就是将转化为函数的过程。会经历以下阶段:

  • 生成树

  • 优化

  • 首先解析模版,生成语法树(一种用J对象的形式来描述整个模板)。 使用大量的正则表达式对模板进行解析,遇到标签、文本的时候都会执行对应的钩子进行相关处理。

  • 的数据是响应式的,但其实模板中并不是所有的数据都是响应式的。有一些数据首次渲染后就不会再变化,对应的DOM也不会变化。那么优化过程就是深度遍历AST树,按照相关条件对树节点进行标记。这些被标记的节点(静态节点)我们就可以跳过对它们的比对,对运行时的模板起到很大的优化作用。

  • 编译的最后一步是将优化后的树转换为可执行的代码

简单来说,算法有以下过程

  • 同级比较,再比较子节点

  • 先判断一方有子节点一方没有子节点的情况(如果新的没有子节点,将旧的子节点移除)

  • 比较都有子节点的情况(核心)

  • 递归比较子节点

  • 正常两个树的时间复杂度是,但实际情况下我们很少会进行跨层级的移动,所以将进行了优化,从,只有当新旧都为多个子节点时才需要用核心的算法进行同层级比较。

  • 的核心算法采用了双端比较的算法,同时从新旧的两端开始进行比较,借助值找到可复用的节点,再进行相关操作。相比的算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅

  • 在创建时就确定其类型,以及在的过程中采用位运算来判断一个的类型,在这个基础之上再配合核心的算法,使得性能上较有了提升

  • 由于在浏览器中操作是很昂贵的。频繁的操作,会产生一定的性能问题。这就是虚拟Dom的产生原因
  • 本质就是用一个原生的JS对象去描述一个节点。是对真实DOM的一层抽象
  • 映射到真实DOM要经历的、、等阶段

key的作用是尽可能的复用 DOM 元素

  • 新旧 中的节点只有顺序是不同的时候,最佳的操作应该是通过移动元素的位置来达到更新的目的
  • 需要在新旧 的节点中保存映射关系,以便能够在旧 的节点中找到可复用的节点。也就是中节点的唯一标识
  • 组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。
  • 组件的销毁操作是先父后子,销毁完成的顺序是先子后父。

加载渲染过程

->->->->->- >->

子组件更新过程

->->->

父组件更新过程

->

销毁过程

->->->

也就是服务端渲染,也就是将在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端

有着更好的、并且首屏加载速度更快等优点。不过它也有一些缺点,比如我们的开发条件会受到限制,服务器端渲染只支持和两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于的运行环境。还有就是服务器会有更大的负载需求

编码阶段

  • 尽量减少中的数据,中的数据都会增加和,会收集对应的
  • 和不能连用
  • 如果需要使用给每项元素绑定事件时使用事件代理
  • 页面采用缓存组件
  • 在更多的情况下,使用替代
  • 保证唯一
  • 使用路由懒加载、异步组件
  • 防抖、节流
  • 第三方模块按需导入
  • 长列表滚动到可视区域动态加载
  • 图片懒加载

SEO优化

  • 预渲染
  • 服务端渲染

打包优化

  • 压缩代码
  • 使用加载第三方模块
  • 多线程打包
  • 抽离公共文件
  • 优化

用户体验

  • 骨架屏

还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启压缩等。

  • 简洁:页面由模板+Json数据+实例组成
  • 数据驱动:自动计算属性和追踪依赖的模板表达式
  • 组件化:用可复用、解耦的组件来构造页面
  • 轻量:代码量小,不依赖其他库
  • 快速:精确有效批量DOM更新
  • 模板友好:可通过npm,bower等多种方式安装,很容易融入
  • 文件夹是放静态资源;
  • 是放组件;
  • 是定义路由相关的配置;
  • 视图;
  • 是一个应用主组件;
  • 是入口文件
  • 使用方法传入的参数使用接受
  • 使用方式传入的参数使用接受
  • 是一个专为 应用程序开发的状态管理模式。
  • 有 5 种,分别是 、、、、
  • 是一个专为 应用程序开发的状态管理模式。
  • 有 5 种,分别是 、、、、
  • 的 是什么?
  • 就是一个仓库,仓库里放了很多对象。其中 就是数据源存放地,对应于一般 vue 对象里面的 里面存放的数据是响应式的, 组件从 读取数据,若是 中的数据发生改变,依赖这相数据的组件也会发生更新它通过 把全局的 和 映射到当前组件的 计算属性

vuex 的 getter 是什么?

  • 可以对 进行计算操作,它就是 的计算属性虽然在组件内也可以做计算属性,但是 可以在多给件之间复用如果一个状态只在一个组件内使用,是可以不用

vuex 的 mutation 是什么?

  • 更改的中的状态的唯一方法是提交

vuex 的 action 是什么?

  • 类似于 , 不同在于: 提交的是 ,而不是直接变更状态 可以包含任意异步操作
  • 中 请求代码应该写在组件的 中还是 的 中
  • 的 是什么?

面对复杂的应用程序,当管理的状态比较多时;我们需要将的对象分割成模块()。

如果请求来的数据不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入 的 里如果被其他地方复用,请将请求放入 里,方便复用,并包装成 返回

将当前组件的修改为

  • 只是被删除的元素变成了 其他的元素的键值还是不变。
  • 直接删除了数组 改变了数组的键值。

可以


v-on 常用修饰符

  • 该修饰符将阻止事件向上冒泡。同理于调用 方法
  • 该修饰符会阻止当前事件的默认行为。同理于调用 方法
  • 该指令只当事件是从事件绑定的元素本身触发时才触发回调
  • 该修饰符表示绑定的事件只会被触发一次
  • 第一种方法是直接在子组件中通过来调用父组件的方法
  • 第二种方法是在子组件里用向父组件触发一个事件,父组件监听这个事件就行了。

babel-polyfill插件

以下方法调用会改变原始数组:, , , , , , ,

  • 调用方法:
    • :要更改的数据源(可以是对象或者数组)
    • :要更改的具体数据
    • :重新赋的值

注意 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 替换掉


  • : 可以在这加个事件,在加载实例时触发
  • : 初始化完成时的事件写在这里,如在这结束事件,异步请求也适宜在这里调用
  • : 挂载元素,获取到DOM节点 : 如果对数据统一处理,在这里写上相应函数
  • : 可以做一个确认停止事件的确认框

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

会触发 , , ,

, 变量

本文地址:http://changmeillh.xhstdz.com/quote/66452.html    物流园资讯网 http://changmeillh.xhstdz.com/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


0相关评论
相关最新动态
推荐最新动态
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号