![cover](https://img-blog.csdnimg.cn/img_convert/a7b426f027554ddcbce196b962043da2.png)
Vue3前端面试题考点
为了性能优化, 因为vue是虚拟DOM,更新DOM时用diff算法对节点进行一一比对,比如有很多li元素,要在某个位置插入一个li元素,但没有给li上加key,那么在进行运算的时候,就会将所有li元素重新渲染一遍,但是如果有key,那么它就会按照key一一比对li元素,只需要创建新的li元素,插入即可,不需要对其他元素进行修改和重新渲染。在data()中的修改后,页面中无法获取data修改后的数据
参考:前端面试题 — — vue篇_Jet_closer_burning的博客-CSDN博客
合集:2023年最全前端面试题考点HTML5+CSS3+JS+Vue3+React18+八股文+手写+项目+笔试_参宿7的博客-CSDN博客
Vue.js - 渐进式 JavaScript 框架 | Vue.js
框架为一二面,面试官尤其喜欢问为什么要用+怎么用
一到三颗⭐代表重要性,⭐选择性了解,⭐⭐熟悉,⭐⭐⭐掌握
目录
目录
父子组件:子组件props来接受,$emit触发父组件的自定义事件;
兄弟组件:一个公共组件bus.js.。传递方通过事件触发bus.$emit。接收方通过在mounted(){}生命周期里触发bus.$on
div class="demo" data-v-27e4e96e>
.demo{color: red;}会被编译成.demo[data-v-27e4e96e]{color: red;}
掌握⭐⭐⭐
Vue2和3
组件传值
一、Vue父子 组件之间传值
子组件通过props来接受数据和通过$emit来触发父组件的自定义事件;
二、兄弟组件之间的传值
建一个公共组件bus.js.。传递方通过事件触发bus.$emit。接收方通过在mounted(){}生命周期里触发bus.$on。
三、可以通过VUEX 来跨组件传参。
四、父孙传值 $attrs(向下)$listeners(向上)
五、 祖先和子孙传值provide/inject
六、获取父组件实例this.$parent
vue传值之父子组件传值、bus传值、vuex传值、其他方式传值…-CSDN博客
父子组件:子组件props来接受,$emit触发父组件的自定义事件;
兄弟组件:一个公共组件bus.js.。传递方通过事件触发bus.$emit
。接收方通过在mounted(){}生命周期里触发bus.$on
Vuex跨组件
Vue父子组件通信的缺点
-
逐层传递 props: 在多层次的组件嵌套中,如果需要在更深层的子组件中访问某些数据,就需要通过逐层传递 props,这会导致组件之间的耦合增加,并且在层级较深的情况下,维护起来可能会变得复杂。
-
Prop drilling(属性钻取): 如果父组件需要传递给孙子组件数据,但这些数据对于中间的子组件来说并不需要,那么这些数据会在组件层级之间进行无意义的传递,导致代码冗余和性能损耗。
-
难以追踪数据流: 在复杂的组件结构中,跟踪数据的传递和变化可能变得困难,特别是在大型应用中。这会增加调试和维护的难度。
-
无法直接修改 props: 从父组件传递给子组件的 prop 是只读的,子组件无法直接修改这些数据。如果需要在子组件中修改这些数据,需要通过触发事件或者使用 Vuex(状态管理模式)等方式来实现。
-
耦合性增加: 父子组件之间的通信可能导致它们之间紧密耦合,使得组件难以在其他上下文中重用,因为它们依赖于特定的数据传递方式。
为了解决这些问题,Vue 提供了其他更高级的组件通信机制,如:
-
Vuex(状态管理): 适用于管理大规模应用的共享状态,使得组件之间的数据共享和响应变得更加简单和可控。
-
事件总线: 可以通过 Vue 实例作为中央事件总线来实现组件之间的通信,尽管这也可能带来一些全局状态的问题。
-
Provide / Inject: 可以在父组件中使用
provide
,然后在子组件中使用inject
来实现跨多层次的组件通信,但也会增加组件之间的依赖关系。
选择合适的通信方式取决于应用的规模、复杂度以及团队的偏好,但在设计时需要权衡各种因素来避免可能的问题。
Vuex
css scoped
每个vue文件生成一个唯一的id
div class="demo" data-v-27e4e96e></div>
css选择器改造成属性选择器
.demo{color: red;}
会被编译成.demo[data-v-27e4e96e]{color: red;}
1)编译时,会给每个vue文件生成一个唯一的id,会将此id添加到当前文件中所有html的标签上
如<div class="demo"></div>
会被编译成<div class="demo" data-v-27e4e96e></div>
2)编译style标签时,会将css选择器改造成属性选择器,如.demo{color: red;}
会被编译成.demo[data-v-27e4e96e]{color: red;}
// 页面上 “属性选择器”这几个字显示红色
<div data-v-hash class="test-attr">属性选择器</div>
<style>
/* 该标签有个data-v-hash的属性,只不过该属性为空,依然可以使用属性选择器 */
.test-attr[data-v-hash] {
color: red;
}
</style>
<script>
// 通过js判断是否存在 data-v-hash 属性
console.log(document.querySelector('.test-attr').getAttribute('data-v-hash') === ''); // true
</script>
「历时8个月」10万字前端知识体系总结(前端框架+浏览器原理篇)🔥 - 掘金
熟悉⭐⭐
4.路由之间如何传参⭐⭐
通过router-link路由导航跳转传递
<router-link to=`/a/${id}`>routerlink传参</router-link>
1
跳转时使用push方法拼接携带参数。
this.$router.push({
path: `/getlist/${id}`,
})
1
2
3
通过路由属性中的name来确定匹配的路由,通过params来传递参数。
this.$router.push({
name: 'Getlist',
params: {
id: id
}
})
使用path来匹配路由,然后通过query来传递参数。
this.$router.push({
path: '/getlist',
query: {
id: id
}
})
注意:query有点像ajax中的get请求,而params像post请求。
params在地址栏中不显示参数,刷新页面,参数丢失,
其余方法在地址栏中显示传递的参数,刷新页面,参数不丢失。
详情请看Vue-router之简单的路由传参三种方法
5.谈一谈VUEX⭐⭐
原理:Vuex是专门为vue.js应用程序设计的状态管理工具。
构成:
state:vuex的基本数据,用来存储变量,存放的数据是响应式的。
mutations:提交更改数据,同步更新状态。
actions:提交mutations,可异步操作。
getters:是store的计算属性。
modules:模块,每个模块里面有四个属性。
关于VUEX如何使用可以看VUE的传值问题
6.如何解决vuex页面刷新数据丢失问题?⭐⭐
原因:因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被清空。
解决方法:将vuex中的数据直接保存到浏览器缓存中。(一般是用sessionStorage)
9.Route和router的区别⭐
route:是路由信息对象,包括“path,parms,hash,name“等路由信息参数。
Router:是路由实例对象,包括了路由跳转方法,钩子函数等。
10.v-show和v-if的区别⭐
v-if:组件的销毁和重建,更适合带有权限的操作,切换开大。如果开始条件为false则什么都不做,只有为true才会编译。
v-show:css切换,隐藏显示更适合频繁切换。在任何情况下都会被编译,然后被缓存,而且dom元素会被保留。
11.vue中数据变了但是视图不跟新怎么解决?⭐
原因:
数组数据变动:使用某些方法操作数组,变动数据时,有些方法无法被vue监测。
Vue 不能检测到对象属性的添加或删除。
异步更新队列:数据第一次的获取到了,也渲染了,但是第二次之后数据只有在再一次渲染页面的时候更新,并不能实时更新。
12.vue中data为什么是函数而不是对象?⭐⭐
官网中有这么一段介绍,详情可以看组件的复用
意思就是,在Vue中组件是可以被复用的,而当data是一个函数的时候,每一个实例的data都是独立的,不会相互影响了。
更详细的解释 ==>
13.vue中父子组件传值,父组件异步请求,子组件不能实时更新怎么解决?(vue中数据不能实时更新怎么解决?)⭐⭐⭐
首先了解父子组件生命周期执行顺序 ==>
加载渲染数据过程
父组件 beforeCreate -->
父组件 created -->
父组件 beforeMount -->
子组件 beforeCreate -->
子组件 created -->
子组件 beforeMount -->
子组件 mounted -->
父组件 mounted -->
原因:因为生命周期只会执行一次,数据是要等到异步请求以后才能拿到,那么子组件的mounted钩子执行的时候,还没有拿到父组件传递过来的数据,但是又必须要打印出来结果,那这样的话,就只能去打印props中的默认值空字符串了,所以打印的结果是一个空字符串。
解决办法:
使用v-if控制组件渲染的时机
初始还没拿到后端接口的异步数据的时候,不让组件渲染,等拿到的时候再去渲染组件。使用v-if="变量"去控制,初始让这个变量为false,这样的话,子组件就不会去渲染,等拿到数据的时候,再让这个变量变成true,
举例:
data() {
return {
isTrue:false // 初始为false
};
},
monted(){
this.$post.a.b.c.getData(res=>{
if(res.result){
this.isTrue = true
}
})
}
使用watch监听数据的变化
举例:
props: {
tableData: {
type: Array,
default: [],
},
},
watch: {
tableData(val){
console.log(val)
}
},
使用VueX
14.父子组件传参emit如何传多个参数?⭐
子组件:
submit(){
this.$emit('g',1,2,3,4,5)
}
父组件
g(val1,val2,val3,val4,val5) {
console.log(val1,val2,val3,val4,val5)
}
15.Vue 路由跳转方式⭐⭐
router-link 标签跳转
this.$router.push()
this.$router.replace()
this.$router.go(n):(0:当前页,-1上一页,+1下一页,n代表整数)
16.条件渲染v-if 与 v-for 优先级⭐
vue2.0文档是这么说的
vue2列表渲染指南
vue3.0文档是这么说的
vue3条件渲染
18.Vue 中 for循环为什么加 key?⭐⭐
为了性能优化, 因为vue是虚拟DOM,更新DOM时用diff算法对节点进行一一比对,比如有很多li元素,要在某个位置插入一个li元素,但没有给li上加key,那么在进行运算的时候,就会将所有li元素重新渲染一遍,但是如果有key,那么它就会按照key一一比对li元素,只需要创建新的li元素,插入即可,不需要对其他元素进行修改和重新渲染。
key也不能是li元素的index,因为假设我们给数组前插入一个新元素,它的下标是0,那么和原来的第一个元素重复了,整个数组的key都发生了改变,这样就跟没有key的情况一样了。
20.为什么vue3不继续用$set?⭐
$set的作用:在vue2.0中:使用对象和数组来定义数据,当需要向对象或数组中新增一个属性或元素,并希望它在更新 View 时响应式地更新,就需要使用 $set方法来完成。
vue2是用object.definedProperty来实现数据响应的,无法监听深层数据的变化。
Vue3 中使用Proxy对数据代理通过ref和reactive将值和对象类型变为响应式对象,这样对它的修改和添加就能被vue捕获到,从而实现页面的自动刷新。
参考官网响应式基础
21.vue路由中的history和hash的区别⭐⭐
地址栏带不带"#"号
hash:http://localhost:8080/#/
history:http://localhost:8080/
都是利用浏览器的两种特性实现前端路由
history是利用浏览历史记录栈的API实现
hash是监听location对象hash值变化事件来实现
相同的url
history会触发添加到浏览器历史记录栈中,hash不会触发,
history需要后端配合,如果后端不配合刷新页面会出现404,hash不需要
hashRouter原理:通过window.onhashchange获取url中hash值
historyRouter原理:通过history.pushState,使用它做页面跳转不会触发页面刷新,使用window.onpopstate监听浏览器的前进和后退
详情可以看官网不同历史模式|Vue Router
参考:
更多推荐
所有评论(0)