记录前端生涯的第一次面试,打消了我对面试的恐惧。
前言
学前端也有一段时间了,自认为掌握的还算阔以,试着投递了些简历,也成功的约到了好几场面试,这篇文章记录的正是被面试官狠狠拷打的实录,已老实求放过,下次再也不装x了。
自我介绍
下面开始走马灯环节,请你做个简单的自我介绍。然后我就开始bb
项目介绍
这里咱就不展开说了(doge),因为项目介绍和面试官bb太久了,下面就是面试官就我的项目提出的一些问题。
提问环节
路由组件的缓存
我看你项目中用到了组件缓存啊,请你展开说一下。
然后我开始表演了:
有一个这样的场景,在进行Tabs多页切换时,切换不同的页面然后再切换回来,页码仍然停留在切换前的状态。
实现这个业务场景就可以用到路由缓存了,就是使用Vue中的keep-alive去包裹router-view来实现。
<template>
<div class="app-main">
<keep-alive ,include="a,b,c">
<router-view />
</keep-alive>
</div>
</template>
- keep-alive的include动态缓存
在这里keep-alive是一个组件需要接受props,一个是include
,一个是exclude
。被include匹配的组件会被缓存,被exclude匹配的组件不会被缓存。
include和exclude可以传入name
属性,这个name是当前组件的name不是路由的name,这个不要混淆了。
Vue2中组件name的定义方法:
export default {
name: "Name",
data(){
return{}
}
};
vue3中组件name可以直接写在script标签中:
<script setup name = "Person">
<script>
注意千万不要把组件的name属性和路由的name属性搞混了,血的教训,被面试官狠狠拷打。
另外,在使用了keep-alive组件后会有activated和deactivated这两个生命周期函数。
当引入keep-alive的时候,页面第一次进入,钩子函数的触发顺序 created > mounted > activated
退出时触发deactivated,当再次进入时只触发activated。
注意: keep-alive之后的页面模板只有第一次解析变成HTML片段,然后再次进入时则直接读取内存中的数据,即只有数据变化时,才使用VirtualDOM进行diff更新。
怎么实现简单的手机号码校验
面试官: 我看你的项目中有一个登录功能啊,那你如果要实现手机号的校验你会怎么实现呢?
听到这个问题,我瞬间大脑萎缩了。😭 秉承着就算不懂也要装懂的原则,我又开始了新一轮的胡言乱语。
我的回答是: 额,可以先判断一下字符串的长度,然后再校验一下手机号的前缀因为手机号的前缀就那几个开头,或者直接申请一个阿里云服务器把所有的校验工作都交给它。
面试官说: 哪有这么复杂啊,哈哈,其实可以编写一个正则表达式来匹配手机号的模式,你这个解决方案太low了,可以编写一个类似这种的正则表达式^1[3-9]\d{9}$
瞬间悟了,不得不说这个面试官人真很好。感动了😋
跨域如何解决
面试官: 我看你这是一个全栈项目啊,那你是怎么解决跨域问题的?
我说: 在后端中我是直接通过koa引入那个第三方的库cors来解决的 ,前端的话在项目部署的时候可以用nginx做反代理。
这时面试官打断我说,不用这么复杂再想想,大脑再次萎缩😱
面试官说: 唉呀,哪里需要这么复杂,可以使用JSONP来绕过同源策略的技术,从外部服务器获取数据并执行回调函数,这样不就解决了吗。
pinia刷新数据丢失问题
这又碰到知识盲区了,面试官问我有没有遇到过pinia刷新数据丢失的问题,我心想pinia在浏览器刷新时还会丢失??
此时的我又只能厚着脸皮的说,没有碰到过这个问题。
这个时候面试官看不下去了,只好又一次纠正我,他说:
在使用Pinia作为状态管理库时,会遇到页面刷新导致数据丢失的问题,也就是说当浏览器刷新页面时,Pinia中的状态会被重置为它的初始状态。
这是因为pinia它的设计就是为了方便的管理应用的状态而不是要实现数据的持久化,当浏览器刷新时,整个应用的状态会被重新初始化,Pinia的状态也会回到初始值。
为了解决这个问题可以手动实现数据持久化,就是说用localStorage或sessionStorage来存储数据。
路由的跳转方式,如何携带参数,有两种
面试官:我看你用到了路由啊,你来说一下路由跳转有几种携带参数的方法。
我心想,这我熟,于是开始和面试官大吹特吹。😏
- 声明式导航 ()
<template>
<div>
<router-link :to="{ name: 'user', params: { userId: 123 }}">Go to User Page</router-link>
</div>
</template>
在这个示例中,我们使用 params 属性来传递参数。假设你有一个名为 user 的路由,它接受一个 userId 参数。
- 程序式导航 (router.push)
router.push({ path: '/user', query: { userId: 123 } });
如何获取当前路由实例中的参数?
const route = useRoute();
// 从 params 获取 userId
const userIdFromParams = ref(route.params.userId);
// 从 query 获取 userId
const userIdFromQuery = ref(route.query.userId);
nextTick
刚装完x,又碰到了一个不会的问题。
面试官让我讲讲vue中的nextTick,然后我就开始了我的小丑时刻。🤡
我说: process.nextTick 提供了一种快速执行回调的方法,可以模拟一些异步任务,会在同步操作完成之后立即执行。
面试官此时无语了😶,我要你说的是vue中的nextTick。
又又又懵了😰
面试官: Vue中dom的更新是异步的,批量更新的,我们放在nextTick中的回调函数它不会立刻执行,而是等数据更新、DOM更新完成之后再执行的这样我们就可以拿到最新的数据,也就是说nextTick方法将回调延迟到下次的DOM更新循环之后再执行。
v-if和v-show的区别
这个问题就是老生常谈了,v-if直接会销毁dom而v-show只是修改css中的display属性来隐藏
watch的深度监听
watch 选项用于侦听数据的变化,并在数据变化时执行相应的操作。如果你需要深度监听一个对象,可以通过将 deep 选项设置为 true 来实现深度监听。
当 deep 选项被设置为 true 时,Vue 会递归地深入对象的每个层级,监听所有的属性变化。这是因为 Vue 通过它的响应式系统来跟踪数据的变化,它使用 Object.defineProperty 方法来劫持对象的属性,当属性发生变化时,相关的依赖就会得到通知并触发更新。
<template>
<div>
<p>Name: {{ user.name }}</p>
<p>City: {{ user.address.city }}</p>
<input type="text" v-model="user.name">
<input type="text" v-model="user.address.city">
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
const user = ref({
name: 'Alice',
age: 30,
address: {
city: 'Beijing',
country: 'China'
}
});
// 使用 watch 函数进行深度监听
watch(user, (newVal, oldVal) => {
console.log('User object changed:', newVal, oldVal);
}, { deep: true });
</script>
v-for里面的key有什么作用
这涉及到虚拟DOM的问题,使用key可以帮助Vue更准确地识别到每一个元素,可以更高效地更新DOM,可以避免不必要的渲染。
如何阻止事件冒泡
乍一听,我沉默了,事件?冒泡?这啥?😂
然后面试官又给解释了一下:就是点击事件如何阻止他冒泡,比如div的嵌套,里面的div点击事件不会影响到外面的div
这让我有点印象了,事件冒泡就是类似下面这个场景。
点击蓝色时,会同时触发三个事件,这就是事件冒泡。解决它可以通过使用event.stopPropapgation()
<div id="parent">
<button id="child">Click me!</button>
</div>
<script>
const parent = document.getElementById('parent');
const child = document.getElementById('child');
parent.addEventListener('click', event => {
alert('Parent clicked!');
});
child.addEventListener('click', event => {
alert('Child clicked!');
event.stopPropagation(); // 阻止事件冒泡到父元素
});
</script>
vue里面的指令集
v-on , v-bind , v-model , v-on , v-text , v-html ,v-if , v-else ,v-show
vue常见的修饰符
vue提供了一些修饰符来增强指令集的功能,通常用于v-on
和v-model
指令
v-on下的修饰符
v-on.stop 阻止事件冒泡
v-on.prevent 阻止默认行为
v-on.once 只触发一次
v-modle的修饰符
v-model.lazy 在change事件而不是input事件同步
v-model.number 将输入的值转为Number类型
v-model.trim 过滤掉用户输入的首位空格
路由懒加载:
路由懒加载是一种优化技术,主要用于改善大型应用的加载性能(尽量往性能优化上面扯),它是通过按需加载组件,而不是一次性加载整个应用的所有模块,从而减少了加载时的资源消耗。
{
path: "/account/management",
name: "Management",
component: () => import("@/views/account/components/informationManagement.vue"),
meta: {
title: '账号管理'
}
}
以这种方式导入则为路由懒加载
总结
在面试之前,一直都很紧张,在想到时候答不出来怎么办。其实在面试的时候反而不紧张了,就像是在和老学长聊天聊聊技术,总之感谢我的第一位面试官,一直都在耐心的教我,让我消除了对面试的恐惧。最后也是得到了一个好消息,一面顺利通过了,学习的动力瞬间暴涨。
好了,这篇文章就到这里了,祝大家早日找到心仪的工作,谢谢大家。
转载自:https://juejin.cn/post/7397628739886104611