vue前端面试题——记录一次面试当中遇到的题(10)

目录

1.css的定位有哪些?

2.promise

[3.v-bind="attrs"是什么意思](#3.v-bind="attrs"是什么意思)

4.二次封装穿梭框组件,支持异步加载数据、拖拽排序怎么实现的

[🔄 实现异步加载数据](#🔄 实现异步加载数据)

当穿梭框需要处理大量数据时,异步加载可以有效提升性能。

[👆 实现拖拽排序](#👆 实现拖拽排序)

[🧩 组件封装技巧](#🧩 组件封装技巧)

[⚠️ 注意事项](#⚠️ 注意事项)

[💎 总结](#💎 总结)

[5.在elemnt当中,使用v-model绑定他的数据,然后再封装一次,也使用v-model的方式把数据绑定,那他里面的属性比如prefix、suffix 这些前缀和后缀,我仍然要使用他原生的一些属性 怎么实现?](#5.在elemnt当中,使用v-model绑定他的数据,然后再封装一次,也使用v-model的方式把数据绑定,那他里面的属性比如prefix、suffix 这些前缀和后缀,我仍然要使用他原生的一些属性 怎么实现?)

[💎 总结](#💎 总结)

6.localStorage、sessionStorage、cookie有什么区别

7.router的路由模式有哪几种?

8.vuex的核心属性有那5种?

9.Xhr、Fetch、Axios有什么区别?

10.Symbol


1.css的定位有哪些?

(1)静态定位(static)

  • 这是元素的默认定位方式。
  • 元素按照正常的文档流进行排列,忽略top、bottom、left、right和z-index属性。

(2)相对定位(relative)

  • 元素先放置在未添加定位时的位置,再通过top、bottom、left、right属性使其相对于原本的位置进行移动。

  • 移动后,它原本所占的空间不会改变,因此不会影响其他元素的位置。

(3)绝对定位(absolute)

  • 元素脱离正常文档流,不占据空间。

  • 相对于最近的非static定位的祖先元素进行定位(如果没有,则相对于初始包含块,通常是html元素)。

  • 其位置由top、bottom、left、right属性确定。

(4)固定定位(fixed)

  • 元素脱离正常文档流,不占据空间。

  • 相对于浏览器窗口进行定位,即使页面滚动,它也会停留在固定的位置。

  • 常用于导航栏、悬浮按钮等。

(5)粘性定位(sticky)

  • 可以看作是相对定位和固定定位的混合。

  • 元素在跨越特定阈值前为相对定位,之后为固定定位。

  • 例如,可以设置一个元素在滚动到距离顶部10px时固定在那里。

2.promise

Promise 是 JavaScript 中用于处理异步操作的对象,它代表一个异步操作的最终完成(或失败)及其结果值。Promise 有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。一旦状态改变,就不会再变。

(1)Promise 的基本用法:

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolvereject,它们是两个函数。

  • resolve 函数将 Promise 状态从 pending 变为 fulfilled,并将异步操作的结果作为参数传递出去。

  • reject 函数将 Promise 状态从 pending 变为 rejected,并将异步操作报出的错误作为参数传递出去。

(2)Promise 的实例方法:

  • then(): 用于指定 fulfilled 状态和 rejected 状态的回调函数。它接受两个参数,第一个是 fulfilled 状态的回调,第二个是 rejected 状态的回调(可选)。then 方法返回一个新的 Promise 实例,因此可以采用链式写法。

  • catch(): 用于指定发生错误时的回调函数,相当于 then 的第二个参数,但 catch 可以捕获前面 then 方法执行中的错误。

  • finally(): 用于指定不管 Promise 对象最后状态如何都会执行的操作。

(3)Promise 的静态方法:

  • Promise.resolve(): 将现有对象转为 Promise 对象,并且状态为 fulfilled。

  • Promise.reject(): 返回一个状态为 rejected 的 Promise 对象。

  • Promise.all(): 用于将多个 Promise 实例包装成一个新的 Promise 实例。当所有 Promise 都成功时,返回的结果数组与传入的顺序一致;如果有一个失败,则立即返回失败的结果。

  • Promise.race(): 同样将多个 Promise 实例包装成一个新的 Promise 实例,但是只要有一个实例率先改变状态,新的 Promise 实例的状态就跟着改变。

  • Promise.allSettled(): 等待所有 Promise 实例都完成(不管成功还是失败),返回一个对象数组,每个对象表示对应的 Promise 结果。

  • Promise.any(): 接收多个 Promise 实例,只要有一个变成 fulfilled 状态,就返回该 Promise 的值;如果所有都变成 rejected,则返回一个 AggregateError。

(4)错误处理: Promise 中的错误具有"冒泡"性质,直到被捕获为止。建议使用 catch 来捕获错误,而不是在 then 中写第二个参数。

(5)与回调函数相比的优点:

  • 避免回调地狱,代码更清晰。

  • 提供统一的错误处理机制。

(6)Promise 的局限性:

  • 一旦创建无法取消。

  • 如果不设置回调函数,Promise 内部抛出的错误不会反应到外部。

  • 当处于 pending 状态时,无法得知当前进展到哪一个阶段。

3.v-bind="$attrs"是什么意思

$attrs 是什么?

  • $attrs 是Vue实例的一个属性,包含父组件传递给子组件没有在子组件props中声明的所有属性

  • 包括:HTML特性、自定义属性、事件监听器等

  • 不包括:在props中声明的属性、class、style

v-bind="$attrs" 的作用

$attrs对象中的所有属性一次性绑定到当前元素上

常用于创建包装组件,实现属性的透传

通常配合inheritAttrs: false使用,避免重复的属性绑定

4.二次封装穿梭框组件,支持异步加载数据、拖拽排序怎么实现的
🔄 实现异步加载数据
当穿梭框需要处理大量数据时,异步加载可以有效提升性能。
  • 懒加载与分页展示

    • 思路是初始只加载部分数据(如20条),通过监听列表滚动,滚动到底部时加载下一页数据 。

    • data 中定义 pageSize(每页条数)、curIndex(当前页码)和 showData(当前展示的数据) 。

    • 使用 v-infinite-scroll 指令(Element-UI 已提供)绑定滚动到底部的加载方法 。

    • 向上滚动翻页需自行监听 scroll 事件,判断滚动条到达顶部且当前不是第一页时,加载上一页数据 。翻页时注意重置滚动条位置。

  • 数据拼接与展示

    • 初始展示数据通过截取总数据的前 pageSize 条实现 。

    • 后续加载通过数组的 sliceconcat 方法拼接新数据 。务必注意,直接展示 showData 而非全部数据 filteredData

👆 实现拖拽排序

为穿梭框右侧已选项列表增加拖拽排序功能,Sortable.js 是一个不错的选择。

  • 使用 Sortable.js

    • 安装 Sortable.js:npm install sortablejs

    • 建议封装一个自定义指令(如 v-draggable-transfer),在其 mounted 钩子中,使用 Sortable.create 初始化拖拽。通常只需对右侧列表(可通过类名 .el-transfer-panel__list 选取,注意一般是第二个此类元素)启用拖拽 。

    • 配置 Sortable 选项,如 handle(指定拖拽触发元素,如一个拖拽图标),draggable(指定可拖拽项),animation(拖拽动画)等 。

    • 在 Sortable 的 onEnd 回调中,通过 event.oldIndexevent.newIndex 获取拖拽前后元素位置,并调用绑定的回调函数更新数据顺序 。指令卸载时销毁 Sortable 实例 。

  • 数据更新与视图同步

    • 在拖拽结束的回调函数中,交换 v-model 绑定数组(即右侧已选值数组)中对应 oldIndexnewIndex 的元素 。

    • Vue 是数据驱动的,数据更新后视图会自动同步。

  • 排序与回显处理

    • Element-UI 穿梭框的 target-order 属性会影响右侧列表排序。其默认值 original 会使右侧列表顺序与数据源保持一致 。若希望按选择顺序或拖拽后顺序显示,可设置 target-orderpushunshift

    • 对于编辑回显,若数据源顺序与期望的右侧展示顺序不一致,可能需在回显时手动对数据源进行排序,使其与已选值数组顺序匹配 。

🧩 组件封装技巧

优雅地二次封装第三方组件很重要。

  • 属性与事件透传

    • 使用 v-bind="$attrs" 可以将父组件传入而子组件未在 props 中声明的属性绑定到内部组件 。使用 v-on="$listeners" 可以透传所有事件监听器 。

    • 在组件选项中设置 inheritAttrs: false,可以避免未声明的属性被自动添加到组件的根元素上 。

    • 这样封装后的组件能保持与原始 Element-UI 穿梭框相似的属性和事件使用体验。

  • 插槽(Slot)处理

    • 若原组件使用了插槽,需要在封装组件中通过 <slot> 标签进行暴露或自定义默认内容 。

    • 例如,穿梭框支持通过插槽自定义每项显示内容,封装时需在模板中保留对应插槽。

⚠️ 注意事项
  • 性能优化:异步加载主要解决大数据量渲染的卡顿问题 。需合理设置每页加载数量。

  • 拖拽目标与反馈:明确拖拽区域和触发元素,提供清晰的拖拽视觉反馈 。

  • 数据一致性 :确保拖拽排序后,组件绑定的数据与视图展示保持一致。注意 target-order 属性对排序行为的影响 。

💎 总结

在面试中回答这个问题时,可以概括说明:二次封装Element-UI穿梭框,主要是通过懒加载和分页展示 优化大量数据的性能,利用 Sortable.js 实现拖拽排序 以增强交互,并运用 $attrs$listeners 实现属性和事件的透传,保持组件的灵活性和易用性。清晰说明这些核心技术和思路,通常能给面试官留下良好印象。

5.在elemnt当中,使用v-model绑定他的数据,然后再封装一次,也使用v-model的方式把数据绑定,那他里面的属性比如prefix、suffix 这些前缀和后缀,我仍然要使用他原生的一些属性 怎么实现?
配置要点 作用和说明 示例或注意事项
属性透传 使父组件传递的、未在子组件props中声明的原生属性(如prefix, suffix)传递到内部组件 使用 v-bind="$attrs"
事件监听器透传 使父组件传递的、未在子组件emits中声明的事件监听器传递到内部组件 使用 v-on="$listeners" (Vue 2) 或 v-on="proxyEvents" (Vue 3)
v-model 处理 确保自定义组件的 v-model 与 Element 组件的 v-model 正确衔接 使用 modelValueupdate:modelValue
禁用根元素继承 防止未声明的属性自动添加到封装组件的根元素上 设置 inheritAttrs: false
💎 总结

通过 v-bind="$attrs"v-on="proxyEvents"(Vue 3)v-on="$listeners"(Vue 2) 以及正确处理 v-model,你可以在二次封装 Element 组件时,轻松保留所有原生属性和事件。这样既保持了组件的易用性,又确保了功能的完整性。

6.localStorage、sessionStorage、cookie有什么区别
特性 localStorage sessionStorage cookie
生命周期 永久,除非手动删除 会话级别,页面关闭则清除 可设置过期时间,未设置则为会话级别
存储大小 5MB 5MB 4KB
与服务器通信 不自动发送 不自动发送 每次请求都会携带在HTTP头中
API易用性 简单 简单 需要自己封装
作用域 同源窗口共享 当前标签页有效 可设置域名和路径
安全性 不安全 不安全 可设置HttpOnly和Secure提高安全性
7.router的路由模式有哪几种?

(1)hash模式

  • 使用URL的hash(#)来模拟一个完整的URL,当URL改变时,页面不会重新加载。

  • 原理:通过监听hashchange事件来响应路由的变化。

  • 特点:hash模式下的URL会带有#,有些用户可能觉得不美观。但是,它兼容性好,支持所有浏览器。

(2)history模式

  • 利用HTML5 History API(pushState、replaceState、popState)来实现无刷新跳转。

  • 原理:通过pushState和replaceState改变URL,且不会发送请求,然后通过popState事件来监听URL变化。

  • 特点:URL没有#,看起来更美观。但是,需要后台配置支持,因为当用户直接访问一个路由时,如果后台没有配置该路由的对应页面,会返回404。

特性 Hash 模式 History 模式 Abstract 模式
URL 形式 http://site.com/#/home http://site.com/home 无 URL(内存路由)
是否需要服务器配置
SEO 友好性 较差 较好
兼容性 所有浏览器 HTML5 History API 所有环境
使用场景 通用场景 需要美观URL、SEO 非浏览器环境
8.vuex的核心属性有那5种?

五大核心属性

  • State:存储应用状态数据,唯一数据源

  • Getters:计算派生状态,类似计算属性

  • Mutations:同步修改State的唯一途径

  • Actions:处理异步操作,提交Mutations

  • Modules:模块化分割大型应用状态

核心原则

  • State是响应式的,不能直接修改

  • 必须通过Mutations修改State

  • Actions处理异步,Mutations必须是同步

  • 大型应用使用Modules进行模块化管理

9.Xhr、Fetch、Axios有什么区别?

(1)XHR(XMLHttpRequest)
简介:

  • 是一种原生的 JavaScript API,用于发送 HTTP 请求和接收响应。
  • 最早用于实现异步的 Ajax 请求。

特点:

  • API 比较旧,使用起来不够直观,代码通常较为冗长。
  • 支持同步和异步请求,但同步请求在现代浏览器中被逐步废弃。

优点:

  • 兼容性强,支持几乎所有浏览器。

缺点:

  • 不支持 Promise,需要手动处理回调逻辑,代码复杂。

补充:(2)Ajax(Asynchronous JavaScript and XML)
简介:

  • 是一种技术概念,代表使用异步方式与服务器通信。
  • 通常指使用 XHR 来实现异步请求的方式。

特点:

  • Ajax 不是一个具体的工具,而是一种技术组合(HTML、CSS、JavaScript 和 XHR)。

优点:

  • 可以加载数据到页面而无需刷新整个页面。

缺点:

  • 如果基于 XHR 实现,依然存在代码冗长、缺少现代特性的问题。

(3) API
简介:

  • 是现代浏览器提供的新的原生 JavaScript API,用于 HTTP 请求。
  • 基于 Promise,语法更简洁,更现代化。

特点:

  • 默认使用异步方式,不支持同步请求。
  • 支持更丰富的功能,比如流式处理响应。

优点:

  • Promise 和 async/await 支持,使代码更加直观。
  • 易于扩展,比如通过拦截器对请求和响应进行处理。

缺点:

  • 浏览器兼容性不如 XHR(例如旧版 IE 不支持)。
  • 默认不支持超时控制,需要手动实现。

(4) Axios

简介:

  • 是一个基于 Promise 的第三方 HTTP 请求库,封装了 XHR 和部分 Fetch 功能。
  • 提供了更高级的功能,简化了 HTTP 请求的实现。

特点:

  • 自动转换 JSON 数据。
  • 支持请求和响应拦截器。
  • 提供默认超时设置和更便捷的错误处理。

优点:

  • 语法简单,易于使用。
  • 更强大的功能(拦截器、取消请求、超时设置等)。
  • 浏览器兼容性好。

缺点:

  • 需要引入额外的库,增加项目体积。
10.Symbol

Symbol 是 ES6 引入的一种新的原始数据类型,表示唯一的值。主要作用是创建唯一的属性键,避免对象属性名冲突,还可以用于定义对象的私有属性,以及修改对象在特定操作下的行为(如使用内置 Symbol 值)。

  1. 基本概念

    • ES6 新增的原始数据类型

    • 表示唯一且不可变的值

    • 主要用途是创建唯一的属性键

  2. 核心特性

    • 唯一性:每个 Symbol 都是唯一的,即使描述相同

    • 不可枚举性:Symbol 属性不会被常规方法枚举到

    • 全局注册表 :可以使用 Symbol.for() 创建全局共享的 Symbol

  3. 主要应用场景

    • 避免属性名冲突:在库开发中防止属性被意外覆盖

    • 实现私有属性:虽然不是真正的私有,但提供了某种程度的封装

    • 内置 Symbol:定义对象的默认行为(迭代、类型转换等)

    • 元编程:控制对象的底层行为

  4. 常用方法

    • Symbol(description) - 创建 Symbol

    • Symbol.for(key) - 创建或获取全局 Symbol

    • Symbol.keyFor(sym) - 获取全局 Symbol 的键

    • Object.getOwnPropertySymbols() - 获取对象的 Symbol 属性

相关推荐
tiantian_cool3 小时前
正确的 .gitignore 配置
前端·github
三小河3 小时前
封装 classNames:让 Tailwindcss 类名处理更优雅
前端·javascript
起这个名字3 小时前
ESLint 导入语句的分组排序
前端·javascript
踩着两条虫3 小时前
VTJ.PRO低代码快速入门指南
前端·低代码
Lazy_zheng3 小时前
一场“数据海啸”,让我重新认识了 requestAnimationFrame
前端·javascript·vue.js
crary,记忆3 小时前
MFE: React + Angular 混合demo
前端·javascript·学习·react.js·angular·angular.js
Asort4 小时前
JavaScript设计模式(十七)——中介者模式 (Mediator):解耦复杂交互的艺术与实践
前端·javascript·设计模式
linda26184 小时前
String() 和 .toString()的区别
前端·javascript·面试
拜晨4 小时前
初探supabase: RLS、trigger、edge function
前端