Vue面试题以及实际项目中遇到的坑

写在前面


以前有提到,在经历了前端转型以后,一场技术变革的到来,小程序,h5移动端,对性能优化的要求愈来愈高,受面向对象思想编程方式的影响,前端如今主流的技术框架就是Vue,React,Angular.他们的数据驱动模式,MVVM模式,很受欢迎,这种spa单页面应用,组件思惟对一个庞大的web应用颇有帮助提高加载速度,减小Dom操做,随之而来的也就是不断地学习,对技术员的技术要求也开始偏向于vue,小程序,公众号,因为智能手机的普及,app端比网页更受欢迎,因此就要不断地学习新的知识,不然会被淘汰。前端


好了,不说废话了,总结一下使用vue开发项目过程当中遇到的坑以及面试经验。vue

这里关于v-model原理的仅限于vue3.0如下版本,据说vue3.0不在采用Object.defineProperty,具体的还有待学习,完了了解了再来更新。git

step一,谈谈你对MVVM 的理解?

  • MVVM 由 Model,View,ViewModel 三部分构成,Model 层表明数据模型,也能够在Model中定义数据修改和操做的业务逻辑;View 表明UI 组件,它负责将数据模型转化成UI 展示出来,ViewModel 是一个同步View 和 Model的对象。 在MVVM架构下,View 和 Model 之间并无直接的联系,而是经过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 所以View 数据的变化会同步到Model中,而Model 数据的变化也会当即反应到View 上。 ViewModel 经过双向数据绑定把 View 层和 Model 层链接了起来,而View 和 Model 之间的同步工做彻底是自动的,无需人为干涉,所以开发者只需关注业务逻辑,不须要手动操做DOM, 不须要关注数据状态的同步问题,复杂的数据状态维护彻底由 MVVM 来统一管理。

step二,vue路由传参的方式

\color{red}{回答关键字}

step三,vue组件之间的传参

\color{red}{回答关键字}

step四,vue-router有哪几种导航钩子?

答案github

  • 第一种是全局导航钩子(全局守卫):router.beforeEach(to,from,next),做用:跳转前进行判断拦截。
  • 第 二种:全局解析守卫router.beforeResolve,在导航被确认前,全部组件内守卫和异步路由组件被解析以后,解析守卫就被调用。(2.5.0新增)。
  • 第三种:单独路由独享的守卫beforeEnter,在路由配置时定义,与全局守卫的方法是同样的。
  • 第四种:组件内的守卫。直接在路由组件内定义守卫, 如下为官网文档的介绍:
beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 由于当守卫执行前,组件实例还没被建立
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,可是该组件被复用时调用
    // 举例来讲,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 因为会渲染一样的 Foo 组件,所以组件实例会被复用。而这个钩子就会在这个状况下被调用。
    // 能够访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 能够访问组件实例 `this`
  }
复制代码

step五,请写出几种经常使用的vue指令

v-once、v-for、v-if、v-show、v-on,v-model
复制代码

step六,请详细解释一下vue(2.0)的生命周期?

答案:web

生命周期 阶段 描述
beforeCreated 建立前 vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
created 建立后 vue实例的数据对象data有了,$el尚未。
beforeMount 模板载入前 vue实例的$el和data都初始化了,但仍是挂载以前为虚拟的dom节点,data.message还未替换
mounted 模板载入后 vue实例挂载完成,data.message成功渲染。
beforeUpdate 组件更新前 组件更新以前调用
updated 组件更新后 组件更新以后调用
beforeDestroy 组件销毁前 调用$destroy方法后,当即执行beforeDestroy
pdestroyed 组件销毁后 组件销毁后调用,此时只剩下dom空壳

step七,slot是什么?并说一下详细的用法?

答案: vue官网解释:slot 插槽,-------(Vue 实现了一套内容分发的 API,这套 API 基于当前的 Web Components 规范草案,将 <slot> 元素做为承载分发内容的出口。 )是否是看完稀里糊涂的,反正我是稀里糊涂的,再来讲说我本身的理解: slot就是为了实现真正的灵活的单页组件,在组件外部灵活控制组件内部的内容一种形式或者是入口,就是将组件内所须要的内容以插槽(slot)的形式插入到公共组件中,以达到灵活控制。 当组件渲染的时候,这个 元素将会被替换为“Your Profile”。插槽内能够包含任何模板代码,包括 HTML:详情请看vue 带动画效果的NavBar这里边有详细介绍到<slot>的使用方法。面试

step八,谈谈你对vue响应式原理的理解?

答案: 先看看官网的解释: 当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象全部的属性,并使用 Object.defineProperty 把这些属性所有转为 getter/setter。Object.defineProperty 是 ES5 中一个没法 shim 的特性,这也就是为何 Vue 不支持 IE8 以及更低版本浏览器的缘由。vue-router

这些 getter/setter 对用户来讲是不可见的,可是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。这里须要注意的问题是浏览器控制台在打印数据对象时 getter/setter 的格式化并不一样,因此你可能须要安装 vue-devtools 来获取更加友好的检查接口。vuex

每一个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程当中把属性记录为依赖,以后当依赖项的 setter 被调用时,会通知 watcher 从新计算,从而导致它关联的组件得以更新。vue-cli

这里特别说明一下npm

其实看过api,源码的人就不难知道,v-model,响应式原理共分为两层

第一层,底层,就是es5的一个特性Object.defineProperty经过getter,setter更新数据, 第二层,表现层,看过v-model原理的人都知道,v-model里边有一个watcher,v-onwatcher监听到数据变化,v-on更新到视图中,相信好多人在实战中都用过v-on来更新数据。

step九,直接对对象属性进行添加和删除会不会直接响应到视图中?也就是说数组的更新方法?并说明缘由?

答案: 直接对对象属性进行添加和删除是不会响应到视图中的,须要用到this.$set()方法 举个例子

var vm = new Vue({
  data:{
      myjson:{
    name:"张三"     
}
  }
})
vm.myjson.age= "12";    //这样直接对对象属性进行增长是不会直接响应到视图中的。
须要这么写:
this.$set(this.myjson,'age',12);//才会生效
复制代码

缘由 受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。因为 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,因此属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

step十,如何建立一个公共的全局组件,并在每一个页面中调用以及如何建立并调用公共的方法?

答案: \color{red}{回答关键字} 将建立好的组件或者js方法导出并挂载到vue实例上。 详情请参考关于vue全局引用公共的js和公共的组件的折腾

step十一,请说明v-ifv-show的异同?

同:二者都是达到显示隐藏的功能 异:

  • v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果
  • v-show指令经过修改元素的display属性让其显示或者隐藏

step十二,<keep-alive></keep-alive>的做用是什么?

答案: <keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免从新渲染。 用本身的理解说 好比有一个列表和一个详情,那么用户就会常常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就能够对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是从新渲染,这样就会减轻服务器压力,提升性能。

step十三,<router-link>属性以及方法?

答案:

  • :to 至关于a标签中的"herf"属性,后面跟跳转连接所用 ,会渲染成a标签--
<router-link :to="/home">Home</router-link>
<!-- 渲染结果 -->
<a href="/home">Home</a>
复制代码
  • replace属性,加上该属性页面切换不会留下历史纪录。
<router-link :to="/home" replace></router-link>
复制代码
  • tag属性,具备tag属性的router-link会被渲染成相应的标签
<router-link :to="/home" tag="li">Home</router-link>
<!-- 渲染结果 -->
<li>Home</li>
此时页面的li一样会起到a连接跳转的结果,vue会自动为其绑定点击事件,并跳转页面
复制代码
  • active-class属性:设置连接激活时的class属性:默认值为router-link-active,因此若是没有设置,就会被渲染为这个class,咱们能够在router.js里边配置这个属性
const router = new VueRouter({
  mode: 'hash',
  linkActiveClass: 'u-link--Active', // 这是连接激活时的class
})
<router-link :to="/home" active-class="u-link--Active">Home</router-link>
复制代码
  • exact属性:严格模式
// 这个连接只会在地址为 / 的时候被激活 
<router-link to="/" exact>Home</router-link>

<router-link to="/user">USER</router-link>

<router-link to="/user/userinfo">USER-info</router-link>

// 若是不设置exact,则当路由到了/user/userinfo 页面时,USER也是被设置了router-link-active样式的!
复制代码
  • 方法:
router-link默认是触发router.push(location),若是设置的replace 则触发router.replace(location),这有啥区别呢?
&emsp;&emsp;router.push() :导航跑到不一样的URL,这个方法会向history栈添加一个新的记录,因此,当用户点击浏览器后退按钮时,则回到以前的url.
&emsp;&emsp;router.replace(): 跟router.push做用是同样的,可是,它不会向history添加新记录,而是跟它的方法名同样替换掉当前的history记录.
&emsp;&emsp;router.go(n): 这个方法的参数是一个整数,意思是在history记录中向前或者后退多少步,相似window.history.go(n)
复制代码

step十四,v-once的做用和用法?

只渲染元素和组件一次,随后的渲染,使用了此指令的元素/组件及其全部的子节点,都会看成静态内容并跳过,这能够用于优化更新性能。 举个例子:一看便知

<template>
  <div>
    <div>{{count}}</div>
    <button v-on:click="addCount">改变count的值</button>
  </div>
</template>
<script>
  export default {
    name: "VueOnce",
    data() {
      return {
        count: "我是不可改变的"
      }
    },
    methods: {
      addCount: function () {
        this.count = "我就要改变你";
       此时这个操做dom里边的count是不会变化的
      }
    }
  }
</script>
<style scoped>
</style>
复制代码

step十五,如何解决在加载页面时出现的闪烁问题。

v-cloak详情请移步v-cloak详解

step十六,vue如何兼容ie的问题。

答案: 回答关键字 - babel-polyfill插件 详情请移步vue-cli 解决ie兼容性问题

step十七,vue-cli如何解决跨域?

答案:常见的后台加请求头以及jsonp就不详细解释了,若要看详细教程请移步前端面试题总结。 这里主要介绍的是 npm模块之http-proxy-middleware的解决跨域的办法。详情移步vue-cli如何解决跨域

step十八,vue如何在父组件中调用子组件的方法。

答案: 回答关键字 - ref 详情请移步vue如何在父组件中调用子组件的方法

step十九,谈谈你对minxins混入的理解以及使用方法

详情请移步深刻浅出之vue-cli混入(mixins)的理解和使用

step 二十,谈谈你对watch(侦听器)和 computed (计算属性)理解以及两者的区别。

详情请移步vue watch - 侦听器和computed - 计算属性 的理解和使用

相关文章
相关标签/搜索