小问题需要注意

1. useEffect和uselayoutEffect区别

Hook 触发时机 是否阻塞渲染
useEffect 浏览器完成渲染(绘制)之后 才执行,属于 异步 调用,不会阻塞页面的绘制。 ❌ 不阻塞
useLayoutEffect DOM 更新后、浏览器绘制前 执行,属于 同步 调用,会在页面绘制前完成执行,因此可能阻塞渲染。 ✅ 阻塞

使用场景建议

useEffect 适合:

  • 数据请求
  • 事件监听/解绑
  • 日志记录
  • 不影响页面首屏渲染的逻辑

useLayoutEffect 适合:

  • 需要立即 测量 DOM 尺寸/位置(如 getBoundingClientRect
  • 需要阻止页面闪烁的布局调整
  • 同步修改 DOM 样式(如动画的初始位置)

记住口诀

useEffect:绘制后执行 → 异步 → 不影响渲染
useLayoutEffect:绘制前执行 → 同步 → 会阻塞渲染

2.useEffectreturn (清理函数)和 依赖数组 的执行时机梳理成一个精确的时序表

基本规则

scss 复制代码
ts
复制编辑
useEffect(() => {
  // 副作用逻辑

  return () => {
    // 清理逻辑
  };
}, [dep1, dep2]);

执行顺序

  1. 组件首次渲染 → 执行副作用函数(// 副作用逻辑)。
  2. 依赖变化 → 先执行上一次的 return 清理逻辑,再执行新的副作用逻辑。
  3. 组件卸载 → 执行最后一次的 return 清理逻辑。

3.taiwindcss如何选择组件内的子元素

1. space-* / divide-* 处理直接子元素间距或边框

这种方式最适合「兄弟元素」场景,不需要自己写选择器。

css 复制代码
html
复制编辑
<div class="space-y-4">
  <p>第一段</p>
  <p>第二段</p>
  <p>第三段</p>
</div>
  • space-y-4 → 给所有 直接子元素 添加垂直间距
  • space-x-4 → 给所有 直接子元素 添加水平间距
  • divide-y / divide-x → 给直接子元素之间添加分隔线

2. group + group-* 选择子元素

group 是 Tailwind 内置的父级状态类,可以配合伪类选择子元素(常用在 hover、focus 场景)。

ini 复制代码
html
复制编辑
<div class="group p-4 border">
  <p class="group-hover:text-red-500">鼠标移到父元素时变红</p>
</div>
  • 父元素加 .group
  • 子元素用 group-hover:group-focus: 等前缀响应父元素状态

3. @layer 写自定义选择器

如果需要像普通 CSS 那样 .parent > .child,可以借助 Tailwind 的 @layer 功能扩展样式:

scss 复制代码
css
复制编辑
@layer components {
  .card > .title {
    @apply text-lg font-bold text-blue-500;
  }
}

HTML:

ini 复制代码
html
复制编辑
<div class="card">
  <div class="title">标题</div>
</div>
  • 这样 Tailwind 编译时会保留 .card > .title 规则
  • 适合复用性强的子元素样式

4. 使用 & 嵌套选择器(在 Tailwind 的 SCSS/Sass/ PostCSS 中)

如果项目用了 Sass 或 PostCSS Nesting,可以直接写嵌套语法:

scss 复制代码
css
复制编辑
@layer components {
  .parent {
    @apply p-4 bg-gray-100;
    & > .child {
      @apply text-red-500;
    }
  }
}

编译后会生成:

css 复制代码
css
复制编辑
.parent { padding: 1rem; background-color: #f7fafc; }
.parent > .child { color: #ef4444; }

5.实现一个es6的proxy

js 复制代码
function MyProxy(target, handler) {
  const proxy = {};

  Object.keys(target).forEach(key => {
    Object.defineProperty(proxy, key, {
      get() {
        if (handler.get) {
          return handler.get(target, key, proxy);
        }
        return target[key];
      },
      set(value) {
        if (handler.set) {
          const res = handler.set(target, key, value, proxy);
          if (res) target[key] = value;
          return res;
        }
        target[key] = value;
        return true;
      }
    });
  });

  return proxy;
}

// 测试
const obj = { a: 1, b: 2 };

const p = MyProxy(obj, {
  get(target, prop) {
    console.log(`get ${prop}`);
    return target[prop];
  },
  set(target, prop, value) {
    console.log(`set ${prop} = ${value}`);
    target[prop] = value;
    return true;
  }
});

console.log(p.a); // get a -> 1
p.b = 10;         // set b = 10

6.JavaScript 事件循环(Event Loop)主线程(Main Thread)消息队列(Message Queue / Task Queue)调用栈(Call Stack) 的运作过程

2. 执行流程

假设代码:

javascript 复制代码
js
复制编辑
console.log("A");

setTimeout(() => console.log("B"), 0);

Promise.resolve().then(() => console.log("C"));

console.log("D");

执行过程:

  1. 主线程执行同步代码console.log("A") 输出 → 压栈/弹栈
  2. 遇到 setTimeout → 定时器到点后回调放入 宏任务队列
  3. 遇到 Promise.then → 回调放入 微任务队列
  4. 继续执行 console.log("D")
  5. 执行所有微任务队列 (输出 C
  6. 执行一个宏任务队列的任务(输出 B

最终输出:

css 复制代码
css
复制编辑
A
D
C
B

可视化顺序图

javascript 复制代码
javascript
复制编辑
┌───────────────────┐
│   Call Stack       │
└───────┬───────────┘
        │
        ▼
同步任务先执行(A、D)
        │
        ▼
微任务队列(Promise.then)
        │
        ▼
宏任务队列(setTimeout)

事件循环流程:

css 复制代码
css
复制编辑
[执行栈为空] →
  执行微任务队列全部任务 →
    执行一个宏任务 →
      执行微任务队列全部任务 →
        再取一个宏任务 →
          循环...
相关推荐
独行soc4 分钟前
2025年渗透测试面试题总结-15(题目+回答)
python·科技·docker·容器·面试·eureka
转转技术团队6 分钟前
「快递包裹」视角详解OSI七层模型
前端·面试
AAA修煤气灶刘哥1 小时前
面试官:Spring容器中的bean是线程安全的吗?小心陷阱!!!
后端·面试
李剑一1 小时前
面试官:Vue 中 data 属性为什么是一个函数而不是对象?
前端·面试
默默地离开1 小时前
小编第一次面试吓尿了,赶快来写篇文章压压经
前端·面试·程序员
李剑一2 小时前
面试官:watch和computed的区别?不要简单的说监听器和计算属性!
前端·面试
Java中文社群2 小时前
说说内存泄漏的常见场景和排查方案?
java·后端·面试
C4程序员3 小时前
北京JAVA基础面试30天打卡08
java·开发语言·面试
Hilaku4 小时前
从“高级”到“资深”,我卡了两年和我的思考
前端·javascript·面试