HIKVISION前端一面面经整理
- Vue2和Vue3熟悉度+Vue3优势+性能更好原因
Vue3优势:Composition API(逻辑复用更灵活,告别Vue2 Options API的代码碎片化)、更好的TypeScript支持(原生适配,类型推断更精准)、新增特性(Teleport、Suspense、多v-model绑定)。性能更好的核心原因:① 响应式系统升级(Vue2用Object.defineProperty,Vue3用Proxy,可监听数组、对象新增属性,无需递归初始化);② 编译优化(静态提升、PatchFlags标记动态节点,减少Diff对比范围);③ 体积更小(Tree-shaking支持,未使用的API可被打包剔除)。
- Vuex使用+函数方法+语法
常用函数/核心概念:State(存储状态)、Mutation(修改状态的唯一途径,同步)、Action(处理异步,可调用Mutation)、Getter(计算派生状态,类似Vue的computed)、Module(模块化拆分状态)。
import Vuex from 'vuex'
const store = new Vuex.Store({state: { count: 0 }, // 状态mutations: { increment(state, payload) { state.count += payload } // 同步修改},actions: { asyncIncrement({ commit }, payload) { // 异步操作setTimeout(() => commit('increment', payload), 1000)}},getters: { doubleCount(state) { return state.count * 2 } // 派生状态}
})
- Pinia与Vuex的区别
Pinia优势(核心区别):① 简化API(无Mutation,直接在Action中修改状态,无需commit);② 天然支持TypeScript(无需额外声明,类型推导更友好);③ 无Module嵌套,通过创建多个Store实现模块化(结构更扁平);④ 体积更小(约1KB,比Vuex轻量);⑤ 支持DevTools调试(保留时间线、状态快照)。
• 示例:Pinia无需Mutation,Action可直接修改state:
import { defineStore } from 'pinia'
const useCountStore = defineStore('count', {state: () => ({ count: 0 }),actions: { increment(payload) { this.count += payload } } // 直接修改
})
-
组件通信方式
-
父子通信:Props(父传子)、$emit/自定义事件(子传父);
-
祖孙/跨级通信:provide/inject(Vue2/Vue3均支持,Vue3可配合TypeScript);
-
兄弟/全局通信:Vuex/Pinia(状态管理)、事件总线(Vue2:new Vue(),Vue3:mitt库);
-
其他:parent/children(直接访问父子实例,不推荐)、attrs/listeners(透传属性/事件,Vue3中listeners合并入attrs)。
-
大文件上传实现方案
-
切片上传:将大文件按固定大小分割为小切片(如5MB/片);
-
并发上传:用Promise.all并发上传多个切片(控制并发数,避免请求过多);
-
断点续传:上传前通过MD5计算文件唯一标识,向服务端查询已上传切片,仅上传未完成部分;
-
合并切片:所有切片上传完成后,调用服务端接口合并切片为完整文件。
• 核心依赖:File.slice(分割文件)、spark-md5(计算文件MD5)。
- 大文件切片大小选择
• 推荐:5MB~10MB/片(主流方案);
• 依据:① 避免切片过小(如1MB,导致请求数过多,占用带宽和服务器连接数);② 避免切片过大(如50MB,单次请求超时风险高,断点续传优势弱化);③ 适配大多数浏览器/服务器的单次请求大小限制(通常默认支持10MB以内)。
- 防抖点击
// 1. 封装指令(directives/debounceClick.js)
export default {bind(el, binding) {let timer = null;el.addEventListener('click', () => {if (!timer) { // 无定时器时执行binding.value(); // 执行绑定的函数timer = setTimeout(() => {timer = null; // 1秒后重置定时器}, 1000);}});}
};// 2. 全局注册(main.js)
import debounceClick from './directives/debounceClick'
Vue.directive('debounce-click', debounceClick);// 3. 组件中使用
<button v-debounce-click="handleSubmit">提交</button>
- 场景题:100个带input+勾选框的div,跳转至第21个勾选
• 核心思路:给每个div添加唯一标识(如id=“item-21”),通过DOM操作定位并滚动到目标元素。
-
除window.scrollTo外的跳转方法
-
element.scrollIntoView():直接让目标元素滚动到可视区域(支持配置平滑滚动、对齐方式); -
window.scrollBy():相对当前位置滚动(如scrollBy(0, 100)向下滚100px); -
操作
document.documentElement.scrollTop/document.body.scrollTop:直接设置滚动距离(兼容性需处理,Vue中可配合ref获取容器); -
基于CSS:给滚动容器设置
scroll-behavior: smooth,通过锚点(<a href="#target">)跳转。 -
ES6+Promise了解
• ES6核心特性:let/const(块级作用域)、箭头函数、解构赋值、模板字符串、Set/Map、模块化(import/export)、Promise等。
• Promise:用于处理异步操作的对象,有三种状态:Pending(进行中)、Fulfilled(成功)、Rejected(失败),状态一旦改变不可逆。
- Promise.all与Promise.race
• Promise.all(iterable):接收可迭代对象(如数组),等待所有Promise都成功,返回成功结果数组;只要有一个失败,立即返回该失败原因。
• Promise.race(iterable):接收可迭代对象,哪个Promise先改变状态(成功/失败),就返回哪个的结果/原因(“竞速”机制)。
- Promise.all部分成功的返回结果
• 返回失败的Promise。Promise.all是“全量成功才成功”,只要有一个Promise被reject,就会立即终止并返回该reject的原因,忽略其他已成功的结果。
- 防抖(Debounce)与节流(Throttle)
• 防抖:触发事件后,延迟n秒执行函数;若n秒内再次触发,重新计时(“触发后冷却”)。核心是“合并多次触发为最后一次”。
• 节流:触发事件后,n秒内只执行一次函数;若n秒内再次触发,忽略(“固定频率执行”)。核心是“控制触发频率”。
• 实现(简化版):
// 防抖
function debounce(fn, delay) {let timer = null;return (...args) => {clearTimeout(timer);timer = setTimeout(() => fn.apply(this, args), delay);};
}// 节流
function throttle(fn, interval) {let lastTime = 0;return (...args) => {const now = Date.now();if (now - lastTime >= interval) {fn.apply(this, args);lastTime = now;}};
}
- 防抖节流应用场景
• 防抖:搜索框输入联想(输入停止后再请求,避免频繁接口调用)、窗口resize事件(调整完成后再计算布局)、按钮防重复提交(但需结合业务,部分场景用节流)。
• 节流:滚动加载(滚动时固定频率请求数据)、高频点击按钮(如“快速点击搜索”)、鼠标移动事件(如拖拽时计算位置)。
- 搜索框快速点击搜索按钮:用防抖还是节流?
• 推荐用节流。
• 原因:快速点击搜索按钮的需求是“避免短时间内多次触发接口请求,但允许按固定频率执行(如1秒内最多1次)”。
◦ 若用防抖:点击后需等待延迟(如1秒)才执行,用户可能点击多次后仍需等待,体验差;
◦ 若用节流:点击后立即执行一次,1秒内再点击忽略,既防止重复请求,又能快速响应首次点击,符合用户操作预期。
