<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>GDYG</title>
        <link>https://gdyg.blog/</link>
        <description>一个分享和记录日常笔记的博客</description>
        <lastBuildDate>Fri, 26 Jun 2026 09:12:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en-US</language>
        <copyright>All rights reserved 2026, GDYG</copyright>
        <item>
            <title><![CDATA[从零构建现代化DeFi资产管理面板：Next.js + Web3技术栈实战]]></title>
            <link>https://gdyg.blog/article/defi-dashboard</link>
            <guid>https://gdyg.blog/article/defi-dashboard</guid>
            <pubDate>Wed, 28 May 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[DeFi-Dashboard资产管理面板]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-20120f78d83e8007af16d94bac25f3f3"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-20120f78d83e80799d81d7e748155963" data-id="20120f78d83e80799d81d7e748155963"><span><div id="20120f78d83e80799d81d7e748155963" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80799d81d7e748155963" title="从零构建现代化DeFi资产管理面板：Next.js + Web3技术栈实战"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">从零构建现代化DeFi资产管理面板：Next.js + Web3技术栈实战</span></span></h2><blockquote class="notion-quote notion-block-20120f78d83e800b9d02d61955bce7db"><div>在Web3时代，如何构建一个既美观又实用的去中心化金融应用？本文将带你深入了解一个完整的DeFi Dashboard项目，从技术选型到实现细节，全面解析现代Web3应用的开发之道。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e80a386c9dab7ed1701af" data-id="20120f78d83e80a386c9dab7ed1701af"><span><div id="20120f78d83e80a386c9dab7ed1701af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80a386c9dab7ed1701af" title="🎯 项目概览"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🎯 项目概览</span></span></h3><div class="notion-text notion-block-20120f78d83e8055a124fc3672dc3e70">在区块链技术日益成熟的今天，DeFi（去中心化金融）已经成为Web3生态中最重要的应用场景之一。然而，大多数用户在管理自己的数字资产时，往往需要在多个平台间切换，体验并不理想。</div><div class="notion-text notion-block-20120f78d83e801db76cd084c2a8c131">为了解决这个痛点，我们开发了一个现代化的DeFi资产管理面板，它不仅能够连接用户的钱包，还能实时显示真实的资产余额、交易记录和投资组合概览。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80a68470ff65d277985d" data-id="20120f78d83e80a68470ff65d277985d"><span><div id="20120f78d83e80a68470ff65d277985d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80a68470ff65d277985d" title="✨ 核心功能特性"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">✨ 核心功能特性</span></span></h4><ul class="notion-list notion-list-disc notion-block-20120f78d83e8082a78ef46ecf33125b"><li>🔗 <b>无缝钱包集成</b>：支持MetaMask、WalletConnect等主流钱包</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e80b39cfddc3e27afe876"><li>💰 <b>真实链上数据</b>：直接从以太坊网络获取用户资产信息</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e80f185b2cc7b00d33e63"><li>📊 <b>智能投资组合分析</b>：实时计算总资产价值和持仓分布</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e8053a7f2f1a790c42fab"><li>📝 <b>完整交易历史</b>：展示ETH和ERC20代币的转账记录</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e809eb8e9dd8ca60515aa"><li>🌙 <b>现代化UI设计</b>：深色主题配合响应式布局</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e80cab718ec917c3655a9"><li>⚡ <b>高性能数据获取</b>：集成多个API确保数据准确性</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e8062ad54ccea3de68f55" data-id="20120f78d83e8062ad54ccea3de68f55"><span><div id="20120f78d83e8062ad54ccea3de68f55" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8062ad54ccea3de68f55" title="🛠 技术架构深度解析"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🛠 技术架构深度解析</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e8097b884e0774ec540b4" data-id="20120f78d83e8097b884e0774ec540b4"><span><div id="20120f78d83e8097b884e0774ec540b4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8097b884e0774ec540b4" title="前端技术栈选择"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">前端技术栈选择</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e8036b7dfe79615c83c04" data-id="20120f78d83e8036b7dfe79615c83c04"><span><div id="20120f78d83e8036b7dfe79615c83c04" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8036b7dfe79615c83c04" title="为什么选择Next.js？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么选择Next.js？</span></span></h4><div class="notion-text notion-block-20120f78d83e806db079efe58414588f">Next.js 15作为React的生产级框架，为我们提供了：</div><ol start="1" class="notion-list notion-list-numbered notion-block-20120f78d83e800d88f8f454ff6c06b3" style="list-style-type:decimal"><li><b>服务端渲染（SSR）</b>：提升首屏加载速度和SEO表现</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-20120f78d83e80fba7e6d96e9727db68" style="list-style-type:decimal"><li><b>API路由</b>：内置API处理能力，便于集成第三方服务</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-20120f78d83e80d194e9fa016f482caa" style="list-style-type:decimal"><li><b>自动代码分割</b>：优化包体积，提升用户体验</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-20120f78d83e80b68ea7c7fe2bf77594" style="list-style-type:decimal"><li><b>TypeScript原生支持</b>：类型安全，减少运行时错误</li></ol><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e800f9741f1ec7b24b912" data-id="20120f78d83e800f9741f1ec7b24b912"><span><div id="20120f78d83e800f9741f1ec7b24b912" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e800f9741f1ec7b24b912" title="Web3技术栈的精心选择"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Web3技术栈的精心选择</span></span></h4><div class="notion-text notion-block-20120f78d83e800496daf9b19afaafb6"><b>wagmi + RainbowKit组合</b>是目前最优雅的Web3集成方案：</div><ul class="notion-list notion-list-disc notion-block-20120f78d83e80d1a0bae33266f67a34"><li><b>wagmi</b>：提供React Hooks形式的Web3功能，类型安全且易于使用</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e801fabd5fc551104426e"><li><b>RainbowKit</b>：美观的钱包连接UI组件，支持多种钱包</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e803f93d2de63ea2a72af"><li><b>viem</b>：现代化的以太坊客户端库，性能优异</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80338c27ff8945b7be72" data-id="20120f78d83e80338c27ff8945b7be72"><span><div id="20120f78d83e80338c27ff8945b7be72" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80338c27ff8945b7be72" title="数据层架构设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数据层架构设计</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e8095b143e993fb033d2c" data-id="20120f78d83e8095b143e993fb033d2c"><span><div id="20120f78d83e8095b143e993fb033d2c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8095b143e993fb033d2c" title="多源数据聚合策略"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">多源数据聚合策略</span></span></h4><div class="notion-text notion-block-20120f78d83e8055bbf2ee6872e9fefa">为了确保数据的准确性和可靠性，我们采用了多API源聚合的策略：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80ebbb0ed583252a585a" data-id="20120f78d83e80ebbb0ed583252a585a"><span><div id="20120f78d83e80ebbb0ed583252a585a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80ebbb0ed583252a585a" title="状态管理最佳实践"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">状态管理最佳实践</span></span></h4><div class="notion-text notion-block-20120f78d83e80b4bdd1f1523fd6c884">使用Zustand进行轻量级状态管理：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e8034a01ec33cdef06b5b" data-id="20120f78d83e8034a01ec33cdef06b5b"><span><div id="20120f78d83e8034a01ec33cdef06b5b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8034a01ec33cdef06b5b" title="🔧 核心功能实现详解"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🔧 核心功能实现详解</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e801abb84f3dcc36560e0" data-id="20120f78d83e801abb84f3dcc36560e0"><span><div id="20120f78d83e801abb84f3dcc36560e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e801abb84f3dcc36560e0" title="1. 钱包连接与管理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 钱包连接与管理</span></span></h4><div class="notion-text notion-block-20120f78d83e80a28341c57b3b01c631">钱包连接是Web3应用的入口，我们通过RainbowKit实现了优雅的连接体验：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e802c8359c8b8f0e2f19f" data-id="20120f78d83e802c8359c8b8f0e2f19f"><span><div id="20120f78d83e802c8359c8b8f0e2f19f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e802c8359c8b8f0e2f19f" title="2. 实时资产数据获取"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 实时资产数据获取</span></span></h4><div class="notion-text notion-block-20120f78d83e803a9354d99fb73f68f4">通过集成多个API源，确保数据的准确性：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e8038a501f92aceef9c23" data-id="20120f78d83e8038a501f92aceef9c23"><span><div id="20120f78d83e8038a501f92aceef9c23" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8038a501f92aceef9c23" title="3. 交易记录展示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 交易记录展示</span></span></h4><div class="notion-text notion-block-20120f78d83e80cf812bfe449a3581f6">通过Etherscan API获取完整的交易历史：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e8066b499fe9676a48bb4" data-id="20120f78d83e8066b499fe9676a48bb4"><span><div id="20120f78d83e8066b499fe9676a48bb4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8066b499fe9676a48bb4" title="🎨 UI/UX设计亮点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🎨 UI/UX设计亮点</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80b28454f73009ab75c3" data-id="20120f78d83e80b28454f73009ab75c3"><span><div id="20120f78d83e80b28454f73009ab75c3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80b28454f73009ab75c3" title="现代化深色主题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">现代化深色主题</span></span></h4><div class="notion-text notion-block-20120f78d83e8033a87cced5a45de96b">我们采用了现代化的深色主题设计。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e808d9eadd4b110266082" data-id="20120f78d83e808d9eadd4b110266082"><span><div id="20120f78d83e808d9eadd4b110266082" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e808d9eadd4b110266082" title="响应式布局设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">响应式布局设计</span></span></h4><div class="notion-text notion-block-20120f78d83e80ff9dfbcb1cddb56b03">通过Tailwind CSS的响应式工具类，确保在各种设备上都有良好的体验：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e8042b7b1e94cd81565de" data-id="20120f78d83e8042b7b1e94cd81565de"><span><div id="20120f78d83e8042b7b1e94cd81565de" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8042b7b1e94cd81565de" title="加载状态和错误处理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">加载状态和错误处理</span></span></h4><div class="notion-text notion-block-20120f78d83e80318a69d5bb7adfd08c">优雅的加载状态和错误处理提升用户体验：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e80ff968edf409fc1017c" data-id="20120f78d83e80ff968edf409fc1017c"><span><div id="20120f78d83e80ff968edf409fc1017c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80ff968edf409fc1017c" title="🚀 性能优化策略"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🚀 性能优化策略</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80e7b4d4e40949afd078" data-id="20120f78d83e80e7b4d4e40949afd078"><span><div id="20120f78d83e80e7b4d4e40949afd078" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80e7b4d4e40949afd078" title="1. 数据缓存机制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 数据缓存机制</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e808d8b09c0343f1d6542" data-id="20120f78d83e808d8b09c0343f1d6542"><span><div id="20120f78d83e808d8b09c0343f1d6542" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e808d8b09c0343f1d6542" title="2. 组件懒加载"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 组件懒加载</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80f4a184def3f305e407" data-id="20120f78d83e80f4a184def3f305e407"><span><div id="20120f78d83e80f4a184def3f305e407" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80f4a184def3f305e407" title="3. API请求优化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. API请求优化</span></span></h4><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e80c68ae5edd39edbff10" data-id="20120f78d83e80c68ae5edd39edbff10"><span><div id="20120f78d83e80c68ae5edd39edbff10" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80c68ae5edd39edbff10" title="🔒 安全性考虑"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🔒 安全性考虑</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e806c9d3ed44706449fc1" data-id="20120f78d83e806c9d3ed44706449fc1"><span><div id="20120f78d83e806c9d3ed44706449fc1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e806c9d3ed44706449fc1" title="1. 只读权限设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 只读权限设计</span></span></h4><div class="notion-text notion-block-20120f78d83e8005bd11e5a9e4a6e0bc">应用采用只读设计，只获取公开的区块链数据，不涉及私钥或签名操作：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80d5afb8eafe1ef78faf" data-id="20120f78d83e80d5afb8eafe1ef78faf"><span><div id="20120f78d83e80d5afb8eafe1ef78faf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80d5afb8eafe1ef78faf" title="2. 环境变量管理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 环境变量管理</span></span></h4><div class="notion-text notion-block-20120f78d83e80c690c2c630602189c2">敏感信息通过环境变量管理：</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e805099a5fe694ba58cd5" data-id="20120f78d83e805099a5fe694ba58cd5"><span><div id="20120f78d83e805099a5fe694ba58cd5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e805099a5fe694ba58cd5" title="3. 输入验证和错误处理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 输入验证和错误处理</span></span></h4><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e80e59f6dcdc81d226129" data-id="20120f78d83e80e59f6dcdc81d226129"><span><div id="20120f78d83e80e59f6dcdc81d226129" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80e59f6dcdc81d226129" title="📊 项目亮点与创新"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📊 项目亮点与创新</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80668e1bf4e730974d8b" data-id="20120f78d83e80668e1bf4e730974d8b"><span><div id="20120f78d83e80668e1bf4e730974d8b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80668e1bf4e730974d8b" title="1. 真实数据集成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 真实数据集成</span></span></h4><div class="notion-text notion-block-20120f78d83e802f9a47c5d65e71975b">与许多演示项目不同，我们的Dashboard展示的是真实的区块链数据，用户连接钱包后能看到实际的资产余额和交易记录。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e8069bf2dfbdadb134ea6" data-id="20120f78d83e8069bf2dfbdadb134ea6"><span><div id="20120f78d83e8069bf2dfbdadb134ea6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8069bf2dfbdadb134ea6" title="2. 多API源聚合"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 多API源聚合</span></span></h4><div class="notion-text notion-block-20120f78d83e80298a26fc892a17a911">通过整合Etherscan、Alchemy和CoinGecko等多个数据源，确保数据的准确性和可靠性。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80308553e7ee8794dadb" data-id="20120f78d83e80308553e7ee8794dadb"><span><div id="20120f78d83e80308553e7ee8794dadb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80308553e7ee8794dadb" title="3. 现代化技术栈"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 现代化技术栈</span></span></h4><div class="notion-text notion-block-20120f78d83e80119599c87697c21097">采用最新的Web3技术栈，代码结构清晰，易于维护和扩展。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80cda013d61ecc19020c" data-id="20120f78d83e80cda013d61ecc19020c"><span><div id="20120f78d83e80cda013d61ecc19020c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80cda013d61ecc19020c" title="4. 优秀的用户体验"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 优秀的用户体验</span></span></h4><div class="notion-text notion-block-20120f78d83e80da9bd5fa38205ab9c0">从钱包连接到数据展示，每个环节都经过精心设计，提供流畅的用户体验。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e8077bf52dfdf8b05d5d5" data-id="20120f78d83e8077bf52dfdf8b05d5d5"><span><div id="20120f78d83e8077bf52dfdf8b05d5d5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8077bf52dfdf8b05d5d5" title="🔮 路线图"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🔮 路线图</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e801292c5fca33aa939c4" data-id="20120f78d83e801292c5fca33aa939c4"><span><div id="20120f78d83e801292c5fca33aa939c4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e801292c5fca33aa939c4" title="短期计划"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">短期计划</span></span></h4><ul class="notion-list notion-list-disc notion-block-20120f78d83e805db257d37788d3d1ab"><li>🔄 支持更多ERC20代币</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e80da9f2eebe88f648733"><li>📈 集成价格图表和历史数据</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e802e8c0dd922c32d5bd6"><li>🔄 添加DeFi协议集成（Uniswap、Compound等）</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e804caebdfe103aef3c47"><li>📱 开发移动端原生应用</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-20120f78d83e80879c73cbb46944f46d" data-id="20120f78d83e80879c73cbb46944f46d"><span><div id="20120f78d83e80879c73cbb46944f46d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e80879c73cbb46944f46d" title="长期愿景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">长期愿景</span></span></h4><ul class="notion-list notion-list-disc notion-block-20120f78d83e806d8c7ecc4a070d004a"><li>🤖 AI驱动的投资建议</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e8034a1c5eacdcb3af56d"><li>🔗 跨链资产管理</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e809d838bdf4730bb0650"><li>📊 高级分析工具</li></ul><ul class="notion-list notion-list-disc notion-block-20120f78d83e80c1bf77e280b7eea36c"><li>🛡️ 安全监控和风险评估</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e805eaafec62419e2a020" data-id="20120f78d83e805eaafec62419e2a020"><span><div id="20120f78d83e805eaafec62419e2a020" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e805eaafec62419e2a020" title="🎯 技术学习价值"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🎯 技术学习价值</span></span></h3><div class="notion-text notion-block-20120f78d83e8007a0eae126efa5e232">这个项目对于想要学习Web3开发的开发者来说具有很高的学习价值：</div><ol start="1" class="notion-list notion-list-numbered notion-block-20120f78d83e804a805cde00384b08c1" style="list-style-type:decimal"><li><b>完整的Web3技术栈</b>：从前端到区块链集成的完整实现</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-20120f78d83e80acbea4cf9de4fc0f55" style="list-style-type:decimal"><li><b>真实项目经验</b>：处理真实数据和用户场景</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-20120f78d83e803f9015e274df9e624c" style="list-style-type:decimal"><li><b>最佳实践示例</b>：代码结构、错误处理、性能优化等</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-20120f78d83e809cb6cdf0daf0ef0a0e" style="list-style-type:decimal"><li><b>现代化开发流程</b>：TypeScript、ESLint、自动化部署等</li></ol><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e8072bccfefad92571d4e" data-id="20120f78d83e8072bccfefad92571d4e"><span><div id="20120f78d83e8072bccfefad92571d4e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8072bccfefad92571d4e" title="🚀 快速开始"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🚀 快速开始</span></span></h3><div class="notion-text notion-block-20120f78d83e8049bf53c6cab953b2e7">想要体验或学习这个项目？只需几个简单步骤：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-20120f78d83e8078910ee984380265c0" data-id="20120f78d83e8078910ee984380265c0"><span><div id="20120f78d83e8078910ee984380265c0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20120f78d83e8078910ee984380265c0" title="💡 结语"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">💡 结语</span></span></h3><div class="notion-text notion-block-20120f78d83e8009b350ee89b384ba17">在Web3技术快速发展的今天，构建一个既实用又美观的DeFi应用需要综合考虑技术选型、用户体验、安全性等多个方面。这个DeFi Dashboard项目展示了如何使用现代化的技术栈来构建高质量的Web3应用。</div><div class="notion-text notion-block-20120f78d83e804b8327d5f603a765c5">无论你是Web3开发的新手还是经验丰富的开发者，这个项目都能为你提供有价值的参考和学习材料。让我们一起推动Web3生态的发展，构建更好的去中心化应用！</div><hr class="notion-hr notion-block-20120f78d83e801a9e3dee90b48ce73a"/><div class="notion-text notion-block-20120f78d83e80ba8e34c27f92ecb162"><b>项目地址</b>: [<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/GDYG/DeFi-Dashboard">GitHub Repository</a>]
<b>在线演示</b>: [<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://defi-dashboard-navy.vercel.app/">Live Demo</a>]
<b>技术交流</b>: 欢迎提交Issue和PR</div><div class="notion-text notion-block-20120f78d83e809c8b59d2ff47249c7e"><em>如果这个项目对你有帮助，别忘了给个⭐️支持一下！</em></div><div class="notion-blank notion-block-20120f78d83e803f9b76e0587f69bbb2"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React中的TDD权威指南：编写保证成功的测试]]></title>
            <link>https://gdyg.blog/article/tdd-react</link>
            <guid>https://gdyg.blog/article/tdd-react</guid>
            <pubDate>Mon, 09 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[测试驱动开发TDD]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-fde47fb855fe4cc790e07a4604316671"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><hr class="notion-hr notion-block-34937c671e0e44a5b96c576debb63e8c"/><div class="notion-text notion-block-cb2ed7dee6294d4a96f7fef429db4a7b">了解如何使用测试驱动开发（TDD）来构建强大的react组件，本步骤指南可以确保您的代码可靠且可维护</div><div class="notion-blank notion-block-6de169b30af74e44a83670ec938157bd"> </div><div class="notion-text notion-block-979d6a54992144c487fbf322c91411be">想象一下可以使用安全网进行编码，可以在错误发生前捕获它们。这就是TDD的力量，在本文中，我们将深入探讨它是如何彻底改变你的开发流程的。在测试驱动开发中，开发人员在实际开发代码之前首先编写测试用例，使用TDD方法编写代码有一下几点好处：</div><ul class="notion-list notion-list-disc notion-block-bf04ad7bb0794c7b886597a7e811086e"><li><b>更改质量的代码：</b>预先考虑测试可以使您更仔细的考虑需求和设计</li></ul><ul class="notion-list notion-list-disc notion-block-c14742b7c7064aee8d975ff0b6d5b98d"><li><b>快速反馈：</b>您可以获得即时验证，减少调试时间</li></ul><ul class="notion-list notion-list-disc notion-block-596d5b81504f437c95e8fae0a373ae26"><li><b>全面的测试覆盖范围：</b>TDD确保您整个的代码库经过彻底测试</li></ul><ul class="notion-list notion-list-disc notion-block-7cf083f69e634b91a1e0e160fc8e2a4e"><li><b>重构信息：</b>通过强大的测试套件，您可以自信的更改代码，而不必担心破坏代码</li></ul><ul class="notion-list notion-list-disc notion-block-f453045cafc7420da4652a26f10a7cc1"><li><b>动态文档：</b>您的测试程序可以成为如何使用它的示例</li></ul><div class="notion-blank notion-block-5187293808f24bee95c1d786fb1f599a"> </div><div class="notion-text notion-block-0732bdf9b5754ac597d787f77f463945">TDD分为三个主要阶段：<b>红色、绿色和重构。</b>红色阶段意味着编写测试用例并观察它的失败。绿色阶段意味着编写最少的代码来实现通过测试用例。重构阶段意味着通过重构来改进代码，以获得更好的结构、可读性和可维护性，而不该变功能，同时确保测试用例仍然通过。我们将React中构建一个登录页面，并详细介绍这一过程，该项目的完整代码<span class="notion-orange"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/anujkumartech/tddreact">在此处</a></span><span class="notion-default">找到。</span></div><div class="notion-blank notion-block-68b907875d334dc0b49abeb57515a085"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-37188305f34149b4ac078d88e6b40e7e" data-id="37188305f34149b4ac078d88e6b40e7e"><span><div id="37188305f34149b4ac078d88e6b40e7e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#37188305f34149b4ac078d88e6b40e7e" title="先决条件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">先决条件</span></span></h3><div class="notion-text notion-block-b7446f718fb7452180d5cf20de6ace53">以下是本文总需要遵循的先决条件：</div><ul class="notion-list notion-list-disc notion-block-5f8fbcf5c1d641a4853fdf3d36a47ce2"><li>了解<code class="notion-inline-code">JavaScript</code>和<code class="notion-inline-code">React</code> </li></ul><ul class="notion-list notion-list-disc notion-block-127dfaa77d4f4621970e5aac9bdec1fb"><li>您选择的代码编辑器</li></ul><div class="notion-blank notion-block-077c225983d446fab3a4efb1e7252fc9"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d9178003e21749e49dbfab492d802d03" data-id="d9178003e21749e49dbfab492d802d03"><span><div id="d9178003e21749e49dbfab492d802d03" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d9178003e21749e49dbfab492d802d03" title="启动一个新的React应用程序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">启动一个新的React应用程序</span></span></h3><ul class="notion-list notion-list-disc notion-block-aa0f2cc28a8948349e642e91cfa3c525"><li>确保使用<code class="notion-inline-code">node -v</code>和<code class="notion-inline-code">npm -v</code>验证安装了Nodejs和npm</li></ul><ul class="notion-list notion-list-disc notion-block-e6ff216a950f458e9b5942be8ba1e69d"><li>使用<code class="notion-inline-code">npx create-react-app tddreact</code>创建新的应用程序</li></ul><ul class="notion-list notion-list-disc notion-block-df630222872549bd9a0136637031adad"><li>使用<code class="notion-inline-code">cd tddreact</code>转到应用程序文件夹并使用<code class="notion-inline-code">npm start</code>启动应用程序</li></ul><ul class="notion-list notion-list-disc notion-block-0dd48286deda4d94a49c5e4d2e6cc1c1"><li>应用程序完全编译后，导航到lcoahost，你会看到应用程序已经加载完成</li></ul><div class="notion-blank notion-block-6eb7309015ad47e4be48feb33a1a5e7f"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f40b4b0291dc482283d2cc9d4dbdcac8" data-id="f40b4b0291dc482283d2cc9d4dbdcac8"><span><div id="f40b4b0291dc482283d2cc9d4dbdcac8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f40b4b0291dc482283d2cc9d4dbdcac8" title="添加测试用例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">添加测试用例</span></span></h3><div class="notion-text notion-block-6d92e0d6601944a7b6f21803e73ddb69">如前所示，如果用使用测试驱动开发，首先要编写初始测试用例。</div><ul class="notion-list notion-list-disc notion-block-5d7284ed93664934aec1769b1ca51b8c"><li>在src下创建__test__文件夹，文件名为login.test.js</li></ul><ul class="notion-list notion-list-disc notion-block-b963b76c6b914b33901818295829dd72"><li>接着添加你的第一个测试用例， 确保登录组件保持存在是基本的</li></ul><ul class="notion-list notion-list-disc notion-block-f497bb49fff74626a8c954f93ea21e25"><li>使用npm test运行测试用例，您将会看到如下的失败，这就是我们之前所说的红色阶段</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-143403d0244b4c4f90f6a3665fede346"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2Fc7c7d615-fb52-4e57-92ab-9dfb43c0331f%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=143403d0-244b-4c4f-90f6-a3665fede346&amp;t=143403d0-244b-4c4f-90f6-a3665fede346&amp;width=749.990234375&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ul class="notion-list notion-list-disc notion-block-516c9d6b01f34305b65d2df5e4877f17"><li>现在是时候添加登录组件并启用绿色阶段了</li></ul><ul class="notion-list notion-list-disc notion-block-014df8ad575c4a679c93d5dd894d7e5a"><li>在src/components下创建一个新文件，命名为Login.js，并添加如下代码：</li></ul><ul class="notion-list notion-list-disc notion-block-067fec9b8148439bb344c3a88d801da1"><li>测试用例现在应该已经通过，并且您成功实施了从红色到绿色阶段的一个周期</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3b348c5f92254961a93364b10b595412"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2F4a4d5a22-5ee0-4ee5-a818-af3ed5ef9e4d%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=3b348c5f-9225-4961-a933-64b10b595412&amp;t=3b348c5f-9225-4961-a933-64b10b595412&amp;width=707.998046875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-fec86a1c38bb4a3888b4b2e648dc3aed"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8297b2fa75fa4b47950baa86c8be3282" data-id="8297b2fa75fa4b47950baa86c8be3282"><span><div id="8297b2fa75fa4b47950baa86c8be3282" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8297b2fa75fa4b47950baa86c8be3282" title="添加我们的输入"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">添加我们的输入</span></span></h3><div class="notion-text notion-block-b6cb325f19394508b19c496dfd2e9bd4">在我们的登录页面上，用户应该能通过用户名和密码并单击登录按钮进行登录。</div><ul class="notion-list notion-list-disc notion-block-53b14184c0f8441bafa0bb2b0d36cb7a"><li>添加测试用例，其中用户名和密码应该出现在我们的页面上</li></ul><ul class="notion-list notion-list-disc notion-block-586d07b2985a47b1ab44f818050a8475"><li>您应该看到一些测试用例再次失败</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-2610dbdd9984473c8f44fd904a1576be"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2F029901e9-3cc2-41e3-9217-93c73605f3e9%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=2610dbdd-9984-473c-8f44-fd904a1576be&amp;t=2610dbdd-9984-473c-8f44-fd904a1576be&amp;width=707.998046875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ul class="notion-list notion-list-disc notion-block-74d9c124863849288ee21c794f5b8c88"><li>按照如下所示更改登录组件的返回方式，您应该能看到失败的测试用例通过</li></ul><div class="notion-blank notion-block-3eebd8ef498544e0a651beda40d6bdc1"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-373924bf2c4149a39a965efb333168e2" data-id="373924bf2c4149a39a965efb333168e2"><span><div id="373924bf2c4149a39a965efb333168e2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#373924bf2c4149a39a965efb333168e2" title="添加登录逻辑"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">添加登录逻辑</span></span></h3><div class="notion-text notion-block-7628b4ca201e4f12bcb1fc83aebefb31">现在您可以添加实际的登录逻辑。</div><ul class="notion-list notion-list-disc notion-block-71a2a8c9c49743eab448fb6516efc334"><li>为简单起见，当用户未输入用户名和密码进行点击登录按钮登录时，应显示一条错误消息。当用户输入用户名和密码进行登录时，不应显示错误消息。相反，显示欢迎消息，例如“欢迎John Doe”。可以通过以下测试将测试用例添加到测试文件中来捕获这些要求。</li></ul><ul class="notion-list notion-list-disc notion-block-1fb44831d90d4d73b71aac1bde4c6694"><li>这应该会导致测试用例失败，如果测试程序尚未运行，请执行<code class="notion-inline-code">npm test</code>运行它们。让我们在组件中实现此功能并通过测试用例。更新登录组件代码以添加缺少的功能，如下所示：</li></ul><ul class="notion-list notion-list-disc notion-block-245606050fd646cba40bc9740e26c449"><li>对于大多数场景，登录组件应该通知父组件已登录。让我们添加一些测试用例来实现此功能，添加测试用例后，验证您的终端是否有失败的测试用例。</li></ul><ul class="notion-list notion-list-disc notion-block-8d9b288490294872aa74858634b9ffeb"><li>让我们在登录组件中实现此功能，更新Login组件以接收<code class="notion-inline-code">onLogin</code>函数并更新<code class="notion-inline-code">handleSubmit</code>， 如下所示：</li></ul><ul class="notion-list notion-list-disc notion-block-40eb0cbe589b44d3b288a25a5af51e7b"><li>恭喜，登录组件已经实现，所有测试用例也通过。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-0ba7463c8f4a47f0a0445ee45ec30c6a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2Ffb57f9c8-9f07-4e30-a9b6-a76330f242f1%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=0ba7463c-8f4a-47f0-a044-5ee45ec30c6a&amp;t=0ba7463c-8f4a-47f0-a044-5ee45ec30c6a&amp;width=749.970703125&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-568195a093f14cfea7abd709452cb047"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-16eb02d22bef4891b034d094a2c8d781" data-id="16eb02d22bef4891b034d094a2c8d781"><span><div id="16eb02d22bef4891b034d094a2c8d781" class="notion-header-anchor"></div><a class="notion-hash-link" href="#16eb02d22bef4891b034d094a2c8d781" title="将登录组件集成到应用程序中"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">将登录组件集成到应用程序中</span></span></h3><ul class="notion-list notion-list-disc notion-block-664f13132c974228810196a2f2d079b7"><li><code class="notion-inline-code">create-react-app</code>将样板代码添加到<code class="notion-inline-code">App.js</code>中，我们必须先将<code class="notion-inline-code">App.js</code>原始的代码给去掉，如果您看到<code class="notion-inline-code">App.test.js</code>文件，也将其删除。</li></ul><ul class="notion-list notion-list-disc notion-block-ffcfb3c86c5443baa2e54c7f52dea063"><li>再次，我们将首先为App组件添加测试用例，首先在<code class="notion-inline-code">__test__</code>文件夹下创建<code class="notion-inline-code">App.test.js</code>文件</li></ul><ul class="notion-list notion-list-disc notion-block-c1553738590f4236a2cae31f8048b13a"><li>您可以从这些测试用例中获得关键见解：</li><ul class="notion-list notion-list-disc notion-block-c1553738590f4236a2cae31f8048b13a"><li>应用程序包含登录组件，登录成功后，需要像isLoggedIn变量来指示登录状态</li><li>用户登录成功后，您需要变更次变量并有条件的显示文本信息</li><li>您正在模拟登录组件，这很重要。因为您不希望应用程序组件的单元测试用例测试登录组件</li></ul></ul><ul class="notion-list notion-list-disc notion-block-6face2822b074a25a1ddccd7122c52b4"><li>使用所描述的功能实现应用程序组件。将以下代码添加到App.js中</li></ul><ul class="notion-list notion-list-disc notion-block-873653767b7f43a6a00129b1735efc45"><li>现在所有的测试用例都应该通过，使用npm start启动应用程序，您应该在localhost看到以下内容</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-2485a7789f9b4d59a1a13b25475fdba5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2Fc22efb8a-7ee7-40da-a3eb-1939ea14d275%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=2485a778-9f9b-4d59-a1a1-3b25475fdba5&amp;t=2485a778-9f9b-4d59-a1a1-3b25475fdba5&amp;width=749.98046875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-69f7da967a5d4e43a7811adf9d76029a"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-bc08fc31301b4ec69b8166391b226b2e" data-id="bc08fc31301b4ec69b8166391b226b2e"><span><div id="bc08fc31301b4ec69b8166391b226b2e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bc08fc31301b4ec69b8166391b226b2e" title="增强我们的应用程序"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">增强我们的应用程序</span></span></h3><div class="notion-text notion-block-4703917883354d869dbaf74f4e900b7a">您已经达到了TDD的关键时刻 - 重构阶段。登录组件的样式非常简单，让我们通过添加样式代码并更新登录组件的方式来增强它。</div><ul class="notion-list notion-list-disc notion-block-24888db5b0494ee9b45ddef746c72485"><li>在Login.js的旁边新建一个login.css的文件，并添加如下代码：</li></ul><ul class="notion-list notion-list-disc notion-block-2ef4c96efc844a3989bfdfbd81ad6ffc"><li>更新登录组件的渲染方法以使用样式。另外，在顶部倒入样式文件，以下是更新后的Login.js文件</li></ul><ul class="notion-list notion-list-disc notion-block-9c20fbd5ebea4d1eb7e1f76fd86d7fd6"><li>确保所有测试用例仍然通过<code class="notion-inline-code">npm test</code>输出</li></ul><ul class="notion-list notion-list-disc notion-block-673e0be0f463438d9181001d0b0a8ee0"><li>使用npm start再次启动应用程序，我们的页面将会变成下面这样</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8291a846130c4450890daa834db2a958"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2F205f5184-1fa4-475e-b302-d7a40af7d4be%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=8291a846-130c-4450-890d-aa834db2a958&amp;t=8291a846-130c-4450-890d-aa834db2a958&amp;width=707.998046875&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-276777fe6e6c4b7ea71e8b546e7883a2"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8af993cadd2e460395afcd1f1b6cb647" data-id="8af993cadd2e460395afcd1f1b6cb647"><span><div id="8af993cadd2e460395afcd1f1b6cb647" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8af993cadd2e460395afcd1f1b6cb647" title="未来的增强功能"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">未来的增强功能</span></span></h3><div class="notion-text notion-block-b3120c358e57465d9e5252375b94a547">我们已经达到了本文的目标，但您的旅程不应该就此停止。我建议进一步增强该项目以继续实践TDD。以下是您可以进行的一些增强功能：</div><ul class="notion-list notion-list-disc notion-block-3db04efc80b54c4a9703f2d389f6dd66"><li><b>高级验证：</b>对用户名和密码进行更复杂的验证规则，例如密码强度检测和邮件格式验证</li></ul><ul class="notion-list notion-list-disc notion-block-cffe8c85158445b481f87d6fbe3b5ac4"><li><b>代码覆盖率分析：</b>将代码覆盖率工具添加到应用程序中，这将提供对单元测试代码覆盖率百分比的深入了解，并帮助您识别为经过测试的代码行和功能</li></ul><ul class="notion-list notion-list-disc notion-block-fe592cae2dc94f4b868a235cfa0e5dbf"><li>持续集成CI：设置CI管道，以便在将代码更改推送到仓库时自动运行测试并生成覆盖率报告</li></ul><div class="notion-blank notion-block-8dfbd59a8d1b4617b994628dd52040bb"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-e5a7f52ccd124d2eb4a5b4d6f8fb7500" data-id="e5a7f52ccd124d2eb4a5b4d6f8fb7500"><span><div id="e5a7f52ccd124d2eb4a5b4d6f8fb7500" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e5a7f52ccd124d2eb4a5b4d6f8fb7500" title="结论"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">结论</span></span></h3><div class="notion-text notion-block-8dbfe756a41e450ebc329d624ad8c62b">在本指南中，我们逐步了解了如何通过测试驱动开发TDD来构建React登录页面，通过测试开始并通过红色绿色重构循环，我们创建了一个可靠的、经过充分测试的组件。TDD可能需要一些时间来适应，但在质量和可维护性方面的影响时巨大的。拥抱TDD将是您更有信心的处理复杂的项目。</div><hr class="notion-hr notion-block-3bd3f070629b4b2c936fa7732fd69fac"/><div class="notion-blank notion-block-c36188b60fc944298223cf9030631cdf"> </div><div class="notion-blank notion-block-8b755f1cdd6141d3870c2f52f2896e44"> </div><blockquote class="notion-quote notion-block-bdec8735439949eb9d46d2ece93a4e9b"><div>原文链接</div></blockquote><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-f624bc8724804327bdeebf466f430c1d" href="https://dzone.com/articles/the-definitive-guide-to-tdd-in-react-writing-tests"><div><div class="notion-bookmark-title">The Definitive Guide to TDD in React - DZone</div><div class="notion-bookmark-description">Learn how to build robust React components using Test-Driven Development (TDD). This step-by-step guide ensures your code is reliable and maintainable.</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fdz2cdn1.dzone.com%2Fthemes%2Fdz20%2Fimages%2Ffavicon.png?table=block&amp;id=f624bc87-2480-4327-bdee-bf466f430c1d&amp;t=f624bc87-2480-4327-bdee-bf466f430c1d" alt="The Definitive Guide to TDD in React - DZone" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://dzone.com/articles/the-definitive-guide-to-tdd-in-react-writing-tests</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fdz2cdn1.dzone.com%2Fstorage%2Farticle-thumb%2F17744535-thumb.jpg?table=block&amp;id=f624bc87-2480-4327-bdee-bf466f430c1d&amp;t=f624bc87-2480-4327-bdee-bf466f430c1d" alt="The Definitive Guide to TDD in React - DZone" loading="lazy" decoding="async"/></div></a></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[前端技术脑图]]></title>
            <link>https://gdyg.blog/article/front-end-tech</link>
            <guid>https://gdyg.blog/article/front-end-tech</guid>
            <pubDate>Mon, 29 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[前端需要掌握的技术汇总]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-40673c6dd85f4064bf7c5e985fdec15b"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f74eb84cd89b473aa511343530192e79"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2F0efd958e-8b17-4dba-bbb2-7e98050f15cb%2FFront-End_Knowledge.jpg%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=f74eb84c-d89b-473a-a511-343530192e79&amp;t=f74eb84c-d89b-473a-a511-343530192e79&amp;width=680&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-36bc6d6ac00e4216a5554e7088b5f351"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[微服务是你正确的选择吗]]></title>
            <link>https://gdyg.blog/article/micro-services</link>
            <guid>https://gdyg.blog/article/micro-services</guid>
            <pubDate>Mon, 09 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[微服务架构]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-11110aaf4325403ca4a116ed77254198"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-345121ab0dcd4dc6b286ec86ad292120">微服务已经成员一种变革性的架构风格, 本文旨在全面了解微服务、它们的优势以及它们何时成为你正确的选择。</div><div class="notion-blank notion-block-db3795d4f3f74ec0b890749dccd62e84"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c2541ab63d8f491585443d46560b34ee"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:439px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2F5bd661e5-1c1c-44ed-9f90-2320a6526555%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=c2541ab6-3d8f-4915-8544-3d46560b34ee&amp;t=c2541ab6-3d8f-4915-8544-3d46560b34ee&amp;width=439&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-c05f8165f5a64dd8be55cf20e879829f" data-id="c05f8165f5a64dd8be55cf20e879829f"><span><div id="c05f8165f5a64dd8be55cf20e879829f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c05f8165f5a64dd8be55cf20e879829f" title="微服务的基础知识"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">微服务的基础知识</span></span></h3><div class="notion-text notion-block-86f65e2ab26c478a995b1622a496f8d3">微服务的核心是一种小型独立服务，具有明确定义的目标，这些服务共同构成了一个完整的生态系统，共同实现更大的目标，同时保持自主性，微服务的独立性使其能够独立开发、部署和扩展。</div><div class="notion-blank notion-block-8ba82c2241a54cd7ae00c434fbc0ddfd"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4c53a2e12016420db4bd6b9fb0ce7923" data-id="4c53a2e12016420db4bd6b9fb0ce7923"><span><div id="4c53a2e12016420db4bd6b9fb0ce7923" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4c53a2e12016420db4bd6b9fb0ce7923" title="微服务与整体式（Microservices vs Monolishs）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">微服务与整体式（Microservices vs Monolishs）</span></span></h3><div class="notion-text notion-block-102394b3cfbd495d877f68c8c68eb6ae">微服务和整体式架构的争论仍在进行中，了解它们的差异性至关重要。</div><ul class="notion-list notion-list-disc notion-block-5072633341f2409299fb77130d274746"><li><b>分离的上下文：</b>微服务是围绕特定的业务功能设计的，允许更集中和模块化的开发。相比之下，单体应用将整个内容捆绑到单个仓库下。</li></ul><ul class="notion-list notion-list-disc notion-block-4ef59762e6ac4c4ea4ea739f68047f3c"><li><b>技术灵活性：</b>每个微服务都可以选择最适合其用途的技术栈，这与单体式应用不同，单体式应用通常局限于单个技术栈，</li></ul><ul class="notion-list notion-list-disc notion-block-46ac6617903f4cfb8da51dc23c22effd"><li><b>风险管理：</b>部署微服务的风险可能较低，因为对一项微服务的更改不会影响到其他的服务。但是整体式应用的一个小更改可能会影响到整体系统。</li></ul><ul class="notion-list notion-list-disc notion-block-8bd7bd4152604a0386f8cfc6b14a5ae6"><li><b>团队组织：</b>微服务可以使团队围绕单个服务进行组织，从而促进所有权和问责制。整体式应用通常需要查看复杂的的代码仓库，这使得分离职责变得困难。</li></ul><ul class="notion-list notion-list-disc notion-block-48cc2b4968d5442e840f37366242fd36"><li><b>初始复杂性：</b>由于需要明确的边界和基础设施来实现服务间通信，因此微服务开始也许会很复杂，另一方面，整体式应用可能更容易启动，丹随着它们的增长可能会变得笨拙。</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-92606fa78c154f4393a54d5fa23f1c49"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:490.99609375px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3c763560-295d-452a-8ba9-8e985346dee5%2F9ecacf62-d605-4403-8ee2-1b2d81b8d835%2Fimage.png%3FspaceId%3D3c763560-295d-452a-8ba9-8e985346dee5?table=block&amp;id=92606fa7-8c15-4f43-93a5-4d5fa23f1c49&amp;t=92606fa7-8c15-4f43-93a5-4d5fa23f1c49&amp;width=490.99609375&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8d5bf8790fbb4529bf738f61013a22f2" data-id="8d5bf8790fbb4529bf738f61013a22f2"><span><div id="8d5bf8790fbb4529bf738f61013a22f2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8d5bf8790fbb4529bf738f61013a22f2" title="何时使用微服务架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">何时使用微服务架构</span></span></h3><div class="notion-text notion-block-f6208a3bc4e948e682e9fec9374dfffb"><b>微服务在以下情况下适合使用：</b></div><ul class="notion-list notion-list-disc notion-block-33d466057a1f4d0da28e83cdfb71beca"><li><b>扩展团队：</b>当多个团队需要同时处理系统的不同部分时</li></ul><ul class="notion-list notion-list-disc notion-block-5172ccc246c84bcbb60bd38697f5ec85"><li><b>明确定义的上下文：</b>当业务区域或上下文被明确划分时</li></ul><ul class="notion-list notion-list-disc notion-block-cbb7d2dce2cd440291e54dc4a39fc693"><li><b>成熟的交付流程：</b>具有已建立CI/CD的管道和测试框架的组织</li></ul><ul class="notion-list notion-list-disc notion-block-d3e7c9a0df0c493c85bce0ca288ccb50"><li><b>技术成熟度：</b>具有管理分布式系统复杂性的专业知识的团队</li></ul><ul class="notion-list notion-list-disc notion-block-79265039e7e740d3895aa43381610a6e"><li><b>选择可扩展性：</b>当只有系统的部分需要扩展时</li></ul><ul class="notion-list notion-list-disc notion-block-66e346d307e8454db1a9e20483e15f00"><li><b>技术多样性：</b>当系统的各个地方需要不同的技术来实现最佳的性能时</li></ul><div class="notion-blank notion-block-de12f25c6cba4be88a4d26d05a20d4c3"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-f7d6358f65c84ba0ae115a31207965b5" data-id="f7d6358f65c84ba0ae115a31207965b5"><span><div id="f7d6358f65c84ba0ae115a31207965b5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f7d6358f65c84ba0ae115a31207965b5" title="何时使用整体式架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">何时使用整体式架构</span></span></h3><div class="notion-text notion-block-03b00698d3604f83a320410ef85bedf0"><b>某些情况下，整体式架构仍然具有相关性和优势：</b></div><ul class="notion-list notion-list-disc notion-block-17cf1e9cc19f4f5e8e77d13c2808bc05"><li><b>概念验证（POC）：</b>快速迭代和验证，无需多个服务的开销</li></ul><ul class="notion-list notion-list-disc notion-block-485bd04445f34f419ef876a768f72bde"><li><b>新项目：</b>当域不完全了解并且预期内会发生快速变化时</li></ul><ul class="notion-list notion-list-disc notion-block-a8dcc9bfdfc04e37ad55f49a049890a5"><li><b>简化治理：</b>更易于管理和实现技术和实践的一致性</li></ul><ul class="notion-list notion-list-disc notion-block-58b43c806c294d63ad0b9154c6c5728f"><li><b>易于招聘和培训：</b>使用统一的代码库可以让开发人员更快的上手项目</li></ul><ul class="notion-list notion-list-disc notion-block-3f17cdef64d74570b7f6286561caca60"><li><b>共享库：</b>更轻松的在单个代码库中共享和维护公共库</li></ul><div class="notion-blank notion-block-55a22096a68741f19cac38bf7be3f187"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-901ca94b568c4ce3a4ad441f0a159233" data-id="901ca94b568c4ce3a4ad441f0a159233"><span><div id="901ca94b568c4ce3a4ad441f0a159233" class="notion-header-anchor"></div><a class="notion-hash-link" href="#901ca94b568c4ce3a4ad441f0a159233" title="从整体式架构迁移到微服务架构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">从整体式架构迁移到微服务架构</span></span></h3><div class="notion-text notion-block-b94244ed5b87412883c68d153aff3461"><b>从整体式架构过度到微服务架构需要仔细规划：</b></div><ul class="notion-list notion-list-disc notion-block-f8059a44dcb04de6b2e7618bc036ef1d"><li><b>分离式上下文（DDD）：</b>使用域驱动设计来识别和分离上下文</li></ul><ul class="notion-list notion-list-disc notion-block-5a257e7b72c9404d87060aa6517aded5"><li><b>避免过大力度：</b>确保服务足够大，可以独立管理，但不要太精细</li></ul><ul class="notion-list notion-list-disc notion-block-b82a089c39dd4c29aac96bbc7ff379e9"><li><b>依赖项管理：</b>避免创建服务之间紧密耦合的分布式单体应用</li></ul><ul class="notion-list notion-list-disc notion-block-934ee976418847679c836994cca3f7aa"><li><b>数据库迁移：</b>规划数据库如何迁移并确保数据的一致性和完整性</li></ul><ul class="notion-list notion-list-disc notion-block-64d87337c1bd42dba842cecfcb268863"><li><b>使用事件：</b>使用事件驱动架构来实现更好的解藕</li></ul><ul class="notion-list notion-list-disc notion-block-c8011b039ca04a2cb2071244b8b50853"><li><b>数据复制：</b>必要时不要回避复制数据</li></ul><ul class="notion-list notion-list-disc notion-block-6dd64402da91434e8e2c00a2db7603bd"><li><b>最终一致性：</b>接收最终一致性而不是立即一致性</li></ul><ul class="notion-list notion-list-disc notion-block-7e3646f40dd54a7a8de53de922d1c1d3"><li><b>成熟的CI/CD：</b>确保强大的CI/CD、测试和环境管理</li></ul><ul class="notion-list notion-list-disc notion-block-68f6a05ed37c43bc9fd6146f97e280a5"><li><b>从小处入手：</b>使用Strangler模式从不太重要的域开始，逐步替换整体式架构的某些部分</li></ul><div class="notion-blank notion-block-553468a63aad4152a69af51325f3e03e"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-0ea6540ac6d94cc593beb8181bbb38ab" data-id="0ea6540ac6d94cc593beb8181bbb38ab"><span><div id="0ea6540ac6d94cc593beb8181bbb38ab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0ea6540ac6d94cc593beb8181bbb38ab" title="微服务的特征"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">微服务的特征</span></span></h3><div class="notion-text notion-block-ac7888a587a94b1794807cb060acf438"><b>成功的微服务具备以下几种特征：</b></div><ul class="notion-list notion-list-disc notion-block-776027ea1b644906b3e7092428662332"><li><b>通过服务进行组件化：</b>每个服务都是一个负责特定功能的组件</li></ul><ul class="notion-list notion-list-disc notion-block-3900b77ffc2346e7a62246e9250a4578"><li><b>业务一致：</b>服务围绕业务功能进行组织，并由跨职能团队进行管理</li></ul><ul class="notion-list notion-list-disc notion-block-7ac7b029c94c40e4ad0356a51ebcbc73"><li><b>产品心态：</b>将每一项服务都视为一个产品，注重之后的迭代和持续改进</li></ul><ul class="notion-list notion-list-disc notion-block-f866400d60f84b14a399c933c6d01303"><li><b>智能端点，哑管道（Smart Endpoints, Dumb Pipes）：</b>服务通过简单的直接消息进行通信，无需中介</li></ul><ul class="notion-list notion-list-disc notion-block-81b59c2ccc38437a8fc8b768b9d1763b"><li><b>去中心化治理：</b>团队选择最好的技术并建立明确的通信制度</li></ul><ul class="notion-list notion-list-disc notion-block-24fc6453cd3e414fa00efc4d1045837a"><li><b>分散式数据管理：</b>允许多个数据库，并仔细管理数据重复</li></ul><ul class="notion-list notion-list-disc notion-block-e8d299a9727c46e696a520953db94ff3"><li><b>基础设施自动化：</b>自动化基础设施以处理分布式服务的复杂性</li></ul><ul class="notion-list notion-list-disc notion-block-1779856f062c4e7cbe0f0a334c62e3f9"><li><b>为故障而设计：</b>构建能够优雅处理故障的弹性系统</li></ul><ul class="notion-list notion-list-disc notion-block-1154b28081544e61bfbe36917ec4f868"><li><b>进化设计：</b>设计服务可进行独立的更换和升级</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-73f331ff896c4816bf4709bc869ea905" data-id="73f331ff896c4816bf4709bc869ea905"><span><div id="73f331ff896c4816bf4709bc869ea905" class="notion-header-anchor"></div><a class="notion-hash-link" href="#73f331ff896c4816bf4709bc869ea905" title="结论"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">结论</span></span></h3><div class="notion-text notion-block-73b1e46baa8a4ed4a15eea5ee34e5c5b">微服务架构提供了一种强大的方法来构建可扩展可维护的系统，特别是对于复杂不断变更的业务需求，但是，它们也带来的复杂性，需要技术成熟度和仔细规划，了解何时如何使用微服务而不是整体式架构可以对您的项目成功产生重大的影响</div><div class="notion-blank notion-block-6782014dd7ef4f818d3274aa4bcaf0ae"> </div><hr class="notion-hr notion-block-f17b513d78ce4b0ba04e702953ae919f"/><blockquote class="notion-quote notion-block-5ffd8341b67e4fe193c457ced90d2974"><div>原文链接</div></blockquote><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-96cce2f980214bca9251e7d63f8b9fc3" href="https://dev.to/v1eira/are-microservices-the-right-choice-for-you-3l6j"><div><div class="notion-bookmark-title">Are Microservices the Right Choice for You?</div><div class="notion-bookmark-description">Microservices have emerged as a transformative architectural style. As I delve deeper into software...</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fmedia.dev.to%2Fcdn-cgi%2Fimage%2Fwidth%3D192%2Cheight%3D%2Cfit%3Dscale-down%2Cgravity%3Dauto%2Cformat%3Dauto%2Fhttps%253A%252F%252Fdev-to-uploads.s3.amazonaws.com%252Fuploads%252Farticles%252F8j7kvp660rqzt99zui8e.png?table=block&amp;id=96cce2f9-8021-4bca-9251-e7d63f8b9fc3&amp;t=96cce2f9-8021-4bca-9251-e7d63f8b9fc3&amp;width=800&amp;cache=v2" alt="Are Microservices the Right Choice for You?" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://dev.to/v1eira/are-microservices-the-right-choice-for-you-3l6j</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fmedia.dev.to%2Fcdn-cgi%2Fimage%2Fwidth%3D1000%2Cheight%3D500%2Cfit%3Dcover%2Cgravity%3Dauto%2Cformat%3Dauto%2Fhttps%253A%252F%252Fdev-to-uploads.s3.amazonaws.com%252Fuploads%252Farticles%252Fynf2rrejyvfaqfwly96n.png?table=block&amp;id=96cce2f9-8021-4bca-9251-e7d63f8b9fc3&amp;t=96cce2f9-8021-4bca-9251-e7d63f8b9fc3&amp;width=800&amp;cache=v2" alt="Are Microservices the Right Choice for You?" loading="lazy" decoding="async"/></div></a></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React 19 RC更新指南]]></title>
            <link>https://gdyg.blog/article/react-19-rc</link>
            <guid>https://gdyg.blog/article/react-19-rc</guid>
            <pubDate>Tue, 13 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[react-19]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-0106f0ef167a411b9d77fd13fadc383f"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-4980ab4fe0874acfac95bc6896458350" data-id="4980ab4fe0874acfac95bc6896458350"><span><div id="4980ab4fe0874acfac95bc6896458350" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4980ab4fe0874acfac95bc6896458350" title="📝 React 19更新特性："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝 <b>React 19更新特性：</b></span></span></h2><hr class="notion-hr notion-block-34f5db1857cd421cadef0c1079b5aad7"/><ul class="notion-list notion-list-disc notion-block-05171f3790a34d628834194dafe25e9b"><li><b>删除已经弃用的API,  </b><code class="notion-inline-code"><b>propTypes</b></code><b> 和 </b><code class="notion-inline-code"><b>defaultProps</b></code></li><ul class="notion-list notion-list-disc notion-block-05171f3790a34d628834194dafe25e9b"><li>自行选择迁移到TypeScript或者其他类型检查工具</li><li>类组件将继续支持 <code class="notion-inline-code">defaultProps</code>，因为没有 ES6 替代方案。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-1efa475a0fe04d3b8acffcc02326dcf6"><li><b>删除了refs字符串引用</b></li><ul class="notion-list notion-list-disc notion-block-1efa475a0fe04d3b8acffcc02326dcf6"></ul></ul><ul class="notion-list notion-list-disc notion-block-b1e5db4e135c47cabeb4c43c7cdfcf93"><li><b>删除了模块模式工厂</b></li><ul class="notion-list notion-list-disc notion-block-b1e5db4e135c47cabeb4c43c7cdfcf93"><li>这种模式很少使用，支持它会导致 React 比必要的稍大和慢。在 React 19 中，我们将删除对模块模式工厂的支持，您需要迁移到常规函数：</li></ul></ul><ul class="notion-list notion-list-disc notion-block-2c757e5e07ad4352bb25c2a7ef317c6a"><li><b>删除了</b><code class="notion-inline-code"><b>React.createFactory</b></code></li><ul class="notion-list notion-list-disc notion-block-2c757e5e07ad4352bb25c2a7ef317c6a"><li>在 JSX 得到广泛支持之前，使用 <code class="notion-inline-code">createFactory</code> 很常见，但现在很少使用，可以用 JSX 替换。在 React 19 中，我们将删除 <code class="notion-inline-code">createFactory</code>，您需要迁移到 JSX：</li></ul></ul><ul class="notion-list notion-list-disc notion-block-a1be4609f9a041f9b233ebd1e8feb769"><li><b>Actions</b></li><ul class="notion-list notion-list-disc notion-block-a1be4609f9a041f9b233ebd1e8feb769"><li>React 应用程序中的一个常见用例是执行数据突变，然后更新状态作为响应。例如，当用户提交表单以更改其姓名时，您将发出 API 请求，然后处理响应。过去，您需要手动处理挂起状态、错误、乐观更新和顺序请求。</li><li>在 React 19 中，我们添加了对在转换中使用异步函数的支持，以自动处理挂起状态、错误、表单和乐观更新。</li><li>例如，您可以使用<code class="notion-inline-code">useTransition</code>来为您处理挂起状态：</li><li>异步转换将立即将<code class="notion-inline-code">isPending</code>状态设置为 true，发出异步请求，并在任何转换后将<code class="notion-inline-code">isPending</code>切换为 false。这使您可以在数据更改时保持当前 UI 的响应能力和交互性。</li><li>React 19 构建在 Actions 之上，引入了<code class="notion-inline-code"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://react.dev/blog/2024/04/25/react-19#new-hook-optimistic-updates">useOptimistic</a></code>来管理乐观更新，并引入了一个新的钩子<code class="notion-inline-code"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://react.dev/blog/2024/04/25/react-19#new-hook-useactionstate">React.useActionState</a></code>来处理 Actions 的常见情况。在<code class="notion-inline-code">react-dom</code>中，我们添加<code class="notion-inline-code"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://react.dev/blog/2024/04/25/react-19#form-actions">&lt;form&gt;</a></code><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://react.dev/blog/2024/04/25/react-19#form-actions">操作</a>来自动管理表单，并<code class="notion-inline-code"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://react.dev/blog/2024/04/25/react-19#new-hook-useformstatus">useFormStatus</a></code>来支持表单中操作的常见情况。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-28ca67735f6e4aab9bbb46202ec2b224"><li><b>新hooks: </b><code class="notion-inline-code"><b>useActionState</b></code><b> ，删除了</b><span class="notion-red"><b>useFromState</b></span><b> hooks</b></li><ul class="notion-list notion-list-disc notion-block-28ca67735f6e4aab9bbb46202ec2b224"><li><code class="notion-inline-code">useActionState</code>接受一个函数（“Action”），并返回一个包装的 Action 来调用。这是有效的，因为动作是组合的。当调用包装的 Action 时， <code class="notion-inline-code">useActionState</code>将返回 Action 的最后结果作为<code class="notion-inline-code">data</code> ，并将 Action 的挂起状态返回为<code class="notion-inline-code">pending</code></li><li>Actions 还与 React 19 的<code class="notion-inline-code">react-dom</code>的新<code class="notion-inline-code">&lt;form&gt;</code>功能集成。我们添加了对传递函数作为<code class="notion-inline-code">&lt;form&gt;</code> 、 <code class="notion-inline-code">&lt;input&gt;</code>和<code class="notion-inline-code">&lt;button&gt;</code>元素的<code class="notion-inline-code">action</code>和<code class="notion-inline-code">formAction</code>属性的支持，以自动提交带有 Actions 的表单：</li><li>当<code class="notion-inline-code">&lt;form&gt;</code>操作成功时，React 将自动重置不受控制组件的表单。如果需要手动重置<code class="notion-inline-code">&lt;form&gt;</code> ，可以调用新的<code class="notion-inline-code">requestFormReset</code> React DOM API。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-441e63179fa14356b49c0d73fc169dd6"><li>新hooks: <code class="notion-inline-code"><b>useFormStatus</b></code></li><ul class="notion-list notion-list-disc notion-block-441e63179fa14356b49c0d73fc169dd6"><li>在设计系统中，通常会编写需要访问其所在<code class="notion-inline-code">&lt;form&gt;</code>信息的设计组件，而无需将 props 深入到组件。这可以通过 Context 来完成，但为了使常见情况更容易，我们添加了一个新的钩子<code class="notion-inline-code">useFormStatus</code> ：</li><li><code class="notion-inline-code">useFormStatus</code>读取父级<code class="notion-inline-code">&lt;form&gt;</code>的状态，就好像该表单是上下文提供程序一样。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-c0531a8590e04126875e59dbb6f1cd82"><li>新hooks: <code class="notion-inline-code"><b>useOptimistic</b></code></li><ul class="notion-list notion-list-disc notion-block-c0531a8590e04126875e59dbb6f1cd82"><li>执行数据突变时的另一种常见 UI 模式是在异步请求正在进行时乐观地显示最终状态。在 React 19 中，我们添加了一个名为<code class="notion-inline-code">useOptimistic</code>的新钩子，以简化此操作：</li><li>当<code class="notion-inline-code">updateName</code>请求正在进行时， <code class="notion-inline-code">useOptimistic</code>钩子将立即渲染<code class="notion-inline-code">optimisticName</code> 。当更新完成或出错时，React 会自动切换回<code class="notion-inline-code">currentName</code>值。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-716939e7677b490bae771899015a20ff"><li>新API: <code class="notion-inline-code">use</code></li><ul class="notion-list notion-list-disc notion-block-716939e7677b490bae771899015a20ff"><li>在 React 19 中，我们引入了一个新的 API 来读取渲染中的资源： <code class="notion-inline-code">use</code> </li><li>例如，您可以<code class="notion-inline-code">use</code>读取 Promise，React 将 Suspend 直到 Promise 解析， 也可以读取Context，简化了Context的操作，同时use可以在if或者循环语句中使用</li></ul></ul><ul class="notion-list notion-list-disc notion-block-4037b5e4cf4247beb276a68ea8dfed3e"><li>简化了<span class="notion-red"><code class="notion-inline-code">Ref</code></span>和<span class="notion-red"><code class="notion-inline-code">Context</code></span></li><ul class="notion-list notion-list-disc notion-block-4037b5e4cf4247beb276a68ea8dfed3e"><li>组件之间传递ref时不再通过forwardRef, 而是将ref作为props值进行传递</li><ul class="notion-list notion-list-disc notion-block-21e2a3463f76471f83aaf839fa98a496"></ul><li>Context包装组件时不再需要使用Provider包装组件, 直接通过Context包装组件即可</li><ul class="notion-list notion-list-disc notion-block-e0d8fe97ffb449e8ba125a4632b486c9"></ul><li>ref支持清理函数</li><ul class="notion-list notion-list-disc notion-block-70f7f17d8a4f4c439214792ac4e98714"></ul><li>当组件卸载时，React 将调用从<code class="notion-inline-code">ref</code>回调返回的清理函数。这适用于 DOM 引用、类组件的引用和<code class="notion-inline-code">useImperativeHandle</code> 。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-7a1648ce3c274b2d9d24f4861236723e"><li><code class="notion-inline-code"><b>useDeferredValue</b></code><b>初始值</b></li><ul class="notion-list notion-list-disc notion-block-7a1648ce3c274b2d9d24f4861236723e"><li>我们为<code class="notion-inline-code">useDeferredValue</code>添加了一个<code class="notion-inline-code">initialValue</code>选项：</li><li>当提供了initialValue时， <code class="notion-inline-code">useDeferredValue</code>会将其作为组件初始渲染的<code class="notion-inline-code">value</code>返回，并使用返回的deferredValue在后台安排重新渲染。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-1ce6878eab51441caa894b11fd0ccab1"><li><b>对文档元数据的支持</b></li><ul class="notion-list notion-list-disc notion-block-1ce6878eab51441caa894b11fd0ccab1"><li>在 HTML 中，文档元数据标记（例如<code class="notion-inline-code">&lt;title&gt;</code> 、 <code class="notion-inline-code">&lt;link&gt;</code>和<code class="notion-inline-code">&lt;meta&gt;</code>被保留放置在文档的<code class="notion-inline-code">&lt;head&gt;</code>部分中。在 React 中，决定哪些元数据适合应用程序的组件可能距离渲染<code class="notion-inline-code">&lt;head&gt;</code>的位置很远，或者 React 根本不渲染<code class="notion-inline-code">&lt;head&gt;</code> 。在过去，这些元素需要手动插入到效果中，或者通过像<code class="notion-inline-code"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/nfl/react-helmet">react-helmet</a></code>这样的库插入，并且在服务器渲染React应用程序时需要仔细处理。</li><li>当 React 渲染此组件时，它将看到<code class="notion-inline-code">&lt;title&gt;</code> <code class="notion-inline-code">&lt;link&gt;</code>和<code class="notion-inline-code">&lt;meta&gt;</code>标记，并自动将它们提升到文档的<code class="notion-inline-code">&lt;head&gt;</code>部分。通过原生支持这些元数据标签，我们能够确保它们与仅限客户端的应用程序、流式 SSR 和服务器组件配合使用。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-1a86ae7fdd1f4b0a869f9c65b7943ecf"><li><b>支持样式表</b></li><ul class="notion-list notion-list-disc notion-block-1a86ae7fdd1f4b0a869f9c65b7943ecf"><li>外部链接的样式表 ( <code class="notion-inline-code">&lt;link rel=&quot;stylesheet&quot; href=&quot;...&quot;&gt;</code> ) 和内联样式表 ( <code class="notion-inline-code">&lt;style&gt;...&lt;/style&gt;</code> )，由于样式的原因，需要在 DOM 中仔细定位优先规则。构建允许组件内可组合性的样式表功能很困难，因此用户通常最终要么加载远离可能依赖于它们的组件的所有样式，要么使用封装这种复杂性的样式库。</li><li>在 React 19 中，我们正在解决这种复杂性，并提供对客户端并发渲染和服务器上流式渲染的更深入集成，并内置对样式表的支持。如果你告诉 React 样式表的<code class="notion-inline-code">precedence</code> ，它将管理 DOM 中样式表的插入顺序，并确保在显示依赖于这些样式规则的内容之前加载样式表（如果是外部的）。</li><li>在服务器端渲染期间，React 将在<code class="notion-inline-code">&lt;head&gt;</code>中包含样式表，这确保浏览器在加载之前不会绘制。如果样式表是在我们开始流式传输之后才发现的，React 将确保在显示依赖于该样式表的 Suspense 边界的内容之前将样式表插入到客户端上的<code class="notion-inline-code">&lt;head&gt;</code>中。</li><li>在客户端渲染期间，React 将等待新渲染的样式表加载，然后再提交渲染。如果您从应用程序中的多个位置渲染此组件，React 将仅在文档中包含一次样式表：</li><li>对于习惯于手动加载样式表的用户来说，这是一个将这些样式表与依赖于它们的组件一起定位的机会，从而可以更好地进行本地推理，并更轻松地确保您只加载实际依赖的样式表。</li><li>样式库和与捆绑器的样式集成也可以采用此新功能，因此即使您不直接渲染自己的样式表，您仍然可以受益，因为您的工具升级为使用此功能。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-69d7134133114d31b09ece1f279f9f03"><li><b>支持异步脚本</b></li><ul class="notion-list notion-list-disc notion-block-69d7134133114d31b09ece1f279f9f03"><li>在 HTML 中，普通脚本 ( <code class="notion-inline-code">&lt;script src=&quot;...&quot;&gt;</code> ) 和延迟脚本 ( <code class="notion-inline-code">&lt;script defer=&quot;&quot; src=&quot;...&quot;&gt;</code> ) 按文档顺序加载，这使得在深层渲染这些类型的脚本你的组件树具有挑战性。但是，异步脚本 ( <code class="notion-inline-code">&lt;script async=&quot;&quot; src=&quot;...&quot;&gt;</code> ) 将以任意顺序加载。</li><li>在 React 19 中，我们对异步脚本提供了更好的支持，允许您在组件树中的任何位置、实际依赖于脚本的组件内渲染它们，而无需管理重新定位和重复数据删除脚本实例。</li><li>在所有渲染环境中，异步脚本都会被去重，这样即使脚本由多个不同的组件渲染，React 也只会加载并执行一次脚本。</li><li>在服务器端渲染中，异步脚本将包含在<code class="notion-inline-code">&lt;head&gt;</code>中，并优先于阻止绘制的更关键资源（例如样式表、字体和图像预加载）。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-dc8e2067dba94ad48d917c4a167d87cd"><li><b>支持预加载资源</b></li><ul class="notion-list notion-list-disc notion-block-dc8e2067dba94ad48d917c4a167d87cd"><li>在初始文档加载和客户端更新期间，告诉浏览器可能需要尽早加载的资源可能会对页面性能产生巨大影响。</li><li>React 19 包含许多用于加载和预加载浏览器资源的新 API，以便尽可能轻松地构建不受低效资源加载阻碍的出色体验。</li><li>这些 API 可用于通过将字体等其他资源的发现移出样式表加载来优化初始页面加载。他们还可以通过预取预期导航使用的资源列表，然后在单击甚至悬停时急切地预加载这些资源，从而加快客户端更新速度。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-42147cac006246109010f7cf4959dca6"><li><b>与第三方脚本和扩展的兼容性</b></li><ul class="notion-list notion-list-disc notion-block-42147cac006246109010f7cf4959dca6"><li>我们改进了水合作用，以考虑第三方脚本和浏览器扩展。</li><li>水合时，如果客户端渲染的元素与服务器 HTML 中找到的元素不匹配，React 将强制客户端重新渲染以修复内容。以前，如果由第三方脚本或浏览器扩展插入元素，则会触发不匹配错误和客户端渲染。</li><li>在 React 19 中， <code class="notion-inline-code">&lt;head&gt;</code>和<code class="notion-inline-code">&lt;body&gt;</code>中的意外标签将被跳过，避免不匹配错误。如果 React 由于不相关的水合作用不匹配而需要重新渲染整个文档，它将保留由第三方脚本和浏览器扩展插入的样式表。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-00d12578490a4058aff83df5857a40ab"><li><b>更好的错误报告</b></li><ul class="notion-list notion-list-disc notion-block-00d12578490a4058aff83df5857a40ab"><li>我们改进了 React 19 中的错误处理，以消除重复并提供处理捕获和未捕获错误的选项。例如，当渲染中出现错误并被错误边界捕获时，以前的 React 会抛出错误两次（一次是针对原始错误，然后在无法自动恢复后再次抛出），然后调用<code class="notion-inline-code">console.error</code>并提供有关错误位置的信息发生。</li><li>在 React 19 中，我们记录一个错误，其中包含所有错误信息：</li><li>此外，我们添加了两个新的根选项来补充<code class="notion-inline-code">onRecoverableError</code> ：</li><ul class="notion-list notion-list-disc notion-block-108406bc24fd4d6bbf73f03ec96ad437"><li><code class="notion-inline-code">createRoot</code> 和 <code class="notion-inline-code">hydrateRoot</code> 添加了用于自定义错误处理的新方法</li><ul class="notion-list notion-list-disc notion-block-966266d833ba4fb3a2b187dd4076df99"><li>如果没有自定义错误处理的方法，react默认会做出相应的处理方式：</li><ul class="notion-list notion-list-disc notion-block-920d90e6869e43f58947a8b46bda6690"><li><b>未捕获的错误</b>：未被错误边界捕获的错误将报告给 <code class="notion-inline-code">window.reportError</code>。</li><li><b>捕获的错误</b>：由错误边界捕获的错误将报告给 <code class="notion-inline-code">console.error</code>。</li><li><code class="notion-inline-code">onRecoverableError</code> ：抛出错误时调用并自动恢复。</li></ul></ul></ul></ul></ul><ul class="notion-list notion-list-disc notion-block-a796a0913cf743929471f15c7cbc5b74"><li><b>反应服务器组件(RSC)</b></li><ul class="notion-list notion-list-disc notion-block-a796a0913cf743929471f15c7cbc5b74"><li>服务器组件是一个新选项，允许在捆绑之前在与客户端应用程序或 SSR 服务器分开的环境中提前渲染组件。这个单独的环境是 React Server Components 中的“服务器”。服务器组件可以在构建时在 CI 服务器上运行一次，也可以使用 Web 服务器针对每个请求运行。</li><li>服务器操作允许客户端组件调用在服务器上执行的异步函数。</li><li>服务器操作可以在服务器组件中创建并作为属性传递给客户端组件，也可以在客户端组件中导入和使用。</li></ul></ul><div class="notion-blank notion-block-0955a3983c0f42aabbfdf76278d0b074"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS 伪类和伪元素]]></title>
            <link>https://gdyg.blog/article/css-class</link>
            <guid>https://gdyg.blog/article/css-class</guid>
            <pubDate>Wed, 25 Apr 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[CSS 伪类和伪元素]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-586be17effc14734b221719d1d9ac96c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-20fed13e77bb4684a868a4198bd7cad5" data-id="20fed13e77bb4684a868a4198bd7cad5"><span><div id="20fed13e77bb4684a868a4198bd7cad5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20fed13e77bb4684a868a4198bd7cad5" title="📝 介绍"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝 介绍</span></span></h2><hr class="notion-hr notion-block-847d7dfecf4c49f68bfe2af4b89596e2"/><div class="notion-text notion-block-38ebc71b59c048c5a13aacccd4c826d5">伪元素（Pseudo-elements）和伪类（Pseudo-classes）是 CSS 中的两个重要概念，用于向文档中的元素添加特定的样式或效果，而无需修改 HTML 结构。它们允许开发者选择文档中某些特定的状态或位置，并对其应用样式。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c2390bf28a8d49ff93884e876fb959c1" data-id="c2390bf28a8d49ff93884e876fb959c1"><span><div id="c2390bf28a8d49ff93884e876fb959c1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c2390bf28a8d49ff93884e876fb959c1" title="1. 伪元素（Pseudo-elements）："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 伪元素（Pseudo-elements）：</span></span></h4><div class="notion-text notion-block-200930a00aa5455d8e728a6b09aa6fb0">伪元素允许开发者在元素的内容之前或之后插入虚拟的元素，并为其应用样式。伪元素以双冒号<code class="notion-inline-code">::</code>开头，常见的伪元素包括<code class="notion-inline-code">::before</code>和<code class="notion-inline-code">::after</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-04ca8a091ecc4a83bb4695a54161531d" data-id="04ca8a091ecc4a83bb4695a54161531d"><span><div id="04ca8a091ecc4a83bb4695a54161531d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#04ca8a091ecc4a83bb4695a54161531d" title="2. 伪类（Pseudo-classes）："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 伪类（Pseudo-classes）：</span></span></h4><div class="notion-text notion-block-da7b70fd94694a2b8e550ac6454fde83">伪类允许开发者选择元素的特定状态或位置，并为其应用样式。伪类以冒号<code class="notion-inline-code">:</code>开头，常见的伪类包括<code class="notion-inline-code">:hover</code>（悬停状态）、<code class="notion-inline-code">:active</code>（活动状态）、<code class="notion-inline-code">:focus</code>（聚焦状态）、<code class="notion-inline-code">:first-child</code>（第一个子元素）等。</div><hr class="notion-hr notion-block-78ed174cd50e4de0ad15f5c3c390f2ff"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-d6ebc8f266484e279d5a88ed2b8bd1fc" data-id="d6ebc8f266484e279d5a88ed2b8bd1fc"><span><div id="d6ebc8f266484e279d5a88ed2b8bd1fc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d6ebc8f266484e279d5a88ed2b8bd1fc" title="🤗 总结归纳"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🤗 总结归纳</span></span></h2><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-59a4dbc5b807426583b53b00dab8bfe6" data-id="59a4dbc5b807426583b53b00dab8bfe6"><span><div id="59a4dbc5b807426583b53b00dab8bfe6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#59a4dbc5b807426583b53b00dab8bfe6" title="区别："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">区别：</span></span></h4><ul class="notion-list notion-list-disc notion-block-295577506a314a77ace664898341c454"><li><b>伪元素</b>是在元素的内容之前或之后插入的虚拟元素，可用于创建一些额外的装饰或图标等。</li></ul><ul class="notion-list notion-list-disc notion-block-4400097236594b4987ab41cf72d0994c"><li><b>伪类</b>是根据元素的特定状态或位置选择元素，并为其应用样式，常用于响应用户的操作或页面结构的特定位置。</li></ul><div class="notion-text notion-block-2d456a6d69ae40b9a78ade5343bbbe80">总的来说，伪元素和伪类都是在不修改 HTML 结构的情况下为元素添加样式的强大工具，能够实现丰富的效果和交互体验。深入理解和熟练运用伪元素和伪类可以提高 CSS 的灵活性和可维护性。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-f009d278e2d043cf84272737e9b8b944" data-id="f009d278e2d043cf84272737e9b8b944"><span><div id="f009d278e2d043cf84272737e9b8b944" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f009d278e2d043cf84272737e9b8b944" title="📎 参考文章"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📎 参考文章</span></span></h2><hr class="notion-hr notion-block-5a648483647e41959bd8911c20379d4f"/><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-f5308b3fc17149f2a625718fb2faeb48" href="https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements"><div><div class="notion-bookmark-title">伪类和伪元素 - 学习 Web 开发 | MDN</div><div class="notion-bookmark-description">下一组我们将了解的选择器被称为伪类和伪元素。这一类选择器的数量众多，通常用于很明确的目的。一旦你了解了如何使用它们，你便可以通过查阅列表来寻找合适的那一项以完成你想要的选择。与之前一样，每个选择器相关的 MDN 页面都将帮助你了解各浏览器的支持情况。</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fdeveloper.mozilla.org%2Ffavicon-48x48.cbbd161b.png?table=block&amp;id=f5308b3f-c171-49f2-a625-718fb2faeb48&amp;t=f5308b3f-c171-49f2-a625-718fb2faeb48" alt="伪类和伪元素 - 学习 Web 开发 | MDN" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fdeveloper.mozilla.org%2Fmdn-social-share.cd6c4a5a.png?table=block&amp;id=f5308b3f-c171-49f2-a625-718fb2faeb48&amp;t=f5308b3f-c171-49f2-a625-718fb2faeb48" alt="伪类和伪元素 - 学习 Web 开发 | MDN" loading="lazy" decoding="async"/></div></a></div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>