VUE 简单面试题

1.MVC 与 MVVM的区别

MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范

  • Model(模型):是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据
  • View(视图):是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的
  • Controller(控制器):是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据

几乎所有的App都只干这么一件事:将数据展示给用户看,并处理用户对界面的操作。MVC的思想:一句话描述就是Controller负责将Model的数据用View显示出来,换句话说就是在Controller里面把Model的数据赋值给View。

MVVM

MVVM:Model、View、ViewModel。

你会下意识地把它和MVC来对比,你会发现,MVVM多了一个ViewModel而少了Controller。

首先说一下多出来的ViewModel(VM,不是显存)。VM的意义,和Model一样,在于数据。Model负责对数据进行取和存,然而我们对数据的操作除了取和存以外,还有一个非常重要的操作:解析

M:对应于MVC的M

V:对应于MVC的V

VM:ViewModel,是把MVC里的controller的数据加载,加工功能分离出来

区别

MVVM 与 MVC 最大的区别就是:它实现了 View 和 Model 的自动同步,也就是当 Model 的属性改变时,我们不用再自己手动操作 Dom 元素,来改变 View 的显示,而是改变属性后该属性对应 View 层显示会自动改变(对应Vue数据驱动的思想)

Vue 并没有完全遵循 MVVM 的思想

这一点Vue官网自己也有说明,因为从严格意义上来讲,MVVM要求View与Model是不能直接通信的,而 Vue 提供了$refs 这个属性,让 Model 可以直接操作 View,违反了这一规定,所以说 Vue 没有完全遵循 MVVM。

2.为什么data需要是一个函数?

这个说法主要是在组件中出现,因为组件是可以复用的,js里对象是引用关系,如果组件data是一个对象,那么子组件中的data 属性值会相互污染,产生副作用。如果组件中 data 选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响;而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。

3.v-if与v-show

v-if与v-show的区别

「v-if」 是「真正」的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是「惰性的」:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

「v-show」 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。

所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。

v-show指令算是重排吗?

v-show本质是通过元素css的display属性来控制是否显示,在DOM渲染时仍然会先渲染元素,然后才会进行判断是否显示(通过display属性),而对于重排的定义是渲染树中的节点信息发生了大小、边距等改变,要重新计算各节点和css具体的大小和位置。当用display来控制元素的显示和隐藏时,会改变节点的大小和渲染树的布局,导致发生重排,因此v-show指令算是重排。

4.v-if 与 v-for 为什么不建议一起使用?

首先,关于v-if和v-for的优先级,可以在源码compiler/codegen/index.js中找到genElement方法,里面的if else判断,可以清楚看到for的判断在if判断之上,由此,可证明v-for的优先级高于v-if

如果v-if和v-for同时出现,分两种情况:

  • 当同时出现在同一标签内,可以通过vue.$options.render打印出渲染函数,可以清晰的看到会优先执行for循环,再执行if判断
  • 当v-if出现在父级中,子级有v-for,此时再打印vue.$options.render,会发现会优先执行if判断。

若想优化,提升性能,v-if需要优先执行,可以在v-for外层加一层template搭配v-if使用。若是v-if与v-for必须出现在同一层或v-if为v-for的子级的情况下,优化的方式可以将for循环的数组提前通过计算属性处理,尽量减少过多渲染导致的性能消耗。

v-for中的key有什么作用?为什么在v-for中的key不推荐使用随机数或者index?

「key的作用:」可以使vue的diff操作更加准确和快速

如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速

「更准确」:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。

「更快速」:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快

「为什么在v-for中的key不推荐使用随机数或者index?」

因为在插入数据或者删除数据的时候,会导致后面的数据的key绑定的index变化,进而导致重新渲染,效率会降低,同时也会导致渲染出错;当数据进行更改的时候,会通过key来判断虚拟dom树是否进行了更改。如果发现了相同的dom-key就可以直接复用。减少了渲染的性能损耗。所以使用随机数或index作为key会导致性能浪费,并且使用index作为key可能会导致渲染出错。

v-for遍历对象时,是按什么顺序遍历的?如何保证顺序?

1、会先判断是否有iterator接口,如果有循环执行next()方法

2、没有iterator的情况下,会调用Object.keys()方法,在不同浏览器中,JS引擎不能保证输出顺序一致

3、保证对象的输出顺序可以把对象放在数组中,作为数组的元素

vue 几种常用组件通讯

props/$emit

  • props 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且是 props 只读的,不可被修改,所有修改都会失效并警告。
  • $emit绑定一个自定义事件, 当这个语句被执行时, 就会将参数传递给父组件,父组件通过v-on监听并接收参数。

$parent/$Children

从上面详细中我们可以知道,通过$parent和$children就可以访问到对应组件的实例,既然都访问到组件实例了,那么组件内的所有内容(data、methods等)就都能够访问到了。

ref

如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例

provide/inject

provide/ inject 是vue2.2.0新增的api, 简单来说就是父组件中通过provide来提供变量, 然后再子组件中通过inject来注入变量。并且不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据

eventBus

eventBus 又称为事件总线,在vue中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。使用$on订阅事件,$emit发布事件

$attrs/$listeners

如果遇到跨级组件使用props与emit来通信的话,那么就需要将数据与事件一层一层往下传递,这样做太麻烦了。所以在vue2.4中,为了解决该需求,引入了$attrs 和$listeners , 新增了inheritAttrs 选项。在版本2.4以前,默认情况下,父作用域中不作为 props 被识别 (且获取) 的特性绑定 (class 和 style 除外),将会“回退”且作为普通的HTML特性应用在子组件的根元素上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值