前端场景题

1,710 阅读5分钟

1. 一个页面中两个组件,组件中有请求相同的接口,如何保证两个数据一致?

  • 组件间数据传递:通过一个父组件将接口数据获取并存储在其状态中,然后将数据作为属性传递给两个子组件。这样两个子组件都使用同一个数据源,确保数据一致性。
  • 全局状态管理:使用状态管理库(例如Redux、Vuex等)来管理应用程序的状态。将接口数据存储在全局状态中,并从两个组件中访问相同的数据源。当接口数据更新时,全局状态会自动更新,保持两个组件的数据一致性。
  • 事件总线/发布订阅模式:使用事件总线或发布订阅模式来实现组件间的通信。当接口数据获取并更新时,触发一个事件,订阅该事件的两个组件会同时接收到通知,从而更新自己的数据。
  • 缓存机制:在客户端中使用缓存机制,例如浏览器的本地存储(localStorage或sessionStorage)或内存缓存。当一个组件请求接口数据时,先检查缓存中是否存在相同的数据,如果存在则使用缓存数据,否则发送请求获取数据,并将数据存储在缓存中。这样,第二个组件在请求相同接口时可以从缓存中获取数据,确保数据一致性。

2. 实现检测页面卡顿,连续三次卡顿后设置状态卡顿,并三秒后重新开始检测。

可以使用requestAnimationFrameperformance.now()方法来实现。

let isPageStuck = false;
let consecutiveStucks = 0;
let startTime;

function checkPageStuck() {
  const currentTime = performance.now();
  const elapsedTime = currentTime - startTime;

  // 如果超过卡顿阈值,增加连续卡顿次数
  if (elapsedTime > 300) {
    consecutiveStucks++;

    // 如果连续卡顿次数达到3次,设置卡顿状态
    if (consecutiveStucks >= 3) {
      isPageStuck = true;
      console.log('页面卡顿!');
      stopPageStuckDetection();

      // 三秒后重新开始检测
      setTimeout(function() {
        isPageStuck = false;
        consecutiveStucks = 0;
        console.log('重新开始检测页面卡顿');
        startPageStuckDetection();
      }, 3000);
    }
  } else {
    // 如果没有卡顿,重置连续卡顿次数
    consecutiveStucks = 0;
  }

  startTime = currentTime;
  requestAnimationFrame(checkPageStuck);
}

function startPageStuckDetection() {
  isPageStuck = false;
  consecutiveStucks = 0;
  startTime = performance.now();
  requestAnimationFrame(checkPageStuck);
}

function stopPageStuckDetection() {
  isPageStuck = false;
  consecutiveStucks = 0;
}

// 在页面加载完成后开始检测页面卡顿
window.addEventListener('load', function() {
  startPageStuckDetection();
});

3. 多个组件都调用了同一个接口,不更改组件内在的逻辑,如何让请求只发一次?

可以使用请求拦截器来实现

// main.js

import Vue from 'vue';
import axios from 'axios';

// 创建一个axios实例
const api = axios.create({
  baseURL: 'http://your-api-url.com'
  // 其他axios配置项...
});

let isRequestPending = false; // 标识请求是否正在进行

// 添加请求拦截器
api.interceptors.request.use(config => {
  if (!isRequestPending) {
    isRequestPending = true;
    return config;
  }
  // 如果已经有请求正在进行,取消当前请求
  return Promise.reject(new Error('Request canceled'));
});

// 添加响应拦截器
api.interceptors.response.use(
  response => {
    isRequestPending = false; // 标识请求完成
    return response;
  },
  error => {
    isRequestPending = false; // 标识请求完成
    return Promise.reject(error);
  }
);

Vue.prototype.$api = api;

new Vue({
  // Vue实例的配置...
}).$mount('#app');

4. sso单点登录怎么实现

  • 单点登录(Single Sign-On,简称SSO)是一种身份验证和授权机制,允许用户使用一组凭据(如用户名和密码)登录到多个应用程序或系统,而不需要为每个应用程序单独进行认证。
  • token验证方式实现单点登录
    1. 用户登录,获取后端接口返回的token
    2. 存储token,使用浏览器的本地存储(如LocalStorage或SessionStorage)或使用专门的状态管理库(如Redux或Vuex)
    3. 发送token给后端,请求头中添加Token或在每个请求中添加token。在前端应用程序中,当用户访问其他需要身份验证的应用程序或系统时,你需要将令牌发送给服务提供者进行验证。

5.JWT和token区别

  • JWT(JSON Web Token)是一种特定类型的Token,它采用了JSON格式来存储有关用户身份和访问权限的信息。
  • JWT由三部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature)。头部包含有关JWT的元数据和算法信息,载荷包含实际的用户数据,例如用户ID、角色等,签名用于验证JWT的完整性和真实性。
  • jwt和token区别主要体现在接收的信息是否需要进入数据库查询信息; Token需要查库验证token 是否有效,而JWT不用查库,直接在服务端进行校验,因为用户的信息及加密信息,和过期时间,都在JWT里,只要在服务端进行校验就行,并且校验也是JWT自己实现的;

6.Vue-Router是如何保证URL变化后页面不会刷新

  • Vue Router 使用了浏览器的 History API(pushState、replaceState 和 popstate)或 hash 模式(在 URL 中使用 # 符号)来实现前端路由,而不会引起页面的完全刷新。
  • 当使用 Vue Router 进行路由导航时,它会拦截浏览器默认的导航事件,并使用自己的机制进行处理。
  • 下面是 Vue Router 如何保证 URL 变化后页面不会刷新的基本工作原理:
  1. 捕获导航事件:当用户点击页面上的链接或调用编程式导航(如 $router.push)时,Vue Router 会捕获导航事件。
  2. 更新 URL:Vue Router 使用 History API 或 hash 模式来更新 URL,而不会触发完整页面的刷新。这是通过修改浏览器的历史记录而不导致新的页面请求的。
  3. 响应导航事件:Vue Router 会根据更新后的 URL 和路由配置,找到匹配的组件并进行相应的渲染。
  4. 更新视图:Vue Router 会更新组件的显示,并将新的组件渲染到视图中,而不需要刷新整个页面。它会基于路由匹配到的组件进行局部渲染,以实现页面的部分更新。

通过以上机制,Vue Router 可以在 URL 变化时实现页面的无刷新更新。这种方式可以提供更好的用户体验,避免了完整页面刷新的开销,同时保持了 Vue.js 的单页面应用特性。