前端框架vue-5

1.30 双向数据绑定原理

参考答案:

目前几种主流的mvc(vm)框架都实现了单向数据绑定,而我所理解的双向数据绑定无非就是在单向绑定的基础上给可输入元素(input、textare等)添加了change(input)事件,来动态修改model和 view,并没有多高深。所以无需太过介怀是实现的单向或双向绑定。

实现数据绑定的做法有大致如下几种:

发布者-订阅者模式: 一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set('property', value),这里有篇文章讲的比较详细,有兴趣可点这里

这种方式现在毕竟太low了,我们更希望通过 vm.property = value这种方式更新数据,同时自动更新视图,于是有了下面两种方式

脏值检查: angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过 setInterval() 定时轮询检测数据变动,当然Google不会这么low,angular只有在指定的事件触发时进入脏值检测,大致如下:

  • DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
  • XHR响应事件 ( $http )
  • 浏览器Location变更事件 ( $location )
  • Timer事件( timeout ,)interval )
  • 执行 digest() 或)%20%E6%88%96)apply()

数据劫持: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调。

1.31 既然 Vue 通过数据劫持可以精准探测数据在具体dom上的变化,为什么还需要虚拟 DOM diff 呢?

参考答案

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

现代前端框架有两种方式侦测变化,一种是 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双向数据绑定的原理如下图)

[vue 双向数据绑定原理

一但我们的绑定细粒度过高就会产生大量的Watcher,这会带来内存以及依赖追踪的开销,而细粒度过低会无法精准侦测变化,因此Vue的设计是选择中等细粒度的方案,在组件级别进行push侦测的方式,也就是那套响应式系统,通常我们会第一时间侦测到发生变化的组件,然后在组件内部进行Virtual Dom Diff获取更加具体的差异,而Virtual Dom Diff则是pull操作,Vue是push+pull结合的方式进行变化侦测的。

1.32 简单聊聊 new Vue 以后发生的事情

参考答案

  1. new Vue 会调用 Vue 原型链上的 _init 方法对 Vue 实例进行初始化;
  2. 首先是 initLifecycle 初始化生命周期,对 Vue 实例内部的一些属性(如 children、parent、isMounted)进行初始化;
  3. initEvents,初始化当前实例上的一些自定义事件(Vue.$on);
  4. initRender,解析 slots 绑定在 Vue 实例上,绑定 createElement 方法在实例上;
  5. 完成对生命周期、自定义事件等一系列属性的初始化后,触发生命周期钩子 beforeCreate
  6. initInjections,在初始化 dataprops 之前完成依赖注入(类似于 React.Context);
  7. initState,完成对 dataprops 的初始化,同时对属性完成数据劫持内部,启用监听者对数据进行监听(更改);
  8. initProvide,对依赖注入进行解析;
  9. 完成对数据(state 状态)的初始化后,触发生命周期钩子 created
  10. 进入挂载阶段,将 vue 模板语法通过 vue-loader 解析成虚拟 DOM 树,虚拟 DOM 树与数据完成双向绑定,触发生命周期钩子 beforeMount
  11. 将解析好的虚拟 DOM 树通过 vue 渲染成真实 DOM,触发生命周期钩子 mounted

1.33 v-for中的key的理解?

参考答案

需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。主要是为了高效的更新虚拟DOM。

1.34 vue首屏白屏如何解决?

参考答案

  1. 路由懒加载
  2. vue-cli开启打包压缩 和后台配合 gzip访问
  3. 进行cdn加速
  4. 开启vue服务渲染模式
  5. 用webpack的externals属性把不需要打包的库文件分离出去,减少打包后文件的大小
  6. 在生产环境中删除掉不必要的console.log
plugins: [
    new webpack.optimize.UglifyJsPlugin({ //

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

前端岗位面试真题宝典 文章被收录于专栏

本面试宝典均来自校招面试题目大数据进行的整理

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务