前端高频面试题day2

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

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

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

代码示例

javascript 复制代码
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 属性与计算属性使用不同名称

      javascript 复制代码
      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)
      • 场景:多个小请求合并为一个请求(如实时搜索、分页加载)。

      • 实现:使用防抖/节流或自定义批量接口。

      • 代码示例(防抖合并请求)

        javascript 复制代码
        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 缓存低频数据。

          javascript 复制代码
          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 存储进行中的请求,避免重复发送。

          javascript 复制代码
          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. 控制并发请求

      • 请求队列(限流)

        • 原理:通过队列控制同时发起的请求数量,避免浏览器资源耗尽。

        • 代码示例(自定义请求队列)

          javascript 复制代码
          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()

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

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

    javascript 复制代码
    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
复制代码
相关推荐
11054654011 小时前
23、电网数据管理与智能分析 - 负载预测模拟 - /能源管理组件/grid-data-smart-analysis
前端·能源
开发者小天1 小时前
React中startTransition的使用
前端·react.js·c#
@PHARAOH2 小时前
WHAT - 缓存命中 Cache Hit 和缓存未命中 Cache Miss
前端·缓存
计算机学姐2 小时前
基于SpringBoot的小型民营加油站管理系统
java·vue.js·spring boot·后端·mysql·spring·tomcat
Elastic 中国社区官方博客2 小时前
JavaScript 中使用 Elasticsearch 的正确方式,第一部分
大数据·开发语言·javascript·数据库·elasticsearch·搜索引擎·全文检索
万物得其道者成2 小时前
从零开始创建一个 Next.js 项目并实现一个 TodoList 示例
开发语言·javascript·ecmascript
海天胜景2 小时前
无法加载文件 E:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
MingT 明天你好!3 小时前
在vs code 中无法运行npm并报无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查
前端·npm·node.js·visual studio code
老兵发新帖3 小时前
pnpm 与 npm 的核心区别
前端·npm·node.js
超级土豆粉3 小时前
怎么打包发布到npm?——从零到一的详细指南
前端·npm·node.js