Vue常见面试题精讲【持续更新】

1. v-if和v-show指令有什么区别?

v-if 是 条件渲染指令,控制的是 组件是否创建(渲染),值为true则渲染该组件,值为false则不渲染该组件,对应Html元素则不会存在于浏览器的html文档中,即 打开浏览器调试工具找不到该组件对应的渲染结果
v-show控制的是 组件是否可见,并且是 通过css样式的display属性来控制组件的显示与隐藏,所以其值无论是true还是false,对应Html元素都会存在于浏览器的html文档中,即 打开浏览器调试工具都能够找到该组件对应的渲染结果,只不过值为false的时候, 会在该组件上添加style="display: none;"
需要注意的是,在vue组件开发的时候,即 在.vue中使用v-show的时候当给

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

vue-router模块的 router-link组件

9. Vue子组件调用父组件的方法?

子组件需要调用父组件的方法,那么可以通过 this.$parent获取到父组件实例,然后就可以调用父组件上的方法了。还有一种方法就是, 子组件向父组件emit一个事件父组件在子组件上监听到该事件后,就可以调用父组件上的方法了。

10. vue中的 ref 是什么?

ref 被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上,即 类似于给组件或者DOM元素上添加一个标识id,然后通过这个标识id拿到对应的DOM元素或组件实例,如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。

11. $route和$router的区别?

$route是" 路由信息对象",包括path,params,hash,query,fullPath,matched,name等路由信息参数。
$router是" 路由实例"对象包括了路由的跳转方法,钩子函数等。

12. 怎么定义组件?

全局定义:调用Vue的component()方法创建, Vue.component(组件名, {template: 模板字符串})
局部定义:在 创建Vue实例时传递的options对象中的components对象中进行定义,components:{组件名: {template: 模板字符串}}
单文件组件:在 .vue文件中定义,包含template,script,style三部分。

13. Vue-cli的src文件夹中有哪些文件?

assets文件夹是放 静态资源
components是放 组件
router是定义 路由相关的配置;
view 视图
app.vue是一个 应用主组件
main.js是 入口文件

14. 对于MVVM的理解?

MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

15. vue等单页面应用及其优缺点?

优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。

16. 路由的跳转方式?

router-link标签会渲染为标签,点击该a标签即可跳转到/home路由;
② 另一种是通过js跳转,即通过路由对象this.$router的push()方法进行跳转, 比如 router.push('/home')

17. 计算属性(computed)、方法(methods)和侦听属性(watch)的区别与使用场景?

methods VS 计算属性
我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。
然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
相比而言,只要发生重新渲染,method 调用总会执行该函数。总之,重新计算开销很大的话请选计算属性,不希望有缓存的请选methods。
watch VS 计算属性
当你在模板内使用了复杂逻辑的表达式时,你应当使用计算属性。
侦听属性是一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。
当你有一些数据需要随着其它数据变动而变动时,或者当需要在数据变化时执行异步或开销较大的操作时,你可以使用 watch。

18. axios是什么?怎么使用?

axios是 基于Promise的,用于浏览器和nodeJS的http客户端,主要作用就是 向后台发送请求。其存在许多优点:
  • 支持Promise
  • 支持并发请求
  • 提供拦截器
  • 浏览器支持防止csrf(跨站请求伪造)

19. axios、fetch、ajax(jquery)的区别?

axios和fetch是基于Promise的,ajax是基于callback的形式。fetch脱离了xhr,是新的语法,默认是不传cookie的, 监听不到请求进度

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

vuex是一个专门为vue构建的状态机管理机制,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,主要 解决组件间数据共享的问题,其实就是 采用类似全局对象的形式来管理所有组件的公共数据,其强调的是集中式管理,主要是为了便于维护、组件解耦,适合大型项目,有多个视图组件共同依赖一个状态的情况下使用,比如商城系统、外卖系统。
vuex的核心: stategettersmutationsactionsmodules

21. 说出4个vue当中常用的指令及其用法?

  • v-if: 这是一个条件渲染指令,代表存在和销毁,用于控制组件的创建与否;
  • v-bind: 这是一个绑定指令,用于绑定属性,可简写为冒号;
  • v-on: 这是一个监听指令,用于监听事件,可简写为@;
  • v-for: 这是一个循环指令,用于遍历数组;

22. 导航钩子有哪些?它们有哪些参数?

导航主要有三类钩子: 全局级路由钩子路由级路由钩子组件级路由钩子。主要参数有to(目标路由对象)、from(当前路由对象)、next(是一个函数,用于控制是否放行,即是否能通过当前守卫)。
  • 全局级路由钩子: beforeEach和afterEach,每次路由跳转全局路由钩子都会执行,beforeEach(to, from, next)钩子有三个参数,但是afterEach是已经跳转结束了,所以其没有next参数,afterEach(to, from),全局路由钩子由router对象调用
  • 路由级路由钩子: 路由级钩子只有一个即beforeEnter,其是在配置路由表的时候配置,也是有to、from、next三个参数,只有进入该路由的时候才会执行,如果是动态路由之间的切换,那么则不会触发beforeEnter钩子,因为是同一个路由,只是参数不一样
  • 组件级路由钩子: beforeRouteEnter(路由进入该组件的时候执行)、beforeRouteUpdate(动态路由切换时候执行)、beforeRouteLeave(路由离开当前组件的时候执行),需要注意的是,路由钩子是优先于组件的生命周期的,也就是说路由钩子全部执行完毕之后才会开始组件的生命周期,所以其钩子执行顺序: beforeRouteLeave --> beforeEach --> beforeEnter --> beforeRouteEnter --> afterEach --> beforeCreate --> created --> mountedbeforeRouteUpdate只有动态路由切换的时候才会执行,即/user/1切换到/user/2才会执行

23. v-model是什么?

v-model主要用于数据的双向绑定,其内部主要完成了两个操作: 通过v-bind绑定value属性值监听input事件,并更新数据,如:

24. 什么是路由懒加载?其原理是什么?

所谓路由懒加载,即在项目打包的时候,项目中通常会有多个路由,如果将所有路由对应的组件都打包到一个文件中,那么最终打包的文件就会变得非常大,会影响页面的加载性能,如果我们能把不同路由对应的组件 分割成不同的代码块,然后 当路由被访问的时候才异步加载出对应组件,这样就会变得更加高效。
所以其原理就是利用了 webpack的代码分割(按需加载)机制和 vue的异步组件功能,代码被分割后就会变成一个单独的文件,所以 路由被访问的时候需要向服务器发起请求加载该组件,这是一个 异步的过程,所以需要使用到vue的异步组件机制。

异步组件?

异步组件,就是在注册组件的时候, 传入一个函数,然后这个函数返回一个Promise对象, resolve的值为这个组件对象,如:
export default new Router({
    routes: [
        {
          path: '/about',
          name: 'about',
          component: () => { // 注册为一个异步组件
              const About = require("./views/About.vue");
              return Promise.resolve(About);
          }
        }
    ]
});

或者在注册异步组件的时候传入resolve和reject,如:

export default new Router({
    routes: [
        {
          path: '/about',
          name: 'about',
          component: (resolve, reject) => { // 注册为一个异步组件
              const About = require("./views/About.vue");
              resolve(About);
          }
        }
    ]
});

webpack提供的import()函数会返回一个Promise对象,并且会对引入的组件进行代码分割,所以可以通过import()同时实现代码分割和组件异步加载,即路由懒加载,如:

export default new Router({
    routes: [
        {
          path: '/about',
          name: 'about',
          component: () => import('./views/About.vue') // 等价于注册异步组件并返回一个Promise对象,分割代码的同时进行异步加载
        }
    ]
});

25. 用过插槽吗?用过哪些类型的插槽?

插槽其实就是 组件中提供的占位符,所以 插槽占位符在组件中使用,插槽有三种: 匿名插槽具名插槽作用域插槽
  • 匿名插槽:即没有名字的插槽,即,使用组件的时候会将组件中的innerHTML插入到位置上,相当于动态向组件内部传递数据。
// About.vue组件


// 使用About组件

    

hello world

  • 具名插槽: 即有名字的插槽,需要在标签上添加一个name属性,指定的名称,即,同时使用组件的时候需要给其中的innerHTML添加slot属性,属性值为的name属性值,如:
// About.vue组件


// 使用About组件

    

header

  • 作用域插槽: 作用域插槽可以理解为组件向外输出数据,我们可以在组件的标签上添加上一些属性,然后其中的属性值可以传到组件外使用,会将slot标签上的所以属性合并到一个对象对外输出,组件外通过slot-scope指定一个变量名来接收这个对象,如:
// About.vue组件


// 使用About组件

    

26. 什么是vue-loader?

vue-loader就是 .vue组件的加载器可以将.vue组件转换为javascript模块,及 动态渲染一些数据,同时vue-loader还对.vue组件中的三个标签都进行了相应的优化。