当前位置: 首页 > news >正文

前端高频面试题day2

如何在vue3中使用defineAsyncComponent实现异步组件加载

在 Vue 3 中,使用 defineAsyncComponent 实现异步组件加载的步骤如下:

  1. 引入方法:从 Vue 中导入 defineAsyncComponent
  2. 定义异步组件:通过 defineAsyncComponent 包装一个返回 Promise 的工厂函数,Promise 解析后返回组件。
  3. 使用组件:在模板中正常使用该异步组件。

代码示例

import { defineAsyncComponent } from 'vue';const AsyncComp = defineAsyncComponent(() => import('./MyComponent.vue')
);export default {components: { AsyncComp }
};

特点

  • 支持懒加载,优化性能。
  • 可选配置如 loadingComponenterrorComponent 提升用户体验。

v-show和v-if有什么区别?使用场景分别是什么

区别:

  1. 实现方式v-show通过display: none控制显示,元素始终在DOM中;v-if条件为假时直接移除元素,为真时重新渲染。
  2. 性能v-show适合频繁切换(仅改CSS);v-if适合不常变化的条件(初始渲染更轻量)。
  3. 特性v-if支持v-else/v-else-if,切换会触发组件销毁/创建钩子;v-show不支持且不会。

场景:

  • v-show:需频繁切换显示的元素(如快速切换的标签页)。
  • v-if:条件极少变化、复杂组件或初始无需渲染的场景。

vue计算属性的函数名和data中的属性可以同名吗?为什么?

在 Vue 中,计算属性的函数名和 data 中的属性 不可以同名,原因如下:


原因:

  1. 属性覆盖机制
    Vue 将 datacomputed 等属性都挂载到 Vue 实例上。当名称冲突时,后定义的属性会覆盖先定义的属性

    • 初始化顺序为:props → methods → data → computed → watch
    • 因此,若计算属性与 data 同名,计算属性会覆盖 data 中的同名属性,导致 data 中的原始数据无法被访问。
  2. 不可预测的逻辑错误

    • 在模板中使用该名称时,实际调用的是计算属性的结果,而非 data 中的原始数据。
    • 若尝试修改 data 中的同名属性,会因计算属性的只读性导致错误(除非计算属性有 setter)。

Vue 的警告机制

  • 当发生命名冲突时,Vue 会通过控制台输出警告,例如:
    [Vue warn]: The computed property "xxx" is already defined in data.

最佳实践

  1. 命名规范

    • data 属性与计算属性使用不同名称
      data() {return {originalMessage: 'Hello' // 原始数据};
      },
      computed: {uppercaseMessage() { // 计算属性名与 data 区分return this.originalMessage.toUpperCase();}
      }
      
  2. 代码审查

    • 通过 ESLint 或 TypeScript 类型检查避免同名冲突(如定义接口时明确区分字段)。

总结

  • 技术上允许同名,但会导致属性覆盖和逻辑混乱。
  • 强烈建议避免同名,通过清晰的命名规范提升代码可维护性。

如何监听Vuex数据的变化?

在 Vue 中监听 Vuex 数据的变化,可以通过以下几种方法实现,根据场景选择最合适的方案:


1. 计算属性 + watch

  • 适用场景:在组件内监听特定状态的变化。
  • 步骤
    1. 通过计算属性映射 Vuex 状态。
    2. watch 中监听计算属性的变化。

2. 直接使用 watch 监听 Vuex 状态

  • 适用场景:直接监听 Vuex 状态,无需计算属性。
  • 步骤
    1. watch 中直接指定 Vuex 状态的路径。
    2. 可选 deep 选项处理嵌套对象/数组。

3. Vuex 的 store.watch 方法

  • 适用场景:在非组件环境(如工具函数、服务层)监听状态变化。
  • 步骤
    1. 通过 store.watch 传入状态获取函数和回调。
    2. 返回的取消函数用于停止监听。

性能注意事项

  • 嵌套对象/数组:使用 deep: true 时性能开销较大,尽量避免深层监听。
  • 取消监听:在组件销毁前调用 unwatch()unsubscribe(),防止内存泄漏。
  • 优先级:频繁变化的状态建议用计算属性,减少 watch 的回调执行次数。

Vue Router路由守卫

  1. 什么是路由守卫?
    路由守卫是 Vue Router 提供的钩子函数,用于在路由跳转的不同阶段插入控制逻辑(如权限验证、数据预加载、页面标题切换等)。它允许开发者在导航过程中拦截、检查或修改路由行为。

  2. 路由守卫的分类
    Vue Router 的路由守卫分为三类:

    • 全局守卫:对所有路由生效,如 beforeEachbeforeResolveafterEach
    • 路由独享守卫:仅对特定路由生效,定义在路由配置的 beforeEnter 属性中。
    • 组件内守卫:定义在组件内部,如 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave

如何解决前端接口大规模并发问题

一、前端优化方案

  1. 减少请求次数

    • 合并请求(Batch API)
      • 场景:多个小请求合并为一个请求(如实时搜索、分页加载)。
      • 实现:使用防抖/节流或自定义批量接口。
      • 代码示例(防抖合并请求)
        let timer = null;
        const requests = [];
        function debounceRequest() {if (timer) clearTimeout(timer);timer = setTimeout(() => {// 合并请求并发送const batchRequest = requests.map(req => req.params);fetch('/batch-endpoint', { method: 'POST', body: JSON.stringify(batchRequest) }).then(data => handleResponse(data));requests.length = 0; // 清空队列}, 300);
        }
        // 每次触发请求时加入队列
        function addRequest(params) {requests.push({ params });debounceRequest();
        }
        
      • 接口聚合(BFF层)
        • 原理:通过后端为前端(BFF)聚合多个接口,减少前端请求次数。
        • 示例:将多个独立接口合并为一个聚合接口 /api/v1/combined
      • 数据缓存
        • 浏览器缓存:通过 Cache-ControlETag 减少重复请求。
          • 协商缓存(动态数据):ETag: "abc123"
        • 本地存储:使用 localStorageIndexedDB 缓存低频数据。
          const CACHE_KEY = 'user-profile';
          const cachedData = localStorage.getItem(CACHE_KEY);
          if (cachedData) {return JSON.parse(cachedData);
          } else {return fetch('/api/user').then(data => {localStorage.setItem(CACHE_KEY, JSON.stringify(data));return data;});
          }
          
      • 请求去重
        • 实现:使用 Map 存储进行中的请求,避免重复发送。
          const requestMap = new Map();
          async function sendRequest(url, params) {const key = `${url}-${JSON.stringify(params)}`;if (requestMap.has(key)) {return requestMap.get(key);}const promise = fetch(url, { method: 'POST', body: params }).then(response => response.json()).finally(() => requestMap.delete(key));requestMap.set(key, promise);return promise;
          }
          
    1. 控制并发请求

      • 请求队列(限流)
        • 原理:通过队列控制同时发起的请求数量,避免浏览器资源耗尽。
        • 代码示例(自定义请求队列)
          class RequestQueue {constructor(maxConcurrency = 5) {this.maxConcurrency = maxConcurrency;this.current = 0;this.queue = [];}add(promise) {return new Promise((resolve, reject) => {this.queue.push({ promise, resolve, reject });this.process();});}async process() {if (this.current >= this.maxConcurrency || this.queue.length === 0) return;const task = this.queue.shift();this.current++;try {const result = await task.promise;task.resolve(result);this.current--;this.process();} catch (error) {task.reject(error);this.current--;this.process();}}
          }
          // 使用示例
          const queue = new RequestQueue(3);
          const requests = [fetch('/api/1'), fetch('/api/2'), ...];
          requests.forEach(req => queue.add(req));
          
      • 懒加载与分页
        • 场景:对非首屏数据延迟加载(如表格分页、图片懒加载)。
    2. 优化请求效率

      • 静态资源优化
        • CDN加速:将静态资源托管到 CDN,减少服务器压力。
        • 资源合并:合并 CSS/JS 文件,减少请求数(如通过 Webpack 的 optimization.splitChunks)。
        • 图片优化:使用 WebP 格式、懒加载、按需加载不同分辨率图片。
      • 使用 HTTP/2
        • 优势:支持多路复用,减少请求开销。

# typeof和instanceof有什么区别

typeof 的场景
检测基本类型(如 numberstringboolean)、函数或 undefined

instanceof 的场景
检测对象是否为某个构造函数的实例(如数组、自定义对象、Date 对象等)。

避免陷阱

  • typeof null 返回 "object"(需额外判断 === null)。
  • 数组用 Array.isArray() 替代 instanceof Array 更可靠。
  • 跨窗口环境(如 iframe)中 instanceof 可能失效。

js中null和undefined的区别

nullundefined 的区别

  • null:表示空值,需手动赋值(如 let user = null),类型为 Null
  • undefined:表示变量未声明/未赋值或属性不存在,类型为 Undefined

关键差异

  1. 类型检测
    • typeof null 返回 "object"(历史遗留问题),typeof undefined 返回 "undefined"
  2. 比较结果
    • null == undefinedtrue,但 null === undefinedfalse
  3. 用途
    • null 是主动设置的“无值”,undefined 是系统默认的“未定义”。

如何判断js变量是数组

判断变量是否为数组的最简方法:

  1. Array.isArray()

    Array.isArray([1,2,3]); // true
    Array.isArray({});      // false
    
  2. Object.prototype.toString

    Object.prototype.toString.call(arr) === "[object Array]";
    
  3. instanceof(需谨慎)

    arr instanceof Array; // 可能受跨窗口影响
    

关键点:

  • 推荐:优先用 Array.isArray()(简洁可靠)或 toString(跨环境通用)。
  • 慎用instanceofconstructor 可能因环境问题出错。
  • 禁用typeof 返回 object,无法准确判断数组。

Js有哪些数据类型,它们的区别是什么

JavaScript 数据类型及区别


原始类型(7种)

直接存值,不可变,存栈内存,用 typeof 检测:

  • undefined:未定义(let a;)。
  • null:空值(类型检测异常:typeof null → "object")。
  • boolean:布尔值(true/false)。
  • number:数值(含整数/浮点/NaN/Infinity)。
  • string:字符串(不可变,如 "abc")。
  • symbol:唯一标识符(ES6,防属性冲突)。
  • bigint:大整数(ES10,后缀 n,如 123n)。

引用类型(对象)

堆内存,通过引用访问,可变,用 instanceofObject.prototype.toString 检测:

  • Object:键值对容器({key: value})。
  • Array:有序集合([1, "a", true])。
  • Function:可执行函数(function() {})。
  • DateRegExp 等:内置对象(如日期、正则)。
  • ES6 新增MapSetPromise 等。

核心区别

特征原始类型引用类型
存储位置栈内存(直接存值)堆内存(存引用地址)
值传递方式按值拷贝(独立)按引用拷贝(指向同一内存)
可变性不可变可变(如数组、对象可修改)
类型检测typeofnull 异常)instanceof / Object.prototype.toString

关键注意

  • typeof null → "object" 是 JavaScript 的历史遗留问题。
  • 判断数组用 Array.isArray(),而非 typeof

相关文章:

  • 大模型工程师基础之学会使用openai
  • 51单片机所有寄存器介绍
  • leetcode0103. 二叉树的锯齿形层序遍历-medium
  • JAVA手写题-精通 Java 单例模式:三种线程安全的实现方式详解
  • JAVA:单例模式
  • 【锂电池剩余寿命预测】Transformer锂电池剩余寿命预测(Pytorch完整源码和数据)
  • Java : GUI
  • RC吸收电路参数设置实战
  • Python包的编译、构建与打包指南
  • IDEA常用快捷键及操作整理(详细图解,持续更新)
  • Allegro23.1新功能之如何冻结动态铜皮操作指导
  • 二、Web服务常用的I/O操作
  • 【Go语言】ORM(对象关系映射)库
  • 层级时间轮的 Golang 实现原理与实践
  • Grok发布了Grok Studio 和 Workspaces两个强大的功能。该如何使用?如何使用Grok3 API?
  • Win10安装 P104-100 驱动
  • Gin 框架中集成 runtime/debug 打印日志堆栈信息
  • Conda 虚拟环境复用
  • react的 Fiber 节点的链表存储
  • 通过示例学习:连续 XOR
  • 马上评丨机械停车库成“僵尸库”,设计不能闭门造车
  • 美媒:受关税政策影响,美国电商平台近千种商品平均涨价29%
  • 公交公司须关注新出行需求:“单车巴士”能否常态化
  • 视频丨伊朗阿巴斯港一处油罐发生高强度爆炸:造成大面积破坏,伤亡不明
  • 明查|把太平洋垃圾污染问题甩锅中国,特朗普用的是P过的图
  • 一年吸引30多万人次打卡,江苏这个渔村是怎么做到的?