vue面试题整理

199 阅读8分钟

vue的双向数据绑定原理

  • Vue数据双向绑定原理是通过数据劫持结合发布者-订阅者模式的方式来实现的,首先是对数据进行监听,然后当监听的属性发生变化时则告诉订阅者是否要更新,若更新就会执行对应的更新函数从而更新视图
  • 细节来说的话就是要通过observe监听数据的变化,如果数据更新了就要通知订阅者(watcher)来调用对应的函数,这里面还有一个处理过程就是vue里面是有多个订阅者的,所以用到消息订阅器dep来收集这些订阅者,同时使用模版解析指令(complie)来解析相关的指令然后找到对应的订阅者初始化模版和对应的函数,这个时候只要数据一更新在订阅者里面就可以调用相对应的函数更新试图

vue的异步更新

  • 在响应式数据更新时,watcher会通过调度器进入一个队列,在队列里面会通过nicktik进行watcher的更新

provide和inject方法

  • vue在设计的时候provide就是不可响应的,如果想让数据是可响应的,可以传一个能够监听的对象(data里的),这样传过去的就是对象的指针,当里面属性改变时,子组件也可以响应到里面的属性

provide和inject方法和vuex的区别

  • 一个是响应式的一个是不是响应式的
  • provide和inject方法,子组件获取的变量是随着子组件实例走的,实例存在这个变量就存在,实例销毁这个变量销毁的,不会影响其他子组件
  • vuex里面的变量是全局的,如果一个子组件销毁了这个变量那么其他子组件里面的变量就会受到影响

vue中解决跨域的方式

通过反向代理技术解决跨域问题,上线需要修改地址

  • 在vue.config文件中配置proxy属性,指向好后端的路径 设置changeOrigin为true允许跨域

vue组件之间传值

  • 父传子 子组件使用props接收
  • 子传父 使用$emit自定义事件名 在父组件中接收并且使用自定义事件
  • 使用provide和inject方法进行依赖注入,好处是父组件的后代都可以使用
  • 使用vuex进行存值取值
  • 使用场景:一般二次封装组件后需要传值的地方比较多

常用的js库

day.js lodash eslint

vue中data是什么形式 为什么

  • vue实例的时候定义data属性既可以是一个对象,也可以是一个函数,但是在脚手架中要写函数防止组件之间变量的污染

vue监听数组的变化

  • 使用数组中的splice或者push方法的时候是可以监听到数组的变化(shift,unshift,可以改变数组本身的元素等也都可以)
  • 使用this.$set()方法也可以监听
  • 使用计算属性对数组完成深拷贝 监听这个计算属性也可以监听到

v-if和v-for为什么不可以同时使用

v-if和v-for存在优先级问题,如果同时使用会造成先循环再判断性能会非常差,如果要使用的话可以用templeate标签在外层包裹使用让二者不处于同级

vue中的自定义指令

  • Vue.directives(指令名,{}) 常用的钩子函数:bind,inserted,update,componentUpdated ,upbind
  • 钩子函数中的参数:el:指令所绑定的元素,可以用来直接操作 DOM binding是一个对象,包含name,value等属性
  • 应用场景:防止表单的重复提交,图片懒加载,input输入框的自动聚焦等

vue中的过滤器

  • Vue.filter(过滤器名,函数)
  • 过滤器中的this是指向不到vue实列的,可以在外部声明一个变量接受this的实列对象(that=this),或者使用计算属性
  • 应用场景:格式化日期时间等对事件处理,通常会单独放在一个js文件当中

vue中的diff算法

  • 作用于同级比较, 在diff比较的过程中,循环从两边向中间比较
  • diff 算法在很多场景下都有应用,在 vue 中,作用于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较

vue中的虚拟dom和key值

  • vue中的虚拟dom其实就是真实dom映射而成的一个js对象,使用虚拟dom处理的话对性能比较友好,因为真实dom包含的节点太多
  • 如果不使用key值的话会就地更新,如果使用key值会比较新老的虚拟dom如果相同则复用,不相同再更新

SSR和SPA

  • ssr服务端渲染 spa单页面应用

keep-alive

  • 如果使用keep-alive包裹的话因为会有缓存所以 created钩子只有初次进入时才会生效,这个时候要使用activated 激活时触发。 deactivated 路由组件失活时触发
  • :is属性指向哪一个组件名 incluld属性将缓存哪个组件名 exclude不缓存什么名字的组件 max最多缓存多少

vueRouter相关

传参时parms和query的区别

  • 使用params方法传参的时候,要在路由后面加参数名,而query方法,就没有这种限制。 使用params方法,如果路由上面不写参数,也是可以传过去的,但不会在url上面显示出你的参数,并且当你跳到别的页面或者刷新页面的时候 参数会丢失
  • 传参可以使用params和query两种方式。
  • 使用params传参只能用name来引入路由,即push里面只能是name:’xxxx’,不能是path:’/xxx’,因为params只能用name来引入路由,如果这里写成了path,接收参数页面会是undefined!!!。
  • 使用query传参使用path来引入路由。
  • params是路由的一部分,必须要在路由后面添加参数名。query是拼接在url后面的参数,没有也没关系。 二者还有点区别,直白的来说query相当于get请求,页面跳转的时候,可以在地址栏看到请求参数,而params相当于post请求,参数不会再地址栏中显示。

hash和history的区别

  • 形式上:hash模式url里面永远带着#号,开发当中默认使用这个模式。如果用户考虑url的规范那么就需要使用history模式,因为history模式没有#号,是个正常的url,适合推广宣传;
    功能上:比如我们在开发app的时候有分享页面,那么这个分享出去的页面就是用vue或是react做的,咱们把这个页面分享到第三方的app里,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式,但是使用history模式还有一个问题就是,在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人配合,让他配置一下apache或是nginx的url重定向,重定向到你的首页路由上就ok了

如果打开一个新页面跳转

  • 使用window.open(location.href,'/')实现

计算属性和监听属性的区别

当需要在数据变化时执行异步或开销较大的操作时,使用watch,这是和computed最大的区别

计算属性

  1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
  2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
  3. computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
  4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
  5. 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
  6. get获取值,set的参数就是或许到变化后到数据值

watch属性

  1. 不支持缓存,数据变,直接会触发相应的操作;
  2. watch支持异步
  3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值
  4. 当一个属性发生变化时,需要执行对应的操作;一对多
  5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
  • immediate:组件加载立即触发回调函数执行,
  • deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

v-model用于组件传值的特性

  • 父组件传给子组件,子组件用value接收,可以监听value的变化获取值 子传父的话使用$emit分发,事件名一般是input

minix相关

  • 将组件的公共逻辑或者配置提取出来,哪个组件需要用到时,直接将提取的这部分混入到组件内部即可。这样既可以减少代码冗余度,也可以让后期维护起来更加容易。

  • 这里需要注意的是:提取的是逻辑或配置,而不是HTML代码和CSS代码。其实大家也可以换一种想法,mixin就是组件中的组件,Vue组件化让我们的代码复用性更高,那么组件与组件之间还有重复部分,我们使用Mixin在抽离一遍。

vuex相关

  • vuex中的属性,state => 基本数据
    getters => 从基本数据派生的数据
    mutations => 提交更改数据的方法,同步!
    actions => 像一个装饰器,包裹mutations,使之可以异步。
    modules => 模块化Vuex

vue的响应式原理

  • Vue 的响应式原理是核心是通过 ES5 的保护对象的 Object.defindeProperty 中的访问器属性中的 get 和 set 方法,data 中声明的属性都被添加了访问器属性,当读取 data 中的数据时自动调用 get 方法,当修改 data 中的数据时,自动调用 set 方法,检测到数据的变化,会通知观察者 Wacher,观察者 Wacher自动触发重新render 当前组件(子组件不会重新渲染),生成新的虚拟 DOM 树,Vue 框架会遍历并对比新虚拟 DOM 树和旧虚拟 DOM 树中每个节点的差别,并记录下来,最后,加载操作,将所有记录的不同点,局部修改到真实 DOM 树上。

Vue子组件调用父组件事件的方法

  • 在子组件中通过this.$parent.event来调用父组件的方法,data参数可选