vue面试题(全)
原理篇:
1,computed和watch的区别
computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。
对检测的值没有要求
watch 侦听器 : 更多的是「观察」的作用, 值为复合类型时,需要开启深度监听deep ,自执行一次immdeiate。
应用场景:
当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算。
当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
2,为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty
Object.defineProperty 本身有一定的监控到数组下标变化的能力,但是在 Vue 中,从性能/体验的性价比考虑,尤大大就弃用了这个特性(Vue 为什么不能检测数组变动 )。为了解决这个问题,经过 vue 内部处理后可以使用以下几种方法来监听数组
push();
pop();
shift();
unshift();
splice();
sort();
reverse();
由于只针对了以上 7 种方法进行了 hack 处理,所以其他数组的属性也是检测不到的,还是具有一定的局限性。
Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue 2.x 里,是通过 递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象是才是更好的选择。
Proxy 可以劫持整个对象,并返回一个新的对象。Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。
3,Vue 中的 key 到底有什么用?
key 是给每一个 vnode 的唯一 id,依靠 key,我们的 diff 操作可以更准确、更快速 (对于简单列表页渲染来说 diff 节点也更快,但会产生一些隐藏的副作用,比如可能不会产生过渡效果,或者在某些节点有绑定数据(表单)状态,会出现状态错位。)
diff 算法的过程中,先会进行新旧节点的首尾交叉对比,当无法匹配的时候会用新节点的 key 与旧节点进行比对,从而找到相应旧节点.
更准确 : 因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确,如果不加 key,会导致之前节点的状态被保留下来,会产生一系列的 bug。
更快速 : key 的唯一性可以被 Map 数据结构充分利用,相比于遍历查找的时间复杂度 O(n),Map 的时间复杂度仅仅为 O(1),源码如下:
4,Vue 组件 data 为什么必须是函数 ?
new Vue()实例中,data 可以直接是一个对象,为什么在 vue 组件中,data 必须是一个函数呢?
因为组件是可以复用的,JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染,产生副作用。
所以一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。new Vue 的实例是不会被复用的,因此不存在以上问题。
5.vue.cli项目中src目录每个文件夹和文件的用法?
assets文件夹是放静态资源;
components是放组件;
router是定义路由相关的配置;
view视图;
app.vue是一个应用主组件;
main.js是入口文件
6.Vue组件之全局组件与局部组件的使用详解
全局组件
main.js
中引入并全局注册组件局部组件
具体页面中引入并声明组件,template中添加组件
1. 计算属性和 watch 的区别?computed 是一个对象时,它有哪些选项?computed 和 methods 有什么区别?computed 是否能依赖其它组件的数据?watch 是一个对象时,它有哪些选项?
答:
- 计算属性是自动监听依赖值的变化,从而动态返回内容,监听是一个过程,在监听的值变化时,可以触发一个回调,并做一些事情。
所以区别来源于用法,只是需要动态值,那就用计算属性;需要知道值的改变后执行业务逻辑,才用 watch,用反或混用虽然可行,但都是不正确的用法。- 有get和set两个选项
- methods是一个方法,它可以接受参数,而computed不能,computed是可以缓存的,methods不会。
- computed可以依赖其他computed,甚至是其他组件的data
- watch 配置
handler
deep 是否深度
immeditate 是否立即执行
2. active-class是哪个组件的属性?嵌套路由怎么定义?怎么定义vue-router的动态路由?怎么获取传过来的动态参数?vue-router有哪几种导航钩子?
1. vue-router模块的router-link组件。
2. 在 VueRouter 的参数中使用 children 配置
3. 在router目录下的index.js文件中,对path属性加上/:id。
4. 使用router对象的params.id。5.有三种:
第一种全局导航钩子router.beforeEach(to,from,next)作用跳转前进行判断拦截。
第二种:组件内的钩子
第三种:单独路由独享组件
3. 什么是vue生命周期?vue生命周期的作用是什么?vue生命周期总共有几个阶段?第一次页面加载会触发哪几个钩子?DOM 渲染在哪个周期中就已经完成?简单描述每个周期具体适合哪些场景?
1. Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
2. 它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
3. 它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
4. 第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
5. DOM 渲染在 mounted 中就已经完成了
6. 生命周期钩子的一些使用方法: beforecreate : 可以在这加个loading事件,在加载实例时触发 created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用 mounted : 挂载元素,获取到DOM节点 updated : 如果对数据统一处理,在这里写上相应函数 beforeDestroy : 可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom
4. vue组件的scoped属性的作用?原理?nextTick的原理?以及优点?
- 作用:在style标签上添加scoped属性,以表示它的样式作用于当下的模块,很好的实现了样式私有化的目的
- 原理:使用 PostCSS 来实现转换,通过给 dom 增加一个动态属性,然后 css 选择器也额外添加对应的属性来选择该 dom ,达到该样式只作用于含有该属性的 dom,实现组件样式的模块
- 将回调延迟到下次dom更细循环之后执行。在修改数据之后立即使用它,然后等待dom更新。(当data中的某个属性改变的时候,这个值并不是立即渲染到页面上的,而是先放到watcher队列上(异步),只有当前任务空闲的时候才会去执行watcher队列上的任务。)
- 优点:相对未来更新后的视图进行操作,我们只需要把要执行的函数传递给this.$nextTick方法
5. vue slot 具体用法 你项目怎么使用slot?vue的diff算法?Vue中的key有什么作用?
1. slot用于封装组件中,写在子组件 接收父组件动态传递子组件内容片断,slot插槽的使用方法其实就是类似于一个子组件或者标签的引用的过程,在父组件里面定义一个slot,起个name,然后组件引入到子组件,子组件里面有个元素的属性slot值等于name,然后父组件里面没有值的时候就可以显示子组件里面的信息了
6,父组件调用子组件方法
<Login ref="Login" v-show="loginstate"></Login>
//事件中直接调用即可
hello() {
console.log('子组件加载完成')
// 去调用子组件事件,同样也可以用点击事件执行
this.$refs.Login.fn()
}