一直以来没太有记录面试题的习惯,以前1天两三个面试,现在1个月只有二三个面试,但是随着面试机会慢慢减少,就记录一下吧,以后会慢慢补充答案。如果答案不准确,希望大家在评论区告诉我
2023.08.14 去面了一家小公司,公司环境实在太差了,无法用语言形容。面试题如下(只记得这么多了) 如果有兴趣,可以进入球球裙,console.log(795477608) 2023.8.16 今天又去参加一场面试,一个国企,那个面试官面无表情,像僵尸就一样,其实我对干互联网的国企我都是啧啧。。。。我都不想和他说话,不过在这记录一下面试题,只记得这么多
js篇
1. 说下线程和进程(第一次遇见问这个问题)
进程:一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。
线程:进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。
与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
2. 说下堆和栈(这个也是第一次遇见)
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、http和https的区别
HTTP(Hypertext Transfer Protocol)和HTTPS(Hypertext Transfer Protocol Secure)是用于在客户端和服务器之间传输数据的协议。它们之间的主要区别在于安全性和数据传输方式:
-
安全性:HTTP是明文传输协议,数据在传输过程中不加密,因此容易被恶意攻击者截取和篡改。而HTTPS通过使用SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议对数据进行加密和身份验证,确保数据在传输过程中的安全性。
-
数据传输方式:HTTP使用的默认端口是80,而HTTPS使用的默认端口是443。HTTP的数据传输是明文的,而HTTPS的数据传输是加密的
-
证书:为了使用HTTPS,服务器需要获得一个数字证书,该证书由权威机构颁发,用于验证服务器的身份和加密通信。而HTTP不需要使用证书。 总结来说,HTTPS比HTTP更安全,因为它通过加密数据传输来保护用户的隐私和安全。在处理敏感信息(例如登录凭证、支付信息等)时,建议使用HTTPS来确保数据的安全传输。
4、get和post的区别
get和post是HTTP协议中常用的两种请求方法,它们之间的主要区别如下:
- 数据传输方式: - GET:通过URL参数传递数据,数据会附加在URL的末尾,以键值对的形式出现,例如:
GET请求通常用于获取数据,对服务器的数据不会产生影响。
- POST:通过请求体传递数据,数据不会附加在URL上,而是作为请求的一部分发送。POST请求通常用于提交数据,对服务器的数据进行修改添加。
-
数据传输安全: - GET:数据以明文形式出现在URL上,因此在传输过程中不够安全。适用于非敏感数据。 - POST:数据通过请求体传输,不会直接暴露在URL上,相对更安全。适用于敏感数据。
-
数据长度限制: - GET:由于数据附加在URL上,URL的长度受限制,不适合传输大量数据。 - POST:由于数据在请求体中传输,没有URL长度限制,适合传输大量数据。
-
缓存: - GET:请求会被浏览器缓存,可以通过浏览器的后退按钮重新加载页面。 - POST:请求不会被浏览器缓存,重新加载页面时会重新发送请求。
-
安全性: - GET:由于数据暴露在URL上,容易被恶意攻击者截取和篡改。 - POST:相对于GET请求,POST请求的数据传输更加安全,因为数据不会直接暴露在URL上。
综上所述,GET适合用于获取数据,POST适合用于提交数据,根据具体的需求和数据的安全性要求选择合适的请求方法。
5. 从输入url到展示页面的过程
- 输入URL并回车,浏览器将URL发送到DNS服务器解析域名,得到网站的IP地址。
- 浏览器与网站服务器建立TCP连接,发送HTTP请求报文。请求报文中包含请求的URL、方法(GET或POST)、HTTP协议版本号等信息。
- 网站服务器接收到请求后,找到请求的资源(网页文件),并构建HTTP响应报文。响应报文中包含状态码(200表示成功)、内容类型(text/html)、网页内容等信息。
- 网站服务器将HTTP响应报文发送给浏览器。
- 浏览器接收到响应报文,解析HTML内容并开始加载外部资源(图片、CSS、JS文件等)。
- 浏览器将HTML文档转换成DOM树,CSS文件转换成CSSOM,JS文件编译成机器码,渲染引擎开始构建渲染树。
- 渲染引擎将渲染树渲染到浏览器窗口,展示网页内容。
- 如果网页中有JS脚本,还会执行JS代码,与用户互动,动态更新页面。
- 当用户浏览网页或点击链接时,重复步骤1~8,加载新页面或资源。
以上就是浏览器从输入URL到展示页面的过程。实际上,这个过程还涉及到许多细节,比如缓存、编码、安全等方面,但总体来说,可以归结为输入URL -> 解析域名 -> 建立连接 -> 发送请求与响应 -> 渲染页面 -> 执行脚本 这几个步骤。
6. css加载会造成阻塞吗
CSS加载会造成浏览器的渲染阻塞。这是因为:
- 浏览器在解析HTML文档时,会遇到link标签加载外部CSS文件,此时浏览器会暂停HTML解析,直到CSS文件加载完成。
- 浏览器需要构建DOM树和CSSOM,并将两者合并成渲染树,才能开始页面渲染。如果CSS文件没有加载完成,浏览器无法构建渲染树,因此无法渲染页面。
- CSS的加载和解析是同步的,浏览器需要等待CSS文件完全加载和解析完成后才会继续渲染页面。 以上三个原因会造成CSS加载对浏览器的渲染产生阻塞效应。
为了避免这种阻塞,我们可以采取以下措施:
- 将CSS代码内联在HTML文档中,而不是使用外部CSS文件。这可以避免浏览器暂停HTML解析等待CSS文件加载的阻塞。
-
- 使用media属性为CSS文件指定media类型,使其只在特定媒体加载。例如:
html
<link rel="stylesheet" media="print" href="print.css">
- 使用CSS预加载技术preload,提前加载CSS文件,避免其加载阻塞页面渲染。例如:
html
<link rel="preload" href="style.css" as="style">
<link rel="stylesheet" href="style.css">
- 使用CSS异步加载库,如loadCSS,可以异步加载CSS文件,避免其加载造成的阻塞。
- 将CSS代码拆分成多个文件,并采用上述方法加载,可以减少单个CSS文件对渲染的阻塞时间。 综上,CSS的加载会对浏览器的渲染产生一定的阻塞效应,我们可以通过各种方法来优化,减少这种阻塞。
7. 说下tcp和http
TCP(传输控制协议)和HTTP(超文本传输协议)是计算机网络中的两个重要协议。
TCP是一种可靠的传输协议,用于在网络上可靠地传输数据。它提供了面向连接的通信方式,确保数据的可靠性和顺序性。
TCP使用三次握手建立连接,然后通过序列号和确认应答来保证数据的可靠传输。它还具备流量控制和拥塞控制的机制,以确保网络的稳定性和公平性。
HTTP是一种应用层协议,用于在Web上传输超文本文档。它是基于客户端-服务器模型的协议,客户端发送HTTP请求,服务器返回HTTP响应。HTTP使用URL(统一资源定位符)来定位资源,并使用不同的方法(如GET、POST、PUT、DELETE等)来对资源进行操作。它还支持状态管理和会话管理等功能,使得Web应用能够实现用户认证、数据交互等操作。
TCP和HTTP之间的关系是,HTTP是建立在TCP协议之上的。在进行HTTP通信时,首先需要建立TCP连接,然后在该连接上发送HTTP请求和接收HTTP响应。
总结一下,TCP是一种传输协议,用于可靠地传输数据,而HTTP是一种应用层协议,用于在Web上传输超文本文档。它们在计算机网络中扮演着不同的角色,但在Web通信中密切配合,确保数据的可靠传输和资源的访问。
8. dns缓存
当我们第一次访问某个网站时,DNS在返回对应的IP地址后,系统会将这个记录临时存储下来,并为其设定一个有效期限(TTL),在有效期限内再次访问该网站,系统会直接将该结果返回,而无需求助DNS系统进行全球查询。这个临时储存下来的记录就是DNS缓存。如果超过DNS缓存的有效期限再次对该网站,系统会自动再次询问DNS服务器以获得最新的结果。
DNS缓存有什么作用?
DNS域名解析采用的是UDP协议通讯,受外部网络环境的影响较大,尤其是在有丢包的情况下会产生较高的时延,严重影响用户上网体验,而DNS缓存机制就是在这种背景下产生的。
DNS缓存可以在用户发起请求时,直接将记录结果返回,不需要委托递归服务器进行全球查询,这样就极大提升了DNS域名解析效率,减小了多次查询所带来的时延问题。此外,由于不必每次都请求权威解析服务器进行查询,所以缓存机制还能大幅节省权威服务器的性能消耗,减轻权威服务器的请求压力。
DNS缓存的缺点
DNS缓存虽然能够在一定程度上提升域名解析的速度,但同样也存在一些弊端,如DNS缓存需要消耗一定的系统资源,增加了域名系统的复杂性。此外TTL值的设置对于平衡DNS解析速度和精度产生了较大影响。如果TTL值较短,能够在较短时间内刷新最新解析记录,但会对解析服务器造成较大压力;如果TTL过大,则可能导致地址变更时,用户无法及时获得最新记录,从而导致站点不可达或者访问到错误网站,影响正常业务开展,并增加DNS被劫持的风险。
9.说下浏览器的垃圾回收
浏览器的垃圾回收(Garbage Collection)是指浏览器自动管理和回收JavaScript代码中不再使用的内存空间的过程。由于JavaScript是一种高级动态语言,开发者无需手动分配和释放内存,因此浏览器的垃圾回收机制非常重要。
浏览器的垃圾回收器主要负责以下几个方面:
- 标记清除(Mark and Sweep):这是最常见的垃圾回收算法。垃圾回收器会周期性地遍历所有的对象,并标记出活动对象和不活动对象。然后,它会清除那些没有被标记的不活动对象,释放它们占用的内存空间。
- 引用计数(Reference Counting):这是另一种常见的垃圾回收算法。垃圾回收器会为每个对象维护一个引用计数器,当对象被引用时计数器加一,当引用失效时计数器减一。当计数器为零时,垃圾回收器会清除该对象。然而,引用计数算法无法处理循环引用的情况,因此现代浏览器很少使用该算法。
- 分代回收(Generational Collection):这是一种优化的垃圾回收策略。根据对象的生命周期将内存分为不同的代(generation),并为每个代应用不同的回收策略。通常,新创建的对象会被分配到第一代,而经过多次垃圾回收仍然存活的对象则会被提升到下一代。这种策略可以提高垃圾回收的效率。
浏览器的垃圾回收器通常在空闲时执行垃圾回收操作,以避免影响页面的性能。然而,垃圾回收的执行时间仍然会对页面的响应性产生一定的影响。因此,开发者应该尽量避免创建大量临时对象,减少内存占用,优化代码结构,以提高浏览器的性能和响应速度。
10.什么是内存泄露
在前端开发中,内存泄露指的是在网页或应用程序中,分配的内存空间没有被正确释放或回收,导致这部分内存无法再被程序使用,从而造成内存资源的浪费。
在前端中,内存泄露通常发生在使用JavaScript等脚本语言编写的网页或应用程序中。以下是一些常见的导致内存泄露的情况:
- 未正确释放事件监听器:如果在网页中添加了事件监听器(如点击事件、滚动事件等),但在元素被移除或页面卸载时没有正确移除这些监听器,就会导致内存泄露。
- 引用计数错误:在JavaScript中,对象的引用计数是用来决定何时释放对象内存的一种机制。如果存在循环引用,即两个或多个对象相互引用,但没有其他地方引用它们,那么这些对象的内存就无法被垃圾回收机制释放,从而导致内存泄露。
- 定时器未清理:在使用定时器(如
setTimeout、setInterval)时,如果没有正确清理定时器,即使页面或应用程序关闭,定时器仍然会持续运行,导致内存泄露。 - 全局变量未释放:如果在全局作用域中定义了变量或对象,并且这些变量或对象没有被及时清除或释放,就会导致内存泄露。
内存泄露会导致网页或应用程序占用过多的内存资源,从而影响性能和用户体验。为了避免内存泄露,开发者应该注意及时释放不再使用的资源、正确管理事件监听器、避免循环引用等。同时,使用浏览器的开发者工具和内存分析工具可以帮助检测和解决内存泄露问题。
11.js中原型和原型链指的是什么?
JavaScript中的原型(Prototype)和原型链(Prototype Chain)是理解JavaScript对象和继承的重要概念。
JS的每个函数在创建的时候,都会生成一个属性prototype,这个属性指向一个对象,这个对象就是此函数的原型对象
当我们访问一个对象的属性时,如果该对象本身没有该属性,JavaScript会自动去它的原型对象中查找该属性。这种属性查找的过程称为原型链。
具体来说,当我们访问一个对象的属性时,JavaScript引擎首先会在对象本身的属性中查找,如果找到了就返回该属性值。如果没有找到,它会继续在原型对象中查找,如果找到了就返回该属性值。如果仍然没有找到,它会继续在原型对象的原型对象中查找,直到找到该属性或到达原型链的末尾(即原型为null)为止。
通过原型和原型链,我们可以实现对象之间的继承。当我们创建一个对象时,可以指定其原型对象,从而让该对象继承原型对象的属性和方法。这样,我们可以通过原型链实现属性和方法的共享和复用。
在JavaScript中,原型和原型链是隐式的,但我们可以通过 __proto__ 属性(非标准)或 Object.getPrototypeOf() 方法来访问和操作对象的原型。
此外,ES6引入了 class 和 extends 关键字,提供了更简洁的语法来定义和继承对象。
总结起来,原型和原型链是JavaScript中实现对象和继承的基础机制,理解它们对于深入理解JavaScript的对象模型和继承机制非常重要。
12.什么是BFC
BFC是块级格式化上下文(Block Formatting Context)的缩写。它是Web页面中的一种CSS渲染机制,用于控制块级盒子的布局及浮动元素与其他元素的交互行为。BFC具有独立的布局空间和渲染规则,可以避免元素之间的相互影响,使得页面的布局更加稳定和可靠。
13.var let const区别?
var、let和const是JavaScript中声明变量的关键字,它们之间有一些区别。
- var:在ES5及之前的版本中使用的声明变量的关键字。它具有函数作用域或全局作用域,而没有块
var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错
2.var不存在暂时性死区
let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
3.var不存在块级作用域
let和const存在块级作用域
4.var允许重复声明变量
let和const在同一作用域不允许重复声明变量
5.var和let可以修改声明的变量
const声明一个只读的常量。一旦声明,常量的值就不能改变
能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var
14.map和set的区别
在JavaScript中,Map和Set是两种不同的数据结构,它们有以下区别:
- 存储的数据类型:Map可以存储键值对(key-value pair),而Set只能存储唯一的值,不允许重复。
- 键的类型:Map的键可以是任意数据类型,包括基本数据类型和引用数据类型,而Set只能存储引用数据类型。
- 迭代顺序:Map会按照插入的顺序保持键值对的迭代顺序,而Set不保证迭代顺序与插入顺序一致。
- 键的唯一性:Map中的键是唯一的,不会出现重复的键,而Set中的值也是唯一的,不会出现重复的值。
- 大小和性能:Map可以通过size属性获取键值对的数量,而Set可以通过size属性获取值的数量。在大规模数据操作时,Map的性能比Set略低。 根据具体的需求,选择使用Map还是Set会有所不同。如果需要存储键值对并需要按照插入顺序进行迭代,可以使用Map。如果只需要存储唯一的值,并且不关心顺序,可以使用Set。
15.正向代理和反向代理指的是什么?
在Web前端中,正向代理(Forward Proxy)和反向代理(Reverse Proxy)是两种不同的代理服务器的概念。
-
正向代理:正向代理是客户端与目标服务器之间的中间服务器。当客户端请求访问目标服务器时,请求首先发送到正向代理服务器,然后由代理服务器转发请求给目标服务器,并将响应返回给客户端。客户端对目标服务器的存在是不可见的,目标服务器也无法感知到客户端的真实IP地址。正向代理常用于访问被限制或阻止的资源,或者提供缓存、加速、安全性等功能。
-
反向代理:反向代理是位于目标服务器前面的中间服务器。当客户端发送请求时,请求首先发送到反向代理服务器,然后由代理服务器根据一定的规则将请求转发给后端的目标服务器进行处理。客户端对目标服务器的存在是不可见的,目标服务器也无法感知到客户端的真实IP地址。反向代理常用于负载均衡、缓存、安全性等方面,可以提高系统的可靠性、可伸缩性和安全性。
总结来说,正向代理是客户端通过代理服务器访问目标服务器,而反向代理是客户端通过代理服务器访问后端的目标服务器。它们在代理的方向和作用上有所不同,但都可以用于提供访问控制、性能优化和安全性等功能。
正向代理和反向代理的异同点
同: 1、正向代理和反向代理中的服务器都是对请求和响应进行转发。 2、都能提高访问速度。 3、帮助客户端或业务服务器隐藏真实的IP。
异: 1、部署的位置不同 正向代理部署在客户端,反向代理部署在服务器端。 2、作用不同 正向代理是客户端的代理,帮助客户端突破访问控制;反向代理是服务器的代理,帮助服务器实现负载均衡,安全防护。
16.事件循环
同步代码,一行一行放在调用栈中去执行。 遇到异步代码,会先记录下代码,等待执行时机(setimeout, ajax)。时机到了,将之前记录的代码放入回调函数队列。当调用栈为空,也就是同步代码执行完,eventloop开始工作。eventloop会轮询查找回调函数队列中是否有可执行的代码,如有,将代码放入调用栈中执行。没有,则会轮询查找。
17.虚拟dom
虚拟DOM(Virtual DOM)是一种在Web开发中常用的概念。它是基于JavaScript对象的表示,用于描述真实DOM(Document Object Model)的层次结构和状态。
在传统的Web开发中,直接操作真实DOM是比较昂贵的操作,因为每次更新都需要重新计算布局和重新渲染。而虚拟DOM的思想是,通过创建一个轻量级的JavaScript对象树来模拟真实DOM的结构和状态。在组件或数据发生变化时,先对虚拟DOM进行操作和计算,然后将变化应用到真实DOM上,这样可以减少对真实DOM的直接操作,提高性能和效率。
虚拟DOM的工作流程一般包括以下几个步骤:
-
初始化:将真实DOM的结构和状态转化为虚拟DOM的JavaScript对象表示。
-
渲染:根据虚拟DOM的JavaScript对象创建真实DOM树,并将其插入到文档中。
-
更新:当组件或数据发生变化时,对比新旧虚拟DOM的差异,生成更新操作序列。
-
应用更新:根据更新操作序列,将变化应用到真实DOM上,更新页面显示。
虚拟DOM的优势在于它可以提供更高效的DOM操作和渲染,减少直接操作真实DOM所带来的性能损耗。同时,虚拟DOM也提供了一种抽象层,使得开发者可以更方便地对组件进行操作和管理。
18.js的运行机制
其实就是讲eventloop,可以看18题
19.settimeout怎么解决倒计时时间偏差的问题
在处理倒计时时间偏差的问题时,可以使用 setTimeout 结合当前时间来进行校准。以下是一种解决方案:
- 获取当前时间戳:使用
Date.now()获取当前的时间戳。 - 计算倒计时时间差:计算目标时间与当前时间的时间差,得到倒计时的剩余毫秒数。
- 设置
setTimeout:使用setTimeout函数设置一个定时器,延迟等于倒计时时间差的毫秒数。 - 倒计时结束处理:当定时器触发后,执行倒计时结束的处理逻辑。 这种方法可以通过动态计算当前时间与目标时间的差异来校准倒计时,从而避免时间偏差的问题。 以下是一个示例代码:
javascript
function startCountdown(targetTime) {
const currentTime = Date.now();
const timeDifference = targetTime - currentTime;
if (timeDifference <= 0) {
// 倒计时结束的处理逻辑
console.log("倒计时结束");
return;
}
setTimeout(() => {
// 倒计时结束的处理逻辑
console.log("倒计时结束");
}, timeDifference);
}
// 示例使用:设置目标时间为当前时间加上 10 秒
const targetTime = Date.now() + 10000;
startCountdown(targetTime);
通过这种方式,即使在 setTimeout 的延迟期间存在一些微小的时间偏差,倒计时仍然可以准确地结束。
20.怎么创建一个class
通过使用 class 关键字,你可以方便地创建和使用类,使代码更加模块化和可维护。
vue
1.vue路由守卫有什么 用处
Vue 路由守卫是一种在导航过程中对路由进行控制和验证的机制。它们允许您在路由切换前、切换后或者在路由更新时执行一些特定的操作。路由守卫可以用于实现诸如权限验证、登录验证、页面加载状态管理等功能。 Vue 提供了三种类型的路由守卫:
-
全局前置守卫(beforeEach):在路由切换前执行,可以用于进行登录验证、权限验证等操作。可以通过调用
next()来继续导航,或者通过调用next(false)来取消导航。 -
全局解析守卫(beforeResolve):在路由被确认之前执行,用于确保异步路由组件被解析。
-
全局后置守卫(afterEach):在路由切换后执行,可以用于执行一些清理操作或者统计页面浏览量等。 此外,还可以为每个路由配置独立的路由守卫,这些守卫将在特定路由被激活时执行。
这些独立的守卫包括: - 路由独享的守卫(beforeEnter):在特定路由被激活之前执行。 - 组件内的守卫:在组件内部通过
beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave来定义。 通过使用这些路由守卫,您可以在路由切换的不同阶段执行相应的操作,从而实现更加灵活和精确的路由控制。
2.vue异步组件怎么加载的
Vue中的异步组件可以通过两种方式进行加载:使用工厂函数或使用import函数。
- 使用工厂函数: 在Vue 2中,可以使用工厂函数来定义异步组件。工厂函数返回一个Promise对象,该Promise对象在解析时会动态地加载组件。
javascript
Vue.component('AsyncComponent', function (resolve, reject) {
setTimeout(function () {
resolve({
template: '<div>This is an async component.</div>'
});
}, 2000);
});
在上述示例中,定义了一个名为 AsyncComponent 的异步组件。在工厂函数内部,通过setTimeout模拟一个异步操作,2秒后通过resolve返回组件的定义。
- 使用import函数: 在Vue 2.4及以上版本和Vue 3中,可以使用import函数来定义异步组件。import函数返回一个Promise对象,在解析时会动态地加载组件。
javascript
Vue.component('AsyncComponent', () => import('./AsyncComponent.vue'));
在上述示例中,通过import函数异步地加载名为 AsyncComponent 的组件。在import函数中指定组件的路径,Vue会自动处理异步加载并渲染组件。 无论是使用工厂函数还是import函数,Vue都会在需要时自动地异步加载组件,从而提高应用的性能和加载速度。异步组件在需要时才会被加载和渲染,可以减少初始加载时的资源负担,提高用户体验。
3.vue中权限是怎么设置的?
在Vue中设置权限可以通过以下几种方式: 1. 路由权限控制:在Vue Router中可以通过路由元信息(meta)来定义路由的权限要求。您可以在路由配置中为每个路由添加一个meta字段,并将权限信息存储在其中。然后,在全局前置守卫(beforeEach)中,可以根据用户的权限来判断是否允许访问该路由。
javascript
// 路由配置
const routes = [
{
path: '/admin',
name: 'Admin',
component: Admin,
meta: { requiresAuth: true } // 需要登录权限
},
// ...
];
// 全局前置守卫
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login'); // 没有权限,跳转到登录页面
} else {
next(); // 有权限,继续导航
}
});
- 组件级权限控制:在组件中可以根据用户的权限来决定是否显示或执行特定的操作。您可以在组件中使用条件语句或计算属性来判断用户的权限,并根据权限来渲染不同的内容或执行不同的逻辑。
vue
<template>
<div>
<button v-if="hasPermission('create')">Create</button>
<button v-if="hasPermission('edit')">Edit</button>
<button v-if="hasPermission('delete')">Delete</button>
</div>
</template>
<script>
export default {
methods: {
hasPermission(permission) {
// 根据用户权限判断是否有权限
return this.userPermissions.includes(permission);
}
}
};
</script>
- API权限控制:在与后端交互的过程中,可以根据后端返回的用户权限信息来控制前端的行为。例如,在获取数据或提交数据时,可以根据用户的权限来决定是否允许进行相应的操作。 这些方法可以根据您的具体需求和项目结构来选择使用。根据您的权限设置,您可以在路由层面、组件层面或者与后端交互的层面来进行权限控制。
4. 用vue 根据后端返回的三级菜单数据动态挂载到前端路由中
根据后端返回的三级菜单数据动态挂载到前端路由中,可以按照以下步骤进行操作:
首先,从后端获取三级菜单数据,假设数据格式如下:
[
{
"name": "Dashboard",
"path": "/dashboard",
"children": [
{
"name": "Overview",
"path": "overview",
"component": "Overview"
},
{
"name": "Analytics",
"path": "analytics",
"component": "Analytics"
}
]
},
{
"name": "Products",
"path": "/products",
"children": [
{
"name": "List",
"path": "list",
"component": "ProductList"
},
{
"name": "Details",
"path": "details",
"component": "ProductDetails"
}
]
}
]
接下来,在Vue的路由配置文件中,使用递归的方式将三级菜单数据动态挂载到前端路由中:
// router.js
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
// ...
];
const router = new Router({
routes
});
// 递归函数,用于动态挂载菜单数据到路由
function addRoutes(menuData, parentPath = '') {
menuData.forEach(menu => {
const route = {
path: parentPath + menu.path,
name: menu.name,
component: () => import(`@/views/${menu.component}.vue`) // 动态导入组件
};
if (menu.children && menu.children.length > 0) {
route.children = [];
addRoutes(menu.children, route.path + '/');
}
router.addRoute(route); // 动态添加路由
});
}
// 在获取到后端返回的菜单数据后,动态添加到路由表中
import axios from 'axios';
axios.get('/api/menu') // 假设后端菜单接口为 '/api/menu'
.then(response => {
const menuData = response.data; // 后端返回的菜单数据
addRoutes(menuData);
});
export default router;
在上面的示例中,我们使用递归函数 addRoutes 来动态挂载菜单数据到路由。首先遍历菜单数据,根据每个菜单项创建一个路由对象,并使用 import() 函数动态导入对应的组件。如果菜单项有子菜单,则递归调用 addRoutes 函数来处理子菜单。最后使用 router.addRoute() 方法将动态生成的路由添加到路由表中。
通过这种方式,您可以根据后端返回的三级菜单数据动态挂载到前端路由中。
今天又远程面了一家小公司,第一轮面试全是vue的相关问题,原理什么 的,就不写了。第二轮是一个后端问的,问了一些问题,我以前确实看过,但是没仔细记过,先记录下吧
5. webpack热更新的原理
- 通过
webpack-dev-server创建两个服务器:提供静态资源的服务(express)和Socket服务 - express server 负责直接提供静态资源的服务(打包后的资源直接被浏览器请求和解析)
- socket server 是一个 websocket 的长连接,双方可以通信
- 当 socket server 监听到对应的模块发生变化时,会生成两个文件.json(manifest文件)和.js文件(update chunk)
- 通过长连接,socket server 可以直接将这两个文件主动发送给客户端(浏览器)
- 浏览器拿到两个新的文件后,通过HMR runtime机制,加载这两个文件,并且针对修改的模块进行更新
6. 说下前端路由
SPA需要在不刷新页面的情况下做页面更新的能力,这就需要引入前端路由,实际上,前端路由是利用了浏览器的hash或history属性。
hash : hash (url中#后面的部分)虽然出现在 URL 中,但不会被包含在 http 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
当hash改变时,会触发hashchange事件,监听该事件,对页面进行更新。
history : history 利用了 html5 history interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器记录栈,
在当前已有的 back、forward、go 基础之上,它们提供了对历史记录 修改的功能(pushState将传入url直接压入历史记录栈,replaceState将传入url替换当前历史记录栈)。
只是当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求。
4.vue3中组合式api(Composotion API)的好处?
●所有API都是import引入的用到的 功能都import进来,对Tree- shaking很友好,没用到功能,打包的时候会被清理掉,减小包的大小。
●不再上下反复横跳,我们可以把一个功能模 块的methods、data 都放在一起书写,维护更轻松。
●代码方便复用,可以把一个功能所有的 methods、data 封装在一个独立的函数里,复用代码非常容易。
●Composotion API新增的return 等语句, 在实际项目中使用
7. vue首页加载慢怎么解决
Vue.js 是一个用于构建用户界面的 JavaScript 框架,它本身并不会直接导致首页加载缓慢。首页加载缓慢可能有多种原因,以下是一些常见的解决方法:
- 优化代码:确保你的代码是高效的,避免不必要的计算和操作,尽量减少网络请求和资源加载。
- 懒加载:使用懒加载技术,将页面上的一些资源延迟加载,只在需要时再加载,可以提高初始加载速度。
- 代码分割:将代码分割成多个小块,按需加载,这样可以减少初始加载的文件大小,加快页面加载速度。
- 图片优化:对于图片资源,可以使用合适的压缩算法和格式,减小图片文件的大小,提高加载速度。
- CDN 加速:使用内容分发网络(CDN)来加速静态资源的加载,将资源分发到全球各地的服务器,减少网络延迟。
- 缓存策略:合理设置缓存策略,利用浏览器缓存和服务器缓存,减少重复加载资源的次数。
- 服务器性能优化:确保服务器的性能良好,可以考虑使用缓存、压缩、并发处理等技术来提高服务器的响应速度。
以上是一些常见的解决方法,具体的优化策略需要根据你的具体情况来确定。希望对你有所帮助!