关于VUE的面试题(小结)
福星星
一、生命周期
钩子函数:
- beforeCreate
- created:此时首次可以使用data和methods
- beforeMount:模板在内存中
- mounted:DOM渲染在页面中,可以访问DOM结构
二、computed、getter、setter
- computed:处理复杂的声明式逻辑
- getter:computed的默认属性,用于读值
- setter:设值属性
//html中 <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> //js中 data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } //getter为默认属性,一般默认省略getter,完整写法: reversedMessage: { get() { return this.message.split('').reverse().join('') }, set(newValue) { this.message = newValue } } } //结果 Original message: "Hello" Computed reversed message: "olleH"
运行vm.message = 'goodbye',setter会被调用,message会被更新
Q1. computed vs methods
methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
computed可以实现的结果看似用methods也可以实现,二者的区别在于:计算属性(computed)是基于它们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时它们才会重新求值;相比之下,每次触发重新渲染都会使得调用方法(methods)再次执行函数。
Q2. computed vs watch
watch是VUE实例上监听响应数据变动的属性,当数据发生变化时做出相应的变化。
data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, //使用watch watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } //使用computed computed: { fullName: function () { return this.firstName + ' ' + this.lastName } }
可以看出使用watch,当一个数据的变化受多个数据影响的时候,命令式会变得重复,这个时候很容易造成滥用watch。watch更适合于在数据变化时执行异步或者开销较大的操作时。
- watch擅长处理的场景:一个数据影响多个数据
- computed擅长处理的场景:一个数据受多个数据影响
三、watch监听对象内部变化
- 只是监听Obj内的某一属性:直接用obj.key进行监听
- 对整个obj深层监听
data: { a: 100, b: { value: 1, type: 2 } } watch: { //普通监听 a(newval, oldval){ console.log("new-a:"+newval+',old-a:'+oldval); } b(val, oldVal){ console.log("b.value: "+val.value, oldVal.value); }, //监听整个obj,深层监听 b:{ handler(val, oldVal){ console.log("b.value: "+val.value, oldVal.value); }, deep:true immediate: true }, //监听Obj中的属性,obj.key 'b.value': { handler(val,oldVal){ console.log("b.value: "+val, oldVal); } }, }
- handler:监听数组或对象时候用到的方法,深层监听。只要obj中有属性值变化就进行监听但不知道具体是哪个属性值变化。
- deep:默认值是false,true发现对象内部值的变化即深层监听,(监听数组的变动不需要这么做)。
- immediate:立即以表达式的当前值触发回调。true代表如果在 wacth里声明了之后,就会立即先去执行里面的handler方法,false就跟我们以前的效果一样,在数据变化的时候才执行,不会在绑定的时候就执行。
Q1:监听对象中某一属性值变化
- 监听obj.key
- 利用computed作为中间层,监听computed计算得到的值,就可以只监听对象中的某一属性变化从而做出相应操作
computed: { newvalue(){ return this.b.value } }, watch: { newvalue(val, oldVal){ console.log("b.value: "+val, oldVal); }, }
Q2:深层监听的理解
监听器会一层层的往下遍历给对象的所有属性都加上了这个监听器
四、v-for中key的作用
key的作用是"唯一标识" ,可以标志组件的唯一性,可以更高效的更新虚拟DOM。
vue的dom渲染是虚拟dom,数据发生变化时,diff算法会只比较更改的部分,如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的改变,而是简单复用此处每个元素。
加上key值后,当VUE节点发生变化的时候可以通过key值来识别相同的节点,更高效率更新DOM。
参考可见:https://www.jb51.net/article/178628.htm
五、$nextTick的作用
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
解决的问题:有些时候在改变数据后立即要对dom进行操作,此时获取到的dom仍是获取到的是数据刷新前的dom,无法满足需要,这个时候就用到了$nextTick。
// 修改数据 vm.msg = 'Hello' // DOM 还没有更新 Vue.nextTick(function () { // DOM 更新了 })
六、$set
如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。Vue 不允许在已经创建的实例上动态添加新的根级响应式属性。
使用 Vue.set(object, key, value)方法将响应属性添加响应式对象,并确保这个新属性同样是响应式的,且触发视图更新。
解决:在vue中对一个对象内部进行一些修改时,vue没有监听到变化无法触发视图的更新,此时来使用$set来触发更新,使视图更新为最新的数据。
【响应式:只有当实例被创建时中存在的属性才是响应式的,或者说在data中存在的才能响应。
原因:由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。】
<template> <div> <p @click="addb(a)">{{a.b}}</p> <p @click="addc(a)">{{a.c}}</p> </div> </template> <script> export default { data(){ return { a: { b: 1 }, } }, methods: { addb(a) { a.b = a.b + 1; }, addc(a) { a.c = a.c + 1; console.log(a.c) }, }, mounted() { this.a.c = 200 //{{a.c}}不能主动触发视图更新故无法被渲染出来,当下一次视图更新时才出现 this.$set(this.a, 'c' ,200) //触发视图更新,{{a.c}}被渲染 } } </scirpt>
- this.a.c = 200:点击b的数字才可以触发视图刷新,点击c的数字console.log出来的c是变化的,但是视图未更新还是原来的c
- this.$set(this.a, 'c' ,'200'):点击c视图变化,是最新的c
七、组件间的传值
- props:父传子
- $emit:子传父
- eventbus:兄弟组件间
- vuex:
- $parent / $children / ref:
- provide / inject:
- Vue.observable:
- $attrs:
- $listeners:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。