NodeJS全栈开发面试题讲解——P5前端能力(React/Vue + API调用)
✅ 5.1 如何使用 React/Vue 发起后端请求?用什么库?
面试官您好,在实际项目中我们通常使用
axios
、fetch
或框架提供的封装库发起后端请求。
🔧 常用库对比:
库 | 框架适配 | 优点 |
---|---|---|
axios | 通用 | 默认支持拦截器、取消请求、请求体转换 |
fetch | 通用 | 原生支持但较原始,无拦截器 |
useSWR | React | 适合缓存和自动请求更新(推荐) |
Vue Resource | Vue 2 已弃用 | 已被淘汰 |
@vueuse/core | Vue 3 | 配合 Composition API 很方便 |
🧩 示例:React 中使用 axios(Hooks + 拦截器)
import axios from 'axios';
import { useEffect, useState } from 'react';const api = axios.create({baseURL: '/api',timeout: 5000,
});export function useUserData() {const [data, setData] = useState(null);useEffect(() => {api.get('/user/info').then(res => setData(res.data));}, []);return data;
}
✅ 5.2 状态管理你用什么?Redux、Pinia、Zustand 等对比
状态管理选择要结合项目复杂度和框架生态,React 我常用 Zustand 或 Redux Toolkit,Vue 我用 Pinia。
🔍 状态管理库对比:
名称 | 所属框架 | 特点 | 使用建议 |
---|---|---|---|
Redux Toolkit | React | 官方推荐,类型安全,支持异步 | 大型项目推荐 |
Zustand | React | 极简、无模板代码、Hook 风格 | 中小型项目非常适合 |
Recoil | React | 原子化状态,更适合组件隔离场景 | 组件粒度状态管理 |
Vuex | Vue 2 | 老牌方案,API 繁琐 | 不推荐新项目使用 |
Pinia | Vue 3 | 轻量、支持模块拆分、Composition API | Vue 3 项目首选 |
示例:Zustand 创建用户状态(React)
import create from 'zustand';export const useUserStore = create(set => ({user: null,setUser: (data) => set({ user: data })
}));
示例:Pinia 创建用户状态(Vue)
import { defineStore } from 'pinia';export const useUserStore = defineStore('user', {state: () => ({ user: null }),actions: {setUser(data) {this.user = data;}}
});
✅ 5.3 如果一个接口很慢,你如何在 UI 上做友好的处理?
面试官我会从「用户感知」和「界面提示」两个维度入手优化体验:
⏳ 接口慢时的 UI 优化手段:
-
骨架屏:如加载用户卡片、文章列表的占位框架;
-
loading Spinner:展示加载中状态,防止用户误操作;
-
请求超时提示:超过 X 秒提示“网络可能异常”;
-
请求缓存 / 懒加载:结合 SWR / React Query / keep-alive 优化重复加载;
-
预请求策略:页面还未进入前发起关键数据请求,提升首屏速度。
示例(React + Skeleton):
return isLoading ? <Skeleton count={5} /> : <UserList data={users} />;
✅ 5.4 如何处理请求节流、防抖?封装方式?
防抖与节流是优化高频请求的重要手段,尤其在搜索框、滚动加载等场景非常常见。
🔄 原理区别:
名称 | 原理 | 应用场景 |
---|---|---|
防抖 | 延迟执行,用户停止操作后触发 | 搜索、输入提示 |
节流 | 固定时间间隔执行一次 | 滚动加载、按钮点击防重复 |
✅ Lodash 工具函数(实战推荐):
import { debounce, throttle } from 'lodash';const onSearch = debounce((val) => {fetchData(val);
}, 500);const onScroll = throttle(() => {loadMore();
}, 1000);
✅ 自定义封装 Hook(React)
function useDebounce(fn, delay) {const timer = useRef(null);return (...args) => {clearTimeout(timer.current);timer.current = setTimeout(() => fn(...args), delay);};
}
✅ 5.5 如何将分页、筛选、排序的参数传给后端?
这是常规表格 / 列表 API 设计问题,建议采用统一参数命名规范。
📌 传参结构建议:
GET /api/users?page=1&pageSize=10&sortBy=name&order=asc&status=active
参数 | 描述 |
---|---|
page | 当前页码 |
pageSize | 每页条数 |
sortBy | 排序字段 |
order | 排序方向(asc/desc) |
filters | 状态、关键词等条件 |
✅ React 示例:
const [params, setParams] = useState({page: 1,pageSize: 10,sortBy: 'createdAt',order: 'desc',status: 'active'
});useEffect(() => {axios.get('/api/posts', { params });
}, [params]);
✅ Vue 示例(配合分页组件):
const params = reactive({page: 1,pageSize: 10,sortBy: 'createdAt',order: 'desc'
});watch(() => [params.page, params.pageSize], () => {fetchData(params);
});
✅ 总结
编号 | 技术点 | 核心亮点 |
---|---|---|
5.1 | 请求库选择 | axios 最通用、SWR 自动缓存、NestJS 中也支持 axios |
5.2 | 状态管理 | Vue 用 Pinia,React 建议 Zustand 或 Redux Toolkit |
5.3 | UI 慢接口处理 | 骨架屏、loading、预加载 |
5.4 | 节流防抖封装 | lodash、React Hook、自定义封装 |
5.5 | 分页筛选排序参数传递 | page、pageSize、sortBy、filters 一致性封装 |