一、Vue面试基础知识
在这一小节中,我们先把一些常见的Vue
的基础的面试题,总结出来。这些基础的知识点都是在面试的时候经常会被问到的一些内容。
当然关于基础的一些内容在前面的课程总咱们都已经讲解过来,所以这里我们只是把一些常见的内容与注意的问题再次强调 一下。
1、computed和watch
computed
有缓存,如果数据data
没有发生变化的话,则不会重新计算。watch
如何实现深度的监听?watch
监听引用类型,获取不到oldValue
下面看一下watch
的伪代码
export default{
data(){
return {
name:'zhangsan',
info:{
city:'上海'
}
}
},
watch:{
name(oldVal,val){
console.log(oldVal,val)//值类型,可以正常获取到值
},
info:{
handler(oldVal,val){
console.log(oldVal,val)//引用类型,获取不到oldVal,因为指针相同,此时已经指向了新的val
},
deep:true//深度监听
}
}
}
这里 还需要注意watch
的一个特点是,最初绑定的时候是不会执行的,要等到 firstName
改变时才执行监听计算。那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?
watch: {
firstName: {
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
immediate: true
}
}
而immediate:true
代表如果在 wacth
里声明了 firstName
之后,就会立即先去执行里面的handler
方法,如果为 false
就跟我们以前的效果一样,不会在绑定的时候就执行。
2、v-if与v-show
简单的说一下,它两者的区别:如果条件满足,使用v-if
与v-show
都会创建对应的元素并展示出对应的内容,如果条件不满足v-else
的内容不会展示也就是不会创建对应的元素,而v-show
会创建出对应的元素,但是不会展示,使用style="display:none"
将其隐藏掉。
两者如何选择呢?如果元素的创建不是很频繁,可以使用v-if与v-else
,如果某些元素需要频繁的创建或者是需要不断的切换元素的显示隐藏状态,就需要使用v-show
,这样性能会比较好,而如果使用v-if
与v-else
就需要不断创建与销毁元素,这样性能比较低了。
3、循环列表
key
的重要性,注意key
不能乱写,例如不能使用random
或者是index
v-for
和v-if
不能一起使用!
<ul>
<li v-if="flag" v-for="item in lists" :key="item.id"></li>
</ul>
<script>
export default {
data(){
return{
flag:false,
lists:[]
}
}
}
</script>
v-for
的优先级要高于v-if
,这样的话就会先去执行循环,这样数组中的内容都循环完毕了,才会使用v-if
进行判断。这样判断会被执行多次,而且是重复的判断。
4、父子组件如何通信
父子组件的通信通过props
与$emit
完成,关于这块内容在前面的课程中已经重点讲解过了,这里不在进行讲解了。
5、兄弟组件之间的通信
自定义事件的实现方式
这里需要注意的一点就是最后要及时销毁自定义的事件,否则可能会造成内存泄漏的问题.
beforeDestroy(){
event.$off('onAddSub',this.addSub)
}
6、生命周期
生命周期分为哪几个阶段?
- 挂载阶段
- 更新阶段
- 销毁阶段
重点理解官网中的图
7、自定义v-model
v-model
是vue
实现数据双向绑定最好的一个指令, v-model
本质上不过是语法糖,它负责监听用户的输入事件以更新数据,当你修改页面的时候 v-model
自动去更新数据层 (model)
,当你修改数据的时候v-model自动去更新视图层 (view
)
8、$nextTick
Vue
是异步渲染data
改变之后,DOM
不会立刻渲染$nextTick
会在DOM
渲染之后被触发,以获取最新的DOM
节点。
<template>
<div id="app">
<ul ref="ul1">
<li v-for="(item,index) in list" :key="index">
{
{item}}
</li>
</ul>
<button @click="addItem">
添加一项
</button>
</div>
</template>
<script>
export default {
name:'app',
data(){
return{
list:['a','b','c']
}
},
methods:{
addItem(){
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
//获取dom元素
const ulElem=this.$refs.ul1
console.log(ulElem.childNodes.length)
}
}
}
</script>
如果我们点击了按钮
以后,输出的子元素的个数是多上呢?这里是3,可能你认为是6
,因为在按钮所对应的处理函数中,我们向list
数组中又添加了3项内容,这样ul
中的子元素应该是6(list
是响应式的,数据发生变化后,重新渲染视图). 但是实际的输出结果为3
.
原因是:当data
中list
数组中的内容发生了变化后,DOM
元素并不会立即改变。这时获取到的DOM
元素的内容还是以前的内容。
但是,这里我们希望当单击完按钮后,立即获取到最新的DOM
元素内容,应该怎样处理呢?
修改addItem
方法中的代码如下:
addItem(){
this.list.push(`${
Date.now()}`)
this.list.push(`${
Date.now()}`)
this.list.push(