Vue面试题

140 阅读2分钟

Vue面试

  1. 对于MVVM的理解

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 也会自动变化。

  1. 开发中常用的指令有哪些
  • v-model:一般用在表单输入,很轻松的实现表单控件和数据的双向绑定
  • v-html:更新元素的innerHTML
  • v-show 与 v-if:条件渲染,注意二者区别
    • 使用了v-if 的时候,如果值为false,那么页面将不会有这个html 标签生成。
    • v-show 则是不管值为true 还是false,html 元素都会存在,只是CSS 中的display 显示或隐藏
  • v-on:click:可以简写为@click,@绑定一个事件。如果事件触发了,就可以指定事件的处理函数
  • v-for:基于源数据多次渲染元素或模板块
  • v-bind:当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM
    • v-bind:title="msg" 简写 :title="msg"
  1. 请详细说下你对vue生命周期的理解

vue生命周期总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后

  • beforeCreate(创建前)vue 实例的挂载元素$el 和数据对象data 都是undefined,还未初始化
  • created(创建后)完成了data 数据初始化,el 还未初始化
  • beforeMount(载入前)vue 实例的$el 和data 都初始化了,相关的reader 函数首次被调用。实例已完成以下的配置:编译模板,把data 里面的数据和模板生成html。注意此时还没有挂载html 到页面上
  • mounted(载入后)在el 被新创建的vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html 内容替换el 属性指向DOM 对象。完成模板中的html 渲染到html 页面中。此过程中进行ajax 交互
  • beforeUpdate(更新前)在数据更新之前调用,发生在虚拟DOM 重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程
  • updated(更新后)在由于数据更新导致的虚拟DOM 重新渲染和打补丁之后调用。调用时,组件DOM 已经更新,所以可以执行依赖于DOM 的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务端渲染期间不被调用
  • beforeDestroy(销毁前)在实例销毁之前调用。实例仍然完全可用
  • destroyed(销毁后)在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用
  1. vue的双向数据绑定原理是什么

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

具体实现步骤:

  • 当把一个普通JavaScript 对象传给vue 实例来作为它的data 选项时,vue 将遍历它的属性,用Object.defineProperty 都加上setter 和getter 这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到数据变化
  • compile(编译)解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
  • watcher 订阅者是Observer 和Compile 之间通信的桥梁,主要做的事情是:1. 在自身实例化往属性订阅器(dep)里面添加自己,2. 自身必须有一个update() 方法,并触发Compile 中绑定的回调,则功成身退
  • MVVM 作为数据绑定的入口,整合Observer、Compile 和Watcher 三者,通过Observer 来监听自己的model数据变化,通过Compile 来解析编译模板指令,最终利用Watcher 搭起Obserer 和Compile 之间的通信桥梁,达到数据变化 ---> 视图更新;视图交互变化(input)---> 数据model 变更的双向绑定效果

列举项目中遇到的问题

  • 开发时,改变数组或对象的数据,但是页面没有更新如何解决 为什么? 因为vue实现双向数据绑定的机制是数据劫持,也就是在所有对象上有个Object.defineProperty() 方法,通过监听set、get方法去实现,而数组没有这两个方法,所以就不会更新view。 解决方案就是:需要我们主动通知vue

    在vm实例上通知

    vm.set(数组,索引,改变值) 或 vm.set(对象,属性名,改变值)

    在全局对象上通知

    Vue.set(数组,索引,改变值) 或 Vue.set(对象,属性名,改变值)

    vue本身可以监听到数组的一些方法,例如

    // push()、pop()、shift()、unshift()、splice()、sort()、reverse() 数组.splice(3,1,'')

  • this.forceUpdate()
vue项目中使用this.forceUpdate() 解决页面v-for 中修改item属性值后页面v-if不改变的问题 数据层次太多,render函数没有自动更新,需手动强制刷新

  • this.$nextTick() 将回调延迟到下次DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待DOM更新