前端面试-场景题

1. Vue怎么实现权限管理?

路由权限

方案一:初始化即加载全部路由,并且在路由上添加上相应权限信息,每次路由跳转前做校验。

  • 缺点:
    • 加载所有路由,如果路由很多,而用户不是所有的权限,那么就会造成不必要的加载。
    • 全局路由守卫里,每次路由跳转都要进行权限判断。
    • 菜单信息写死在前端里,要改个权限信息,需要重新编译,适合角色固定的情况,
    • 菜单和路由耦合在一起,定义路由的时候还要添加菜单显示标题,而且路由不一定作为菜单,还要多加字段进行标识。

方案二:初始化时先挂载不需要权限控制的路由,比如登录页404等。如果用户通过URL强制访问,则会直接进入404,相当于从源头控制。
登陆后,获取用户的权限信息,然后筛选有权限访问的路由,在全局路由守卫里进行调用addRoutes添加路由。

  • 缺点:
    • 全局路由守卫里,每次路由跳转都要进行权限判断。
    • 菜单信息写死在前端里,要改个权限信息,需要重新编译,适合角色固定的情况,
    • 菜单和路由耦合在一起,定义路由的时候还要添加菜单显示标题,而且路由不一定作为菜单,还要多加字段进行标识。

菜单权限

方案一:菜单与路由分离,菜单由后端返回,前端定义路由信息。

  • 每次路由跳转的时候都要判断权限,这里的判断也很简单,因为菜单的name与路由的name是一一对应的,而后端返回的菜单就已经是经过权限过滤的。

  • 如果根据路由name找不到对应的菜单,就表示用户有没权限访问。

  • 如果路由很多,可以在应用初始化的时候,只挂载不需要权限控制的路由。取得后端返回的菜单后,根据菜单与路由的对应关系,筛选出可访问的路由,通过addRoutes动态挂载。

  • 缺点

    • 菜单需要与路由做一一对应,前端添加了新功能,需要通过菜单管理功能添加新的菜单,如果菜单配置的不对会导致应用不能正常使用。
    • 全局路由守卫里,每次路由跳转都要做判断。

方案二:菜单和路由都由后端返回

前端统一定义路由组件

1
2
3
4
5
6
const Home = () => import("../pages/Home.vue");
const UserInfo = () => import("../pages/UserInfo.vue");
export default {
home: Home,
userInfo: UserInfo
};

后端路由组件返回以下格式

1
2
3
4
5
6
7
8
9
10
11
12
[
{
name: "home",
path: "/",
component: "home"
},
{
name: "home",
path: "/userinfo",
component: "userInfo"
}
]
  • 在将后端返回路由通过addRoutes动态挂载之间,需要将数据处理一下,将component字段换为真正的组件

  • 如果有嵌套路由,后端功能设计的时候,要注意添加相应的字段,前端拿到数据也要做相应的处理

  • 缺点

    • 前后端配合要求高
    • 全局路由守卫里,每次路由跳转都要做判断。

2. 前端跨页面通信的方法?

  • LocalStorage 或 SessionStorage:这两个 Web 存储 API 可以在不同页面之间共享数据。一个页面可以将数据存储在本地存储中,另一个页面则可以读取该数据并进行相应处理。通过监听 storage 事件,可以实现数据的实时更新。
  • Cookies:使用 Cookies 也可以在不同页面之间传递数据。通过设置和读取 Cookie 值,可以在同一域名下的不司页面之间交换信息。
  • PostMessage: window.postMessage()方法允许从一个窗口向另一个窗口发送消息,并在目标窗口上触发.message 事件。通过指定目标窗口的 origin,可以确保只有特定窗口能够接收和处理消息。
  • Broadcast Channel:Broadcast Channel API 允许在同一浏览器下的不同上下文(例如,在不同标签页或iframe 中)之间进行双向通信。它提供了一个类似于发布-订阅模式的机制,通过创建一个广播频道,并在不同上下文中加入该频道,可以实现消息的广播和接收。
  • SharedWorker:sharedWorker 是一个可由多个窗口或标签页共享的 Web Worker,它可以在不同页面之间进行跨页面通信。通过 SharedWorker,多个页面可以通过 postMessage 进行双向通信,并共享数据和执行操作。
  • IndexedDB:IndexedDB 是浏览器提供的一个客户端数据库,可以在不同页面之间存储和共享数据。通过在一个页面中写入数据,另一个页面可以读取该数据。
  • WebSockets:WebSockets 提供了全双工的、双向通信通道,可以在客户端和服务器之间进行实时通信。通过建立 WebSocket 连接,可以在不同页面之间通过服务器传递数据并实现实时更新。

3. 大文件上传处理?

分片上传

分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(Part)来进行分片上传。上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。

  1. 将需要上传的文件按照一定的分割规则,分割成相同大小的数据块;
  2. 初始化一个分片上传任务,返回本次分片上传唯一标识;
  3. 按照一定的策略(串行或并行)发送各个分片数据块;
  4. 发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件;

断点续传

断点续传指的是在下载或上传时,将下载或上传任务人为的划分为几个部分。
每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度。
一般实现方式有两种:

  • 服务器端返回,告知从哪开始
  • 浏览器端自行处理
    上传过程中将文件在服务器写为临时文件,等全部写完了(文件上传完),将此临时文件重命名为正式文件即可
    如果中途上传中断过,下次上传的时候根据当前临时文件大小,作为在客户端读取文件的偏移量,从此位置继续读取文件数据块,上传到服务器从此偏移量继续写入文件即可。

4. UI组件的二次封装?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div class="container">
<el-input ref="inp" v-bind="$attrs">
<template v-for="(value,name) in $slots" #[name]="slotData">
<slot :name="name" v-bind="slotData"></slot>
</template>
</el-input>
</div>
</template>
<script>
export default defineComponent({
mounted() {
for (const key in this.$refs.baseRef) {
this[key] = this.$refs.baseRef[key];
}
},
});
</script>

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!