>首页> IT >

全球热推荐:【吐血整理】Vue.js面试题汇总及答案解析(快来收藏)

时间:2022-07-07 05:50:47       来源:转载
本篇文章给大家总结分享一些Vue面试题(附答案解析),带你梳理基础知识,增强Vue知识储备,值得收藏,快来看看吧!

(学习视频分享:vue视频教程)

一、Vue.js基本问题

1.1.Vue 响应式原理

1.2.Vue.js 的特点

1.3. Vue.js 双向绑定的原理

Vue.js 3.0, 放弃了Object.defineProperty ,使用更快的ES6原生 Proxy (访问对象拦截器, 也称代理器)


【资料图】

步骤:

1.4.Vue中如何监控某个属性值的变化?

比如现在需要监控data中, obj.a 的变化。Vue中监控对象属性的变化你可以这样:

watch: {      obj: {      handler (newValue, oldValue) {        console.log("obj changed")      },      deep: true    }

deep属性表示深层遍历,但是这么写会监控obj的所有属性变化,并不是我们想要的效果,所以做点修改:

watch: {   "obj.a": {      handler (newName, oldName) {        console.log("obj.a changed")      }   }  }

还有一种方法,可以通过computed 来实现,只需要:

computed: {    a1 () {      return this.obj.a          }}

利用计算属性的特性来实现,当依赖改变时,便会重新计算一个新值。

1.5.Vue.js 3.0 放弃defineProperty, 使用Proxy的原因

Object.defineProperty缺陷

1.6.Vue 2 中给 data 中的对象属性添加一个新的属性时会发生什么?如何解决?

视图并未刷新。这是因为在Vue实例创建时,新属性并未声明,因此就没有被Vue转换为响应式的属性,自然就不会触发视图的更新,这时就需要使用Vue的全局 api $set():

this.$set(this.obj, "new_property", "new_value")

1.7.Computed和Watch的区别及运用场景

运用场景:

1.8. Computed 和 Methods 的区别

1.9.虚拟DOM,diff算法

1.10.为何需要Virtual DOM?

1.11.过滤器 (Filter)

1.12.常见的事件修饰符及其作用

1.13.v-show指令和v-if指令的区别是什么?

1.14.v-model 是如何实现的,语法糖实际是什么

作用在表单元素上v-model="message"等同于v-bind:value=“message” v-on:input="message=e v e n t . t a r g e t . v a l u e " 作 用 在 组 件 上 , 本 质 是 一 个 父 子 组 件 通 信 的 语 法 糖 ,通过prop和.emit实现, 等同于:value="message" @input=" $emit("input", $event.target.value)"

1.15.data为什么是一个函数而不是对象

1.16.Vue template 到 render 的过程

1.17.Vue template 到 render 的过程

1.18.axios是什么

易用、简洁且高效的http库, 支持node端和浏览器端,支持Promise,支持拦截器等高级配置。

1.19.sass是什么?如何在vue中安装和使用?

sass是一种CSS预编译语言安装和使用步骤如下。

1.20.Vue.js页面闪烁

Vue. js提供了一个v-cloak指令,该指令一直保持在元素上,直到关联实例结束编译。当和CSS一起使用时,这个指令可以隐藏未编译的标签,直到实例编译结束。用法如下

1.21.如何解决数据层级结构太深的问题

在开发业务时,经常会岀现异步获取数据的情况,有时数据层次比较深,如以下代码: , 可以使用vm.$set手动定义一层数据:

vm.$set("demo",a.b.c.d)

1.22.在 Vue. js开发环境下调用API接口,如何避免跨域

config/ index.js内对 proxyTable项配置代理。

1.23.批量异步更新策略

1.24.vue 的 nextTick 方法的实现原理

1.25.Vue 组件 data 为什么必须是函数 ?

因为组件是可以复用的,JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染。 所以一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。

1.26.v-if和v-for一起使用的弊端及解决办法

由于v-for的优先级比v-if高,所以导致每循环一次就会去v-if一次,而v-if是通过创建和销毁dom元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿,性能下降。

解决办法:

1.27.vue常用指令

1.28. 组件传值方式有哪些

1.30.vue中 key 值的作用

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM

1.31.为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?

Object.defineProperty本身有一定的监控到数组下标变化的能力,但是在 Vue 中,从性能/体验的性价比考虑,尤大大就弃用了这个特性(Vue 为什么不能检测数组变动 )。为了解决这个问题,经过 vue 内部处理后可以使用以下几种方法来监听数组

由于只针对了以上 7 种方法进行了 hack 处理,所以其他数组的属性也是检测不到的,还是具有一定的局限性。

1.32.谈一谈 nextTick 的原理

JS 运行机制

JS 执行是单线程的,它是基于事件循环的。事件循环大致分为以下几个步骤:

主线程的执行过程就是一个 tick,而所有的异步结果都是通过 “任务队列” 来调度。 消息队列中存放的是一个个的任务(task)。 规范中规定 task 分为两大类,分别是 macro task 和 micro task,并且每个 macro task 结束后,都要清空所有的 micro task。

for (macroTask of macroTaskQueue) {  // 1. Handle current MACRO-TASK  handleMacroTask();  // 2. Handle all MICRO-TASK  for (microTask of microTaskQueue) {    handleMicroTask(microTask);  }}

在浏览器环境中 :

常见的 macro task 有 setTimeout、MessageChannel、postMessage、setImmediate

常见的 micro task 有 MutationObsever 和 Promise.then

异步更新队列

vue 的 nextTick 方法的实现原理:

1.33.谈谈 Vue 事件机制,手写on,off,emit,once

Vue 事件机制 本质上就是 一个 发布-订阅 模式的实现。

class Vue {  constructor() {    //  事件通道调度中心    this._events = Object.create(null);  }  $on(event, fn) {    if (Array.isArray(event)) {      event.map(item => {        this.$on(item, fn);      });    } else {      (this._events[event] || (this._events[event] = [])).push(fn);    }    return this;  }  $once(event, fn) {    function on() {      this.$off(event, on);      fn.apply(this, arguments);    }    on.fn = fn;    this.$on(event, on);    return this;  }  $off(event, fn) {    if (!arguments.length) {      this._events = Object.create(null);      return this;    }    if (Array.isArray(event)) {      event.map(item => {        this.$off(item, fn);      });      return this;    }    const cbs = this._events[event];    if (!cbs) {     return this;    }    if (!fn) {      this._events[event] = null;      return this;    }    let cb;    let i = cbs.length;    while (i--) {      cb = cbs[i];      if (cb === fn || cb.fn === fn) {        cbs.splice(i, 1);        break;      }    }    return this;  }  $emit(event) {    let cbs = this._events[event];    if (cbs) {      const args = [].slice.call(arguments, 1);      cbs.map(item => {        args ? item.apply(this, args) : item.call(this);      });    }    return this;  }}

1.34.vue-router有哪几种导航钩子?

三种:

1.35.vuex是什么?怎么使用?哪种功能场景使用它?

1.36.MVVM和MVC区别?和其他框架(jquery)区别?那些场景适用?

1.37.聊聊你对Vue.js的模板编译的理解

简而言之,就是先转化成AST树,再得到的渲染函数返回VNODE(Vue公司的虚拟DOM节点) 详情步骤:

1.38.< keep-alive>< /keep-alive>的作用是什么,如何使用?

答:包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染; 使用:简单页面时 缓存: < keep-alive include=”组件名”>< /keep-alive>不缓存: < keep-alive exclude=”组件名”>< /keep-alive>

1.39.vue和react区别

相同点:都鼓励组件化,都有’props’的概念,都有自己的构建工具,Reat与Vue只有框架的骨架,其他的功能如路由、状态管理等是框架分离的组件。

不同点:React:数据流单向,语法—JSX,在React中你需要使用setState()方法去更新状态。Vue:数据双向绑定,语法–HTML,state对象并不是必须的,数据由data属性在Vue对象中进行管理。适用于小型应用,但对于对于大型应用而言不太适合。

1.40.vue生命周期的理解?

参照大神文章:vue笔记 - 生命周期第二次学习与理解

beforeCreate是new Vue()之后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。

created在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。可以做一些初始数据的获取,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。

beforeMount发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。

mounted在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。

beforeUpdate发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。

updated发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

beforeDestroy发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。

destroyed发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。

1.41.Vue2.x和Vue3.x渲染器的diff算法分别说一下

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

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

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

Vue3.x借鉴了ivi算法和 inferno算法

在创建VNode时就确定其类型,以及在 mount/patch 的过程中采用位运算来判断一个VNode的类型,在这个基础之上再配合核心的Diff算法,使得性能上较Vue2.x有了提升。(实际的实现可以结合Vue3.x源码看。)

该算法中还运用了动态规划的思想求解最长递归子序列。

1.42.你都做过哪些Vue的性能优化?

编码阶段

SEO优化

打包优化

用户体验

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

1.43.hash路由和history路由实现原理说一下

location.hash的值实际就是URL中#后面的东西。

history实际采用了HTML5中提供的API来实现,主要有history.pushState()history.replaceState()

1.44.SPA 单页面的理解,它的优缺点分别是什么

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS 一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转 取而代之的是利用路由机制实现 HTML 内容的变换, UI 与用户的交互,避免页面的重新加载 优点:

缺点:

1.45.vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?

1.46.vue如何实现按需加载配合webpack设置

二、组件 Component

2.1.vue中如何编写可复用的组件 (编写组件的原则)

以组件功能命名 只负责ui的展示和交互动画,不要在组件里与服务器打交道(获取异步数据等) 可复用组件不会因组件使用的位置、场景而变化。尽量减少对外部条件的依赖。

2.2.如何让CSS只在当前组件中起作用?

在每一个Vue.js组件中都可以定义各自的CSS、 JavaScript代码。如果希望组件内写的CSS只对当前组件起作用,只需要在Style标签添加Scoped属性即可

2.3.keep-alive是什么?

如果需要在组件切换的时候,保存一些组件的状态防止多次渲染,就可以使用 keep-alive 组件包裹需要保存的组件。

两个重要属性,include 缓存组件名称,exclude 不需要缓存的组件名称。

2.4.如何在 Vue. js动态插入图片

对“src”属性插值将导致404请求错误。应使用 v-bind:src (简写:src)格式代替。

2.5.父子组件的生命周期顺序(可参照上方图解)

加载渲染过程: 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted子组件更新过程:父beforeUpdate->子beforeUpdate->子updated->父updated父组件更新过程:父beforeUpdate->父updated销毁过程:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

三、Vuex

3.1.vuex的核心概念

3.2.vuex是什么?怎么使用?哪种功能场景使用它?

3.3.多个组件之间如何拆分各自的state,每块小的组件有自己的状态,它们之间还有一些公共的状态需要维护,如何思考这块

3.4.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?

1.如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。

2.如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便

3.5.Vuex中如何异步修改状态

actions与mutations作用类似,都是可以对状态进行修改。不同的是actions是异步操作的。

actions是可以调用Mutations里的方法的。

const actions={addActions(context){context.commit("add",10);//调用mutations中的方法setTimeout(()=>{context.commit("reduce")},5000)//setTimeOut(()=>{context.commit("reduce")},3000);console.log("我比reduce提前执行");},reduceActions({commit}){commit("reduce");}}

3.6.Vuex中actions和mutations的区别

Mutation 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

const store = new Vuex.Store({  state: {    count: 1  },  mutations: {    increment (state) {      // 变更状态      state.count++    }  }})

Action Action 类似于 mutation,不同在于:

Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作

const store = new Vuex.Store({  state: {    count: 0  },  mutations: {    increment (state) {      state.count++    }  },  actions: {    increment (context) {      context.commit("increment")    }  }})

3.7.怎么在组件中批量使用Vuex的state状态?

使用mapState辅助函数, 利用对象展开运算符将state混入computed对象中

import {mapState} from "vuex" export default{ computed:{ ...mapState(["price","number"]) } }

3.8.Vuex中状态是对象时,使用时要注意什么?

对象是引用类型,复制后改变属性还是会影响原始数据,这样会改变state里面的状态,是不允许,所以先用深度克隆复制对象,再修改。

四、Router

4.1.vue-router 路由模式有几种

4.2.vue-router如何定义嵌套路由

通过children 数组:

const router = new VueRouter({  routes: [    {      path: "/parentPage",      component: testPage,      children: [        {          path: "/childrenA",          component: childrenComponentA,        },        {          path: "/childrenB",          component: childrenComponentB,        },      ],    },    {      // 其他和parentPage平级的路由    },  ],});

4.3.vue-router有哪几种导航钩子?

参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,如果不用就拦截)最常用就这几种

4.4. $ route和$ router的区别

1、$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。

2、$router是“路由实例”对象包括了路由的跳转方法,钩子函数等

实例方法:

1)、push

2)、go 页面路由跳转 前进或者后退this.$router.go(-1)// 后退

3)、replace push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面, 不会向 history 栈添加一个新的记录

4.5.路由之间跳转的方式

1.声明式(标签跳转) 2.编程式( js跳转)

4.6.active-class是哪个组件的属性

vue-router 模块 的router-link组件

4.7.vue-router实现路由懒加载(动态加载路由)

把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应的组件即为路由的懒加载,可以加快项目的加载速度,提高效率

const router = new VueRouter({  routes: [    {      path: "/home",      name: "Home",            component:() = import("../views/home")}  ]})

4.8.怎么定义vue-router的动态路由以及如何获取传过来的动态参数?

面试官:我难道问不倒这小子了?(面试官持续懵逼中) 对大家有帮助的话三连呀~ 持续更新

【相关视频教程推荐:vuejs入门教程、web前端入门】

以上就是【吐血整理】Vue.js面试题汇总及答案解析(快来收藏)的详细内容,更多请关注php中文网其它相关文章!

关键词: 一个新的 生命周期 可以使用