React 从入门到出门第二章 生命周期函数与内置 Hooks 整体认知

大家好~ 上一篇我们聊了 React 19 的 JSX 增强特性和函数组件基础,今天咱们聚焦另一个核心知识点------生命周期函数与内置 Hooks。

很多刚接触 React 的同学会有个误区:"只有 class 组件才有生命周期"。其实在 React 19 中,函数组件通过 Hooks 完全可以实现甚至优化生命周期的逻辑,而且 Hooks 是函数组件的核心能力,所有 React 19 新特性都围绕 Hooks 展开。

今天这篇文章,我们就从"生命周期的本质是什么"入手,先搞懂 React 组件的核心运行流程,再逐一认识 React 19 中 8 个常用内置 Hooks(useState、useEffect、useContext、useCallback、useRef、useMemo、useDeferredValue、useTransition),结合代码示例讲清"核心作用+应用场景+使用注意",最后用精准的图例梳理清楚 Hooks 与生命周期的对应关系,帮大家建立完整的知识框架。

一、先搞懂:生命周期的本质是"组件的运行阶段"

不管是 class 组件还是函数组件,React 组件的核心运行流程都可以分为三个阶段:挂载阶段(组件第一次渲染到页面)、更新阶段(组件数据变化重新渲染)、卸载阶段(组件从页面中移除)

生命周期函数,就是 React 提供的、允许我们在组件不同运行阶段插入自定义逻辑的"钩子"。比如:

  • 挂载阶段:我们可能需要请求初始化数据、绑定事件监听;
  • 更新阶段:我们可能需要根据数据变化更新 DOM 、做性能优化;
  • 卸载阶段:我们可能需要清除定时器、取消事件监听,避免内存泄漏。

React 19 中生命周期的实现方式

在 React 早期,class 组件通过 componentDidMountcomponentDidUpdatecomponentWillUnmount 等生命周期方法实现上述逻辑。但在 React 19 中,函数组件+ Hooks 已经成为主流,官方也更推荐这种方式------因为 Hooks 能让逻辑复用更简单,代码更简洁。

下面先通过一个精准的图例,直观看看 React 19 组件的完整生命周期流程,以及函数组件中对应的 Hooks 从图中可以看出:useEffect 是最核心的"生命周期 Hooks",能覆盖挂载、更新、卸载三个阶段的逻辑;而 useState、useContext 等 Hooks 则聚焦于状态管理或性能优化,为生命周期中的逻辑提供支撑。

二、React 19 8 个核心内置 Hooks 详解(核心作用+应用场景+代码示例)

React 19 提供了一系列内置 Hooks,每个 Hooks 都有明确的使用场景,遵循"命名以 use 开头、只能在函数组件顶层调用"的规则。下面我们逐一讲解 8 个常用核心 Hooks,重点突出应用场景,结合实战代码说明用法。

1. useState:组件状态管理的"基石"

核心作用:为函数组件添加"可变化的状态"(组件内部可修改、修改后触发重新渲染的数据),是实现组件更新生命周期的基础。

应用场景

  • 管理组件内部的简单状态(如计数器数值、表单输入值、弹窗显示/隐藏状态);
  • 存储组件渲染所需的动态数据(如列表数据、用户信息等,可配合 useEffect 请求后更新);
  • 实现组件内部的状态联动(如根据一个状态变化同步更新另一个状态)。

语法const [状态变量, 状态更新函数] = useState(初始值);

使用注意 :状态更新是异步的,若需基于前一个状态更新,需使用函数式更新(setCount(prev => prev + 1));更新对象/数组时需遵循"不可变原则",不能直接修改原数据。

实战案例:表单输入与弹窗控制

ini 复制代码
import { useState } from 'react';

function FormWithModal() {
  // 场景1:管理表单输入状态(用户名、密码)
  const [formData, setFormData] = useState({ username: '', password: '' });
  // 场景2:管理弹窗显示/隐藏状态
  const [isModalOpen, setIsModalOpen] = useState(false);

  const handleInputChange = (e) => {
    const { name, value } = e.target;
    // 不可变更新对象状态
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    // 表单验证通过后打开弹窗
    if (formData.username && formData.password) {
      setIsModalOpen(true);
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          name="username"
          value={formData.username}
          onChange={handleInputChange}
          placeholder="请输入用户名"
        />
        <input
          type="password"
          name="password"
          value={formData.password}
          onChange={handleInputChange}
          placeholder="请输入密码"
        />
        <button type="submit">提交</button>
      </form>

      {/* 弹窗组件,根据 isModalOpen 状态显示/隐藏 */}
      {isModalOpen && (
        <div style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', border: '1px solid #ccc', padding: '20px' }}>
          <h3>提交成功!</h3>
          <p>用户名:{formData.username}</p>
          <button onClick={() => setIsModalOpen(false)}>关闭</button>
        </div>
      )}
    </div>
  );
}

2. useEffect:处理副作用的"万能 Hooks"

核心作用 :处理组件的"副作用"(即不直接参与 UI 渲染的逻辑,如数据请求、事件绑定、定时器、清理资源等),覆盖 class 组件 componentDidMountcomponentDidUpdatecomponentWillUnmount 三个生命周期方法的功能。

应用场景

  • 挂载阶段:初始化数据请求(如页面加载时请求列表数据)、绑定全局事件(如窗口大小监听、滚动监听);
  • 更新阶段:依赖数据变化后重新请求数据(如根据用户 ID 变化请求对应用户详情)、根据状态变化更新 DOM 样式;
  • 卸载阶段:清理资源(如清除定时器、取消事件监听、取消未完成的请求),避免内存泄漏。

语法useEffect(() => { 副作用逻辑; return () => { 清理逻辑; }; }, [依赖数组]);

使用注意 :依赖数组需包含副作用逻辑中使用的所有状态/变量,避免遗漏导致使用旧值;空依赖数组([])仅在挂载时执行一次,无数组则每次渲染都执行。

实战案例:数据请求+事件监听+定时器清理

javascript 复制代码
import { useEffect, useState } from 'react';

function DataFetchWithCleanup() {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // 场景1:挂载时请求数据
    const fetchData = async () => {
      try {
        const res = await fetch('https://api.example.com/list');
        const result = await res.json();
        setData(result);
      } catch (err) {
        console.error('请求失败:', err);
      } finally {
        setLoading(false);
      }
    };
    fetchData();

    // 场景2:绑定窗口滚动监听事件
    const handleScroll = () => {
      console.log('滚动位置:', window.scrollY);
    };
    window.addEventListener('scroll', handleScroll);

    // 场景3:开启定时器
    const timer = setInterval(() => {
      console.log('定时器执行中...');
    }, 1000);

    // 清理逻辑:卸载时执行
    return () => {
      window.removeEventListener('scroll', handleScroll); // 移除事件监听
      clearInterval(timer); // 清除定时器
      // 若有未完成的请求,可在此处取消(如使用 AbortController)
    };
  }, []); // 空依赖,仅挂载时执行

  if (loading) return <div>加载中...</div>;

  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

3. useContext:跨组件状态共享的"快捷方式"

核心作用:解决"组件层级过深时的 props 透传问题"(即"props drilling"),允许子组件直接获取父组件提供的共享状态,无需通过中间组件层层传递。

应用场景

  • 共享全局基础状态(如主题色、语言设置、用户登录状态);
  • 共享组件树内的公共状态(如表单步骤组件间的步骤状态、列表页与详情页的共享筛选条件);
  • 简化跨层级组件的通信(如爷爷组件向孙子组件传递数据,无需父组件中转)。

使用步骤

  1. 创建 Context:const MyContext = createContext(默认值);(默认值仅在无 Provider 时生效);
  2. 提供 Context:用 <MyContext.Provider value={共享数据/方法}> 包裹需要共享数据的组件树;
  3. 消费 Context:在子组件中用 useContext(MyContext) 获取共享数据。

使用注意:useContext 适合共享"变化不频繁"的状态,若需频繁更新且涉及复杂逻辑,建议结合 useReducer 或专门的状态管理库(如 Redux Toolkit)。

实战案例:全局主题切换(多组件共享主题状态)

javascript 复制代码
import { createContext, useContext, useState } from 'react';

// 1. 创建主题 Context
const ThemeContext = createContext('light');

// 2. 提供 Context 的顶层组件(如 App 或专门的 Provider 组件)
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  // 共享的方法:切换主题
  const toggleTheme = () => {
    setTheme(prev => prev === 'light' ? 'dark' : 'light');
  };

  // 向子组件提供的共享数据(状态+方法)
  const contextValue = { theme, toggleTheme };

  return (
    <ThemeContext.Provider value={contextValue}>
      {children} {/* 包裹需要共享主题的所有组件 */}
    </ThemeContext.Provider>
  );
}

// 3. 消费 Context 的子组件1:主题按钮(任意层级)
function ThemeToggleButton() {
  const { theme, toggleTheme } = useContext(ThemeContext);
  return (
    <button
      onClick={toggleTheme}
      style={{
        background: theme === 'light' ? '#fff' : '#333',
        color: theme === 'light' ? '#333' : '#fff',
        padding: '8px 16px',
        border: '1px solid #ccc'
      }}
    >
      切换到 {theme === 'light' ? '深色' : '浅色'} 主题
    </button>
  );
}

// 4. 消费 Context 的子组件2:主题内容区(任意层级)
function ThemeContent() {
  const { theme } = useContext(ThemeContext);
  return (
    <div
      style={{
        width: '300px',
        height: '200px',
        margin: '20px 0',
        background: theme === 'light' ? '#fff' : '#333',
        color: theme === 'light' ? '#333' : '#fff',
        padding: '20px'
      }}
    >
      <h3>当前主题:{theme}</h3>
      <p>跨组件共享主题状态示例</p>
    </div>
  );
}

// 根组件
function App() {
  return (
    <ThemeProvider>
      <div>
        <ThemeToggleButton />
        <ThemeContent />
      </div>
    </ThemeProvider>
  );
}

4. useCallback:缓存函数的"性能优化工具"

核心作用:缓存函数引用,避免函数在组件每次渲染时重新创建,减少因函数引用变化导致的子组件不必要重渲染。

应用场景

  • 向子组件传递回调函数时(尤其是子组件使用 React.memo 包裹进行性能优化时);
  • 函数作为 useEffect 的依赖时(避免因函数重新创建导致 useEffect 不必要执行);
  • 高频渲染的组件中(如列表项组件,每个列表项需传递点击事件函数)。

语法const 缓存的函数 = useCallback(原函数, [依赖数组]);

使用注意 :依赖数组需包含原函数中使用的所有外部变量/状态;若函数无依赖,依赖数组可为空([]);仅在函数引用变化会导致性能问题时使用,无需过度使用。

实战案例:优化子组件重渲染

javascript 复制代码
import { useState, useCallback, memo } from 'react';

// 子组件:用 React.memo 包裹,仅在 props 变化时重渲染
const Child = memo(({ onClick, name }) => {
  console.log(`${name} 子组件渲染了`);
  return (
    <button onClick={onClick} style={{ margin: '5px' }}>
      {name} 按钮
    </button>
  );
});

function UseCallbackDemo() {
  const [count, setCount] = useState(0);

  // 未使用 useCallback:每次渲染都会重新创建函数,导致 Child 重渲染
  const handleNormalClick = () => {
    console.log('普通按钮点击');
  };

  // 使用 useCallback:缓存函数引用,仅依赖变化时才重新创建
  const handleCachedClick = useCallback(() => {
    console.log('缓存按钮点击');
  }, []); // 无依赖,永久缓存

  return (
    <div>
      <p>计数:{count}</p>
      <button onClick={() => setCount(prev => prev + 1)}>+1(触发父组件渲染)</button>
      <Child onClick={handleNormalClick} name="普通" />
      <Child onClick={handleCachedClick} name="缓存" />
    </div>
  );
}

运行结果:点击"+1"按钮触发父组件渲染时,"普通按钮"子组件会重新渲染(因 handleNormalClick 函数重新创建),而"缓存按钮"子组件不会重新渲染(因 handleCachedClick 引用未变)。

5. useRef:获取 DOM/保存持久值的"工具 Hooks"

核心作用:有两个核心用途------一是获取 DOM 元素或组件实例;二是保存"持久化值"(组件重新渲染时值不重置,且修改值不会触发组件重新渲染)。

应用场景

  • 获取 DOM 元素:实现输入框自动聚焦、获取 DOM 尺寸/位置、操作 DOM 元素(如设置样式、触发事件);
  • 保存持久值:记录组件渲染次数、保存定时器 ID、保存前一次的状态/Props 值、存储不希望触发重新渲染的数据。

语法const ref 对象 = useRef(初始值);(通过 ref.current 访问/修改值)

使用注意 :修改 ref.current 是同步的,但不会触发组件重新渲染;若需基于 ref 值更新 UI,需配合 useState 或 useEffect。

实战案例:输入框自动聚焦+记录渲染次数

javascript 复制代码
import { useRef, useState, useEffect } from 'react';

function UseRefDemo() {
  const [count, setCount] = useState(0);
  // 场景1:获取 DOM 元素(输入框)
  const inputRef = useRef(null);
  // 场景2:保存持久值(渲染次数)
  const renderCountRef = useRef(0);

  // 每次渲染后更新渲染次数(useEffect 无依赖,每次渲染都执行)
  useEffect(() => {
    renderCountRef.current += 1;
    console.log('组件渲染次数:', renderCountRef.current);
  });

  // 挂载时让输入框自动聚焦
  useEffect(() => {
    inputRef.current.focus();
  }, []);

  // 点击按钮滚动到输入框位置
  const scrollToInput = () => {
    inputRef.current.scrollIntoView({ behavior: 'smooth' });
  };

  return (
    <div style={{ marginTop: '50px' }}>
      <p>计数:{count}</p>
      <p>组件渲染次数:{renderCountRef.current}</p>
      <button onClick={() => setCount(prev => prev + 1)}>+1(触发渲染)</button>
      <button onClick={scrollToInput}>滚动到输入框</button>

      {/* 输入框:通过 ref 关联 */}
      <div style={{ marginTop: '200px' }}>
        <input
          ref={inputRef}
          type="text"
          placeholder="我会自动聚焦..."
          style={{ width: '300px', height: '30px' }}
        />
      </div>
    </div>
  );
}

6. useMemo:缓存计算结果的"性能优化工具"

核心作用:缓存"昂贵计算"的结果,避免组件每次渲染时重复执行相同的复杂计算,提升组件渲染性能。

应用场景

  • 执行复杂计算时(如大数据量列表排序、过滤、复杂数学计算);
  • 计算结果作为 props 传递给子组件时(避免因计算结果重新创建导致子组件不必要重渲染);
  • 基于多个状态/Props 推导衍生数据时(如根据筛选条件和排序规则推导过滤后的列表)。

语法const 缓存的计算结果 = useMemo(() => 计算逻辑, [依赖数组]);

使用注意:依赖数组需包含计算逻辑中使用的所有外部变量/状态;仅用于"昂贵计算",简单计算无需使用(缓存本身有轻微开销);useMemo 是"备忘录",仅在依赖变化时重新计算。

实战案例:优化大数据量排序

javascript 复制代码
import { useState, useMemo } from 'react';

function UseMemoDemo() {
  const [list, setList] = useState(() => {
    // 模拟大数据量(10000 条数据)
    return Array.from({ length: 10000 }, (_, i) => ({ id: i, value: Math.random() * 1000 }));
  });
  const [sortType, setSortType] = useState('asc'); // asc:升序,desc:降序

  // 场景:复杂计算(大数据量排序),用 useMemo 缓存结果
  const sortedList = useMemo(() => {
    console.log('执行排序计算...');
    // 模拟昂贵计算(排序 10000 条数据)
    return [...list].sort((a, b) => {
      return sortType === 'asc' ? a.value - b.value : b.value - a.value;
    });
  }, [list, sortType]); // 仅 list 或 sortType 变化时重新排序

  return (
    <div>
      <button onClick={() => setSortType(prev => prev === 'asc' ? 'desc' : 'asc')}>
        切换排序(当前:{sortType === 'asc' ? '升序' : '降序'})
      </button>
      <div style={{ marginTop: '20px' }}>
        {/* 仅渲染前 10 条数据,避免页面卡顿 */}
        {sortedList.slice(0, 10).map(item => (
          <p key={item.id}>ID:{item.id},值:{item.value.toFixed(2)}</p>
        ))}
      </div>
    </div>
  );
}

运行结果:首次渲染和切换排序时会执行排序计算(控制台打印"执行排序计算..."),若仅触发其他不相关状态更新(如添加一个无关计数器),sortedList 会直接使用缓存结果,不会重新排序。

7. useDeferredValue:延迟更新非紧急状态的"体验优化工具"

核心作用:创建一个"延迟版本"的状态,当组件有紧急更新(如输入框输入)时,优先执行紧急更新,非紧急更新延迟到紧急更新完成后再执行,避免页面卡顿,提升用户体验。

应用场景

  • 输入框实时搜索(输入是紧急更新,搜索结果渲染是非紧急更新,避免输入卡顿);
  • 大数据量列表实时筛选(输入筛选条件是紧急更新,筛选结果渲染是非紧急更新);
  • 任何需要"优先响应用户操作"的场景(如拖拽时的非紧急状态更新)。

语法const 延迟状态 = useDeferredValue(原始状态);

使用注意:useDeferredValue 是"被动延迟",依赖原始状态变化;延迟状态会"追平"原始状态,最终与原始状态一致;无需手动清理,React 会自动处理。

实战案例:输入框实时搜索(优化输入体验)

ini 复制代码
import { useState, useDeferredValue } from 'react';

// 模拟大数据量列表(10000 条数据)
const mockList = Array.from({ length: 10000 }, (_, i) => ({
  id: i,
  name: `商品 ${i + 1} - ${Math.random().toString(36).substring(2, 6)}`
}));

function DeferredValueSearch() {
  // 紧急状态:输入框输入值(优先响应)
  const [searchValue, setSearchValue] = useState('');
  // 延迟状态:搜索值的延迟版本(非紧急,等输入完成后再更新)
  const deferredSearchValue = useDeferredValue(searchValue);

  // 根据延迟搜索值筛选列表(非紧急操作)
  const filteredList = mockList.filter(item => {
    return item.name.includes(deferredSearchValue);
  });

  return (
    <div>
      <input
        type="text"
        value={searchValue}
        onChange={(e) => setSearchValue(e.target.value)}
        placeholder="输入关键词搜索商品..."
        style={{ width: '300px', height: '30px', padding: '0 8px' }}
      />
      <div style={{ marginTop: '20px' }}>
        {filteredList.slice(0, 10).map(item => (
          <p key={item.id}>{item.name}</p>
        ))}
        {filteredList.length === 0 && <p>无匹配商品</p>}
      </div>
    </div>
  );
}

效果说明:若不使用 useDeferredValue,输入时会实时执行筛选逻辑(10000 条数据过滤),导致输入框卡顿;使用后,输入操作优先执行,筛选逻辑延迟到输入间隙执行,输入框流畅无卡顿。

8. useTransition:标记非紧急更新的"体验优化工具"

核心作用:将"非紧急的状态更新"标记为过渡更新,React 会优先处理紧急更新(如输入、点击等用户交互),非紧急更新在后台异步执行,避免阻塞用户操作,提升体验。

应用场景

  • 点击按钮触发的大数据量筛选/排序(点击是紧急操作,筛选/排序是非紧急更新);
  • 表单提交后的数据处理(提交操作是紧急的,后续数据加工是非紧急的);
  • 页面切换时的非紧急数据预加载(页面切换是紧急的,预加载数据是非紧急的)。

语法const [isPending, startTransition] = useTransition();

关键说明:

  • startTransition:包裹非紧急的状态更新逻辑;
  • isPending:布尔值,标记过渡更新是否正在进行(可用于显示加载状态)。

使用注意:useTransition 是"主动标记"非紧急更新,需手动将更新逻辑放入 startTransition 中;过渡更新可被中断(如用户触发新的紧急更新),避免无效计算。

实战案例:按钮触发的大数据量排序(优化点击体验)

ini 复制代码
import { useState, useTransition } from 'react';

// 模拟大数据量(10000 条数据)
const mockList = Array.from({ length: 10000 }, (_, i) => ({
  id: i,
  value: Math.random() * 1000
}));

function TransitionSort() {
  const [list, setList] = useState(mockList);
  const [sortType, setSortType] = useState('asc');
  // 获取过渡更新状态(是否正在排序)和标记函数
  const [isPending, startTransition] = useTransition();

  const handleSort = () => {
    const newSortType = sortType === 'asc' ? 'desc' : 'asc';
    setSortType(newSortType); // 紧急更新:切换排序类型文字

    // 非紧急更新:大数据量排序,标记为过渡更新
    startTransition(() => {
      const sortedList = [...mockList].sort((a, b) => {
        return newSortType === 'asc' ? a.value - b.value : b.value - a.value;
      });
      setList(sortedList);
    });
  };

  return (
    <div>
      <button onClick={handleSort} disabled={isPending}>
        {isPending ? '排序中...' : `切换排序(当前:${sortType === 'asc' ? '升序' : '降序'})`}
      </button>
      <div style={{ marginTop: '20px' }}>
        {list.slice(0, 10).map(item => (
          <p key={item.id}>ID:{item.id},值:{item.value.toFixed(2)}</p>
        ))}
      </div>
    </div>
  );
}

效果说明:点击按钮后,排序类型文字(sortType)立即更新(紧急更新),排序逻辑在后台异步执行;排序过程中按钮显示"排序中..."并禁用,避免重复点击;若排序未完成时触发新的紧急操作,排序可被中断,提升整体体验。

三、React 19 生命周期与 Hooks 对应关系梳理(精准图例+核心总结)

为了让大家更清晰地对应"生命周期阶段"与" Hooks 用法",我们用以下精准图例总结,覆盖所有核心场景:

核心总结

  1. 生命周期是"阶段",Hooks 是"实现工具" :函数组件通过不同 Hooks 覆盖挂载、更新、卸载全阶段逻辑,其中 useEffect 是核心生命周期 Hooks,其他 Hooks 按需补充功能;
  2. 8 个核心 Hooks 各司其职:状态管理(useState)、副作用处理(useEffect)、跨组件共享(useContext)、性能优化(useCallback、useMemo)、DOM/持久值(useRef)、体验优化(useDeferredValue、useTransition);
  3. 使用 Hooks 需遵循核心规则:仅在函数组件/自定义 Hooks 顶层调用,不能在条件/循环/嵌套函数中使用;命名以 use 开头;依赖数组需完整包含外部依赖;
  4. 优化类 Hooks 避免过度使用:useCallback、useMemo、useDeferredValue、useTransition 均为优化手段,需结合实际场景使用,简单场景无需额外优化(优化本身有开销)。

四、常见误区与避坑指南

  • 误区 1:过度依赖 useEffect:简单的状态计算、DOM 操作若可同步执行,无需放入 useEffect,避免不必要的渲染延迟;
  • 误区 2:useCallback/useMemo 滥用:简单函数、简单计算无需缓存,仅在确有性能问题时使用;
  • 误区 3:useDeferredValue 与 useTransition 混淆:useDeferredValue 是"被动延迟状态",依赖原始状态;useTransition 是"主动标记更新",需手动包裹更新逻辑;
  • 误区 4:useContext 替代状态管理库:useContext 适合共享少量固定状态,复杂状态更新(如多组件修改同一状态)建议结合 useReducer 或 Redux Toolkit;
  • 误区 5:修改 ref.current 期望触发渲染:ref.current 变化不会触发组件重新渲染,若需更新 UI,需配合 useState 或 useEffect。

五、下一步学习方向

今天我们建立了 React 19 生命周期与 8 个核心 Hooks 的完整认知,这是函数组件开发的核心基础。下一步可以重点学习:

  • 自定义 Hooks:将复用逻辑封装为自定义 Hooks(如 useFetch、useTimer),提升代码复用性;
  • useReducer:处理复杂状态逻辑,替代 useState 实现多状态联动;
  • React 19 新增 Hooks:如 use()、useOptimistic 等,简化异步数据处理和乐观更新;
  • Hooks 性能优化实战:结合 React DevTools 分析组件渲染,精准使用优化类 Hooks。

如果这篇文章对你有帮助,欢迎点赞、收藏、转发~ 有任何问题也可以在评论区留言交流~ 我们下期再见!

相关推荐
xjt_090111 分钟前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农22 分钟前
Vue 2.3
前端·javascript·vue.js
夜郎king1 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳1 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵2 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星2 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_2 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝2 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions2 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发2 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法