文章目录
Vue面试题
Vue
1.请详细说下你对 vue 生命周期的理解?
2.为什么 vue 组件中 data 必须是一个函数?
3.vue 中 v-if 和 v-show 有什么区别?
4.**computed 和 watch 的区别**
计算属性 computed:
侦听属性 watch:
5.**vue-loader 是什么?使用它的用途有哪些?**
6.**$nextTick 是什么?**
7.**v-for key 的作用**
8.**Vue 的双向数据绑定原理是什么?**
9.**请说下封装 vue 组件的过程**
10.**Vue.js 的 template 编译**
11.**vue 如何监听对象或者数组某个属性的变化**
12.**常用的事件修饰符**
13.**vue 如何获取 dom**
14.**v-on 可以监听多个方法吗?**
15.**assets 和 static 的区别**
16.**slot 插槽**
17.**vue 初始化页面闪动问题**
18. Vue 中操作 data 中数组的方法中哪些可以触发视图更新,哪些不可以,不可以的话有什么解决办法?
19.混入(mixin)
20.computed 中的属性名和 data 中的属性名可以相同吗?
21.怎么强制刷新组件?
22.watch 的属性和 methods 方法能用箭头函数定义吗?
23.给组件绑定自定义事件无效怎么解决?
24.怎么访问子组件的实例或者子元素?
25.怎么在子组件中访问父组件的实例?怎么在组件中访问到根实例?
26.组件会在什么时候下被销毁?
27.is 这个特性你有用过吗?主要用在哪些方面?
28.prop 验证的 type 类型有哪几种?
29.在 Vue 事件中传入 `$event` ,使用 $event.target和 event.currentTarget 有什么区别?
30.使用事件修饰符要注意什么?
31.说说你对 Vue 的表单修饰符.lazy 的理解?
32.v-once 的使用场景有哪些?
33.v-cloak 和 v-pre 有什么作用?
34.怎么使 css 样式只在当前组件中生效?在 style 上加 scoped 属性需要注意哪些?你知道 style 上加 scoped 属性的原理吗?
35.Vue 渲染模板时怎么保留模板中的 HTML 注释呢?
36.Vue 中怎么重置 data?
37.过滤器中可以用 this 吗?
38.Vue在created和mounted这两个生命周期中请求数据有什么区别呢?
39.说说你对keep-alive的理解
40.v-if和v-for的优先级是什么?如果这两个同时出现时,那应该怎么优化才能得到更好的性能?
41.使用v-for遍历对象时,是按什么顺序遍历的?如何保证顺序?
42.key除了在v-for中使用,还有什么作用?
43.使用key要什么要注意的吗?
44.说说组件的命名规范
45.为什么组件中data必须用函数返回一个对象?
46.组件的name选项有什么作用?
47.说下`$attrs`和`$listeners`的使用场景?
48.EventBus注册在全局上时,路由切换时会重复触发事件,如何解决呢?
49.Vue组件里写的原生addEventListeners监听事件,要手动去销毁吗?为什么?
50.Vue组件里的定时器要怎么销毁?
51.Vue中能监听到数组变化的方法有哪些?为什么这些方法能监听到呢?
52.在Vue中哪些数组变化无法监听,为什么,怎么解决?
53.在Vue中哪些对象变化无法监听,为什么,怎么解决?
54.删除对象用delete和Vue.delete有什么区别?
55.``有什么用?
56.Vue怎么定义全局方法
57.Vue怎么改变插入模板的分隔符?
58.Vue变量名如果以_、$开头的属性会发生什么问题?怎么访问到它们的值?
59.怎么捕获Vue组件的错误信息?
60.Vue.observable你有了解过吗?说说看
61.Vue项目中如何配置favicon?
62.怎么修改Vue项目打包后生成文件路径?
63.怎么解决Vue项目打包后静态资源图片失效的问题?
64.怎么解决Vue中动态设置img的src不生效的问题?
65.在Vue项目中如何引入第三方库(比如jQuery)?有哪些方法可以做到?
66.说说你对SPA单页面的理解,它的优缺点分别是什么?
67.SPA单页面的实现方式有哪些?
68.说说你对Object.defineProperty的理解
69.说说你对Proxy的理解
70.Object.defineProperty和Proxy的区别
71.Vue的模板语法用的是哪个web模板引擎的吗?说说你对这模板引擎的理解?
72.你认为Vue的核心是什么?
73.说说你对单向数据流和双向数据流的理解
74.什么是虚拟DOM?
75.Vue中如何实现一个虚拟DOM?说说你的思路
76.Vue为什么要求组件模板只能有一个根元素?
77.axios是什么?怎样使用它?怎么解决跨域的问题?
78.如果想扩展某个现有的Vue组件时,怎么做呢?
79.vue-loader是什么?它有什么作用?
80.你有使用过JSX吗?说说你对JSX的理解?
Vuex
1.什么是Vuex?
2.Vuex解决了什么问题?
3.什么时候用Vuex?
4.怎么引用Vuex?
5.Vuex的5个核心属性是什么?
6.Vuex中状态储存在哪里,怎么改变它?
7.Vuex中状态是对象时,使用时要注意什么?
8.怎么在组件中批量使用Vuex的state状态?
9.Vuex中要从state派生一些状态出来,且多个组件使用它,该怎么做?
10.怎么通过getter来实现在组件内可以通过特定条件来获取state的状态?
11.怎么在组件中批量使用Vuex的getter属性
12.怎么在组件中批量给Vuex的getter属性取别名并使用
13.在Vuex中使用mutation要注意什么。
14.Vuex中action和mutation有什么区别?
15.Vuex中action和mutation有什么相同点?
16.在组件中多次提交同一个action,怎么写使用更方便。
17.Vuex中action通常是异步的,那么如何知道action什么时候结束呢?
18.Vuex中有两个action,分别是actionA和actionB,其内都是异步操作,在actionB要提交actionA,需在actionA处理结束再处理其它操作,怎么实现?
19.有用过Vuex模块吗,为什么要使用,怎么使用。
20.在模块中,getter和mutation接收的第一个参数state,是全局的还是模块的?
21.在模块中,getter和mutation和action中怎么访问全局的state和getter?
22.在组件中怎么访问Vuex模块中的getter和state,怎么提交mutation和action?
23.用过Vuex模块的命名空间吗?为什么使用,怎么使用。
24.怎么在带命名空间的模块内提交全局的mutation和action?
25.怎么在带命名空间的模块内注册全局的action?
26.怎么使用mapState,mapGetters,mapActions和mapMutations这些函数来绑定带命名空间的模块?
27.Vuex插件有用过吗?怎么用简单介绍一下?
28.在Vuex插件中怎么监听组件中提交mutation和action?
29.在v-model上怎么用Vuex中state的值?
30.Vuex的严格模式是什么,有什么作用,怎么开启?
Vue-Router
1.怎么重定向页面?
2.怎么配置404页面?
3.切换路由时,需要保存草稿的功能,怎么实现呢?
4.路由有几种模式?说说它们的区别?
5.讲一下完整的导航守卫流程?
6.讲一下导航守卫的三个参数的含义?
7.在afterEach钩子中可以使用`next()`吗?
8.全局导航守卫有哪些?怎么使用?
9.什么是路由独享的守卫,怎么使用?
10.说说你对router-link的了解
11.怎么在组件中监听路由参数的变化?
12.切换路由后,新页面要滚动到顶部或保持原先的滚动位置怎么做呢?
13.路由组件和路由为什么解耦,怎么解耦?
14.说说active-class是哪个组件的属性?
15.怎样动态加载路由?
16.怎么实现路由懒加载呢?
17.路由之间是怎么跳转的?有哪些方式?
18.如果vue-router使用history模式,部署时要注意什么?
19.route和router有什么区别?
20.Vue路由怎么跳转打开新窗口?
Vue面试题
Vue
1.请详细说下你对 vue 生命周期的理解?
总共分为 8 个阶段创建前 / 后,载入前 / 后,更新前 / 后,销毁前 / 后。
创建前 / 后: 在 beforeCreate 阶段,vue 实例的挂载元素 el 和数据对象 data 都为 undefined,还未初始化。在 created 阶段,vue 实例的数据对象 data 有了,el 为 undefined,还未初始化。
载入前 / 后:在 beforeMount 阶段,vue 实例的 $el 和 data 都初始化了,但还是挂载之前为虚拟的 dom 节点,data.message 还未替换。在 mounted 阶段,vue 实例挂载完成,data.message 成功渲染。
更新前 / 后:当 data 变化时,会触发 beforeUpdate 和 updated 方法
销毁前 / 后:在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 vue 实例已经解除了事件监听以及和 dom 的绑定,但是 dom 结构依然存在
2.为什么 vue 组件中 data 必须是一个函数?
对象为引用类型,当复用组件时,由于数据对象都指向同一个 data 对象,当在一个组件中修改 data 时,其他重用的组件中的 data 会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object 的实例),引用地址不同,则不会出现这个问题。
3.vue 中 v-if 和 v-show 有什么区别?
v-if 和 v-show 看起来似乎差不多,当条件不成立时,其所对应的标签元素都不可见,但是这两个选项是有区别的:
1、v-if 在条件切换时,会对标签进行适当的创建和销毁,而 v-show 则仅在初始化时加载一次,因此 v-if 的开销相对来说会比 v-show 大。
2、v-if 是惰性的,只有当条件为真时才会真正渲染标签;如果初始条件不为真,则 v-if 不会去渲染标签。v-show 则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的 CSS 切换。
4.computed 和 watch 的区别
计算属性 computed:
支持缓存,只有依赖数据发生改变,才会重新进行计算
不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化
computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于 data 中声明过或者父组件传递的 props 中的数据通过计算得到的值
如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用 computed
如果 computed 属性属性值是函数,那么默认会走 get 方法;函数的返回值就是属性的属性值;在 computed 中的,属性都有一个 get 和一个 set 方法,当数据变化时,调用 set 方法。
侦听属性 watch:
不支持缓存,数据变,直接会触发相应的操作;
watch 支持异步;
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
当一个属性发生变化时,需要执行对应的操作;一对多;
监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据,当数据变化时,触发其他操作,函数有两个参数:
immediate:组件加载立即触发回调函数执行
watch: {
firstName: {
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了firstName这个方法之后立即执行handler方法
immediate: true
}
}
复制代码
1
2
3
4
5
6
7
8
9
10
deep: deep 的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改 obj 里面任何一个属性都会触发这个监听器里的 handler
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
复制代码
1
2
3
4
5
6
7
8
9
10
优化:我们可以使用字符串的形式监听
watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
// deep: true
}
}
复制代码
1
2
3
4
5
6
7
8
9
10
这样 Vue.js 才会一层一层解析下去,直到遇到属性 a,然后才给 a 设置监听函数。
5.vue-loader 是什么?使用它的用途有哪些?
vue 文件的一个加载器,跟 template/js/style 转换成 js 模块。
6.$nextTick 是什么?
vue 实现响应式并不是数据发生变化后 dom 立即变化,而是按照一定的策略来进行 dom 更新。
nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 nextTick,则可以在回调中获取更新后的 DOM
7.v-for key 的作用
当 Vue 用 v-for 正在更新已渲染过的元素列表是,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue 将不是移动 DOM 元素来匹配数据项的改变,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。key 属性的类型只能为 string 或者 number 类型。
key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复 / 再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
8.Vue 的双向数据绑定原理是什么?
vue.js 是采用数据劫持结合发布者 - 订阅者模式的方式,通过 Object.defineProperty () 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。主要分为以下几个步骤:
1、需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter 这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化
2、compile 解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
3、Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事情是: ①在自身实例化时往属性订阅器 (dep) 里面添加自己 ②自身必须有一个 update () 方法 ③待属性变动 dep.notice () 通知时,能调用自身的 update () 方法,并触发 Compile 中绑定的回调,则功成身退。
4、MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通过 Observer 来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化 (input) -> 数据 model 变更的双向绑定效果。
9.请说下封装 vue 组件的过程
首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。
然后,使用 Vue.extend 方法创建一个组件,然后使用 Vue.component 方法注册组件。子组件需要数据,可以在 props 中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用 emit 方法。
10.Vue.js 的 template 编译
简而言之,就是先转化成 AST 树,再得到的 render 函数返回 VNode(Vue 的虚拟 DOM 节点),详细步骤如下:
首先,通过 compile 编译器把 template 编译成 AST 语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile 是 createCompiler 的返回值,createCompiler 是用以创建编译器的。另外 compile 还负责合并 option。
然后,AST 会经过 generate(将 AST 语法树转化成 render funtion 字符串的过程)得到 render 函数,render 的返回值是 VNode,VNode 是 Vue 的虚拟 DOM 节点,里面有(标签名、子节点、文本等等)
11.vue 如何监听对象或者数组某个属性的变化
当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并没有更新。这是因为 Object.defineProperty () 限制,监听不到变化。
解决方式:
this.$set (你要改变的数组 / 对象,你要改变的位置 /key,你要改成什么 value)
this.$set(this.arr, 0, "OBKoro1"); // 改变数组
this.$set(this.obj, "c", "OBKoro1"); // 改变对象
复制代码
1
2
3
调用以下几个数组的方法
splice()、 push()、pop()、shift()、unshift()、sort()、reverse()
复制代码
1
2
vue 源码里缓存了 array 的原型链,然后重写了这几个方法,触发这几个方法的时候会 observer 数据,意思是使用这些方法不用我们再进行额外的操作,视图自动进行更新。 推荐使用 splice 方法会比较好自定义,因为 splice 可以在数组的任何位置进行删除 / 添加操作
12.常用的事件修饰符
.stop: 阻止冒泡
.prevent: 阻止默认行为
.self: 仅绑定元素自身触发
.once: 2.1.4 新增,只触发一次
passive: 2.3.0 新增,滚动事件的默认行为 (即滚动行为) 将会立即触发,不能和.prevent 一起使用
.sync 修饰符
从 2.3.0 起 vue 重新引入了.sync 修饰符,但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。示例代码如下:
复制代码
1
2
会被扩展为:
复制代码
1
2
当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:
this.$emit('update:foo', newValue)
复制代码
1
2
13.vue 如何获取 dom
先给标签设置一个 ref 值,再通过 this.$refs.domName 获取,例如:
const dom = this.$refs.test
复制代码
1
2
3
4
14.v-on 可以监听多个方法吗?
是可以的,来个例子: