ZiuChen.github.io/article/从0实现一个年度报告.html

200 lines
112 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>从0实现一个年度报告 | ZiuChen</title>
<meta name="description" content="Unlimited Progress.">
<link rel="preload stylesheet" href="/assets/style.01b731bf.css" as="style">
<script type="module" src="/assets/app.df344836.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/framework.eaa7ef56.js">
<link rel="modulepreload" href="/assets/chunks/theme.cde553b8.js">
<link rel="modulepreload" href="/assets/article_从0实现一个年度报告.md.91662ae0.lean.js">
<link rel="icon" href="/logo.png">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-c9141815><!--[--><!--]--><!--[--><span tabindex="-1" data-v-f364a430></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-f364a430> Skip to content </a><!--]--><!----><header class="VPNav" data-v-c9141815 data-v-39dca61f><div class="VPNavBar has-sidebar" data-v-39dca61f data-v-016664a6><div class="container" data-v-016664a6><div class="title" data-v-016664a6><div class="VPNavBarTitle has-sidebar" data-v-016664a6 data-v-2825b2da><a class="title" href="/" data-v-2825b2da><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logo.png" alt data-v-f50a87e5><!--]--><!--[-->ZiuChen<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-016664a6><div class="curtain" data-v-016664a6></div><div class="content-body" data-v-016664a6><!--[--><!--]--><div class="VPNavBarSearch search" data-v-016664a6><!--[--><!----><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20" aria-label="search icon"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-016664a6 data-v-e51f2e59><span id="main-nav-aria-label" class="visually-hidden" data-v-e51f2e59>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/" tabindex="0" data-v-e51f2e59 data-v-4a25c51a><!--[--><span data-v-4a25c51a>首页</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-e51f2e59 data-v-e98c12e5><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-e98c12e5><span class="text" data-v-e98c12e5><!----><span data-v-e98c12e5>我的项目</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-e98c12e5><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-e98c12e5><div class="VPMenu" data-v-e98c12e5 data-v-15053f44><div class="items" data-v-15053f44><!--[--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/project/ClipboardManager/" data-v-d62828c4><!--[-->超级剪贴板<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/project/Markdown/" data-v-d62828c4><!--[-->超级Markdown<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/project/JSRunner/" data-v-d62828c4><!--[-->超级JavaScript<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/project/SmartWordBreak/" data-v-d62828c4><!--[-->超级分词<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-e51f2e59 data-v-e98c12e5><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-e98c12e5><span class="text" data-v-e98c12e5><!----><span data-v-e98c12e5>开源作品</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-e98c12e5><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-e98c12e5><div class="VPMenu" data-v-e98c12e5 data-v-15053f44><div class="items" data-v-15053f44><!--[--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/works/opensource.html" data-v-d62828c4><!--[-->个人作品<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/works/contribution.html" data-v-d62828c4><!--[-->社区贡献<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-e51f2e59 data-v-e98c12e5><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-e98c12e5><span class="text" data-v-e98c12e5><!----><span data-v-e98c12e5>学习笔记</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-e98c12e5><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-e98c12e5><div class="VPMenu" data-v-e98c12e5 data-v-15053f44><div class="items" data-v-15053f44><!--[--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/JavaScript.html" data-v-d62828c4><!--[-->JavaScript基础<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/CSS.html" data-v-d62828c4><!--[-->CSS基础<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/JavaScriptEnhanced.html" data-v-d62828c4><!--[-->JavaScript进阶<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/Front-end%20Engineering.html" data-v-d62828c4><!--[-->前端工程化<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/SSR.html" data-v-d62828c4><!--[-->服务端渲染<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/React.html" data-v-d62828c4><!--[-->React基础<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/React%20Hooks.html" data-v-d62828c4><!--[-->React Hooks<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/Redux.html" data-v-d62828c4><!--[-->Redux<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/React%20Router.html" data-v-d62828c4><!--[-->React Router<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-15053f44 data-v-d62828c4><a class="VPLink link" href="/note/MySQL.html" data-v-d62828c4><!--[-->MySQL<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/self/" tabindex="0" data-v-e51f2e59 data-v-4a25c51a><!--[--><span data-v-4a25c51a>个人介绍</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-016664a6 data-v-0e3f34fb><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-0e3f34fb data-v-842ac2d6 data-v-02e88dea><span class="check" data-v-02e88dea><span class="icon" data-v-02e88dea><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-842ac2d6><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-842ac2d6><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-016664a6 data-v-7862e4c4 data-v-25970e8f><!--[--><a class="VPSocialLink no-icon" href="https://github.com/ZiuChen" aria-label="github" target="_blank" rel="noopener" data-v-25970e8f data-v-377059e4><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="https://juejin.cn/user/1887205216238477" aria-label target="_blank" rel="noopener" data-v-25970e8f data-v-377059e4><svg width="36" height="28" viewBox="0 0 36 28" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5875 6.77268L21.8232 3.40505L17.5875 0.00748237L17.5837 0L13.3555 3.39757L17.5837 6.76894L17.5875 6.77268ZM17.5863 17.3955H17.59L28.5161 8.77432L25.5526 6.39453L17.59 12.6808H17.5863L17.5825 12.6845L9.61993 6.40201L6.66016 8.78181L17.5825 17.3992L17.5863 17.3955ZM17.5828 23.2891L17.5865 23.2854L32.2133 11.7456L35.1768 14.1254L28.5238 19.3752L17.5865 28L0.284376 14.3574L0 14.1291L2.95977 11.7531L17.5828 23.2891Z" fill="#1E80FF"/></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-016664a6 data-v-c5775a0c data-v-e98c12e5><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-e98c12e5><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-e98c12e5><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-e98c12e5><div class="VPMenu" data-v-e98c12e5 data-v-15053f44><!----><!--[--><!--[--><!----><div class="group" data-v-c5775a0c><div class="item appearance" data-v-c5775a0c><p class="label" data-v-c5775a0c>Appearance</p><div class="appearance-action" data-v-c5775a0c><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-c5775a0c data-v-842ac2d6 data-v-02e88dea><span class="check" data-v-02e88dea><span class="icon" data-v-02e88dea><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-842ac2d6><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-842ac2d6><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-c5775a0c><div class="item social-links" data-v-c5775a0c><div class="VPSocialLinks social-links-list" data-v-c5775a0c data-v-25970e8f><!--[--><a class="VPSocialLink no-icon" href="https://github.com/ZiuChen" aria-label="github" target="_blank" rel="noopener" data-v-25970e8f data-v-377059e4><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="https://juejin.cn/user/1887205216238477" aria-label target="_blank" rel="noopener" data-v-25970e8f data-v-377059e4><svg width="36" height="28" viewBox="0 0 36 28" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.5875 6.77268L21.8232 3.40505L17.5875 0.00748237L17.5837 0L13.3555 3.39757L17.5837 6.76894L17.5875 6.77268ZM17.5863 17.3955H17.59L28.5161 8.77432L25.5526 6.39453L17.59 12.6808H17.5863L17.5825 12.6845L9.61993 6.40201L6.66016 8.78181L17.5825 17.3992L17.5863 17.3955ZM17.5828 23.2891L17.5865 23.2854L32.2133 11.7456L35.1768 14.1254L28.5238 19.3752L17.5865 28L0.284376 14.3574L0 14.1291L2.95977 11.7531L17.5828 23.2891Z" fill="#1E80FF"/></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-016664a6 data-v-3b176817><span class="container" data-v-3b176817><span class="top" data-v-3b176817></span><span class="middle" data-v-3b176817></span><span class="bottom" data-v-3b176817></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav reached-top" data-v-c9141815 data-v-7b873ae9><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-7b873ae9><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-7b873ae9><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-7b873ae9>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-7b873ae9 data-v-c2e82416><button data-v-c2e82416>Return to top</button><!----></div></div><aside class="VPSidebar" data-v-c9141815 data-v-cadfaea8><div class="curtain" data-v-cadfaea8></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-cadfaea8><span class="visually-hidden" id="sidebar-aria-label" data-v-cadfaea8> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-cadfaea8><section class="VPSidebarItem level-0" data-v-cadfaea8 data-v-d0c47f51><div class="item" role="button" tabindex="0" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><h2 class="text" data-v-d0c47f51>我的项目</h2><!----></div><div class="items" data-v-d0c47f51><!--[--><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/project/ClipboardManager/" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>超级剪贴板</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/project/Markdown/" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>超级Markdown</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/project/JSRunner/" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>超级JavaScript</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/project/SmartWordBreak/" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>超级分词</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cadfaea8><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cadfaea8 data-v-d0c47f51><div class="item" role="button" tabindex="0" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><h2 class="text" data-v-d0c47f51>开源作品</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-d0c47f51><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-d0c47f51><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-d0c47f51><!--[--><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/works/opensource.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>个人作品</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/works/contribution.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>社区贡献</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cadfaea8><section class="VPSidebarItem level-0 collapsible has-active" data-v-cadfaea8 data-v-d0c47f51><div class="item" role="button" tabindex="0" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><h2 class="text" data-v-d0c47f51>文章归档</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-d0c47f51><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-d0c47f51><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-d0c47f51><!--[--><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E3%80%902023%E3%80%91%E9%9D%92%E8%AE%AD%E8%90%A5%20-%20%E5%89%8D%E7%AB%AF%E7%BB%83%E4%B9%A0%E9%A2%98%E6%B1%87%E6%80%BB%E8%A7%A3%E6%9E%90.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>【2023】青训营 - 前端练习题汇总解析</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E3%80%90%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8%E3%80%91%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98%E6%80%BB%E7%BB%93.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>【字节跳动】前端面试题总结</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E3%80%90%E5%BF%AB%E6%89%8B%E3%80%91%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>【快手】深入理解前端面试题</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E3%80%90%E7%94%A8%E5%8F%8B%E9%87%91%E8%9E%8D%E3%80%91%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98%E6%80%BB%E7%BB%93.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>【用友金融】前端面试题总结</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E4%B8%80%E6%96%87%E8%AF%BB%E6%87%82%E4%BA%8B%E4%BB%B6%E5%86%92%E6%B3%A1%E4%B8%8E%E4%BA%8B%E4%BB%B6%E6%8D%95%E8%8E%B7.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>一文读懂事件冒泡与事件捕获</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E4%B8%80%E6%96%87%E8%AF%BB%E6%87%82%E4%BC%AA%E7%B1%BB%E4%B8%8E%E4%BC%AA%E5%85%83%E7%B4%A0.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>一文读懂伪类与伪元素</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E4%B8%80%E6%96%87%E8%AF%BB%E6%87%82%E5%87%BD%E6%95%B0%E4%B8%ADthis%E6%8C%87%E5%90%91%E9%97%AE%E9%A2%98.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>一文读懂函数中this指向问题</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E4%BB%8E0%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E5%B9%B4%E5%BA%A6%E6%8A%A5%E5%91%8A.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>从0实现一个年度报告</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E5%BD%BB%E5%BA%95%E6%90%9E%E6%87%82%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%95%B0%E6%8D%AE%E5%B1%9E%E6%80%A7%E6%8F%8F%E8%BF%B0%E7%AC%A6%E3%80%81%E5%AD%98%E5%82%A8%E5%B1%9E%E6%80%A7%E6%8F%8F%E8%BF%B0%E7%AC%A6.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>彻底搞懂对象的数据属性描述符、存储属性描述符</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E6%B5%85%E6%9E%90defineProperty%E4%B8%8EProxy%E5%AE%9E%E7%8E%B0%E7%9A%84%E5%8F%8C%E5%90%91%E7%BB%91%E5%AE%9A.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>浅析defineProperty与Proxy实现的双向绑定</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E6%B7%B1%E5%85%A5JavaScript%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>深入JavaScript数据类型</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E6%B7%B1%E5%85%A5Vue3%E6%BA%90%E7%A0%81%EF%BC%8C%E7%9C%8B%E7%9C%8BVue.use%E5%90%8E%E7%A9%B6%E7%AB%9F%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88%EF%BC%9F.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>深入Vue3源码看看Vue.use后究竟发生了什么</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Proxy%E4%B8%8EReflect.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>深入理解Proxy与Reflect</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>深入理解浏览器缓存机制</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/article/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%E6%B5%8F%E8%A7%88%E5%99%A8%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>深入理解浏览器运行原理</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cadfaea8><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cadfaea8 data-v-d0c47f51><div class="item" role="button" tabindex="0" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><h2 class="text" data-v-d0c47f51>学习笔记</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-d0c47f51><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-d0c47f51><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-d0c47f51><!--[--><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/JavaScript.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>JavaScript基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/CSS.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>CSS基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/JavaScriptEnhanced.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>JavaScript进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/Front-end%20Engineering.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>前端工程化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/SSR.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>服务端渲染</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/React.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>React基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/React%20Hooks.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>React Hooks</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/Redux.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>Redux</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/React%20Router.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>React Router</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-d0c47f51 data-v-d0c47f51><div class="item" data-v-d0c47f51><div class="indicator" data-v-d0c47f51></div><a class="VPLink link link" href="/note/MySQL.html" data-v-d0c47f51><!--[--><p class="text" data-v-d0c47f51>MySQL</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-c9141815 data-v-a52b0863><div class="VPDoc has-sidebar has-aside" data-v-a52b0863 data-v-4ad9891f><!--[--><!--]--><div class="container" data-v-4ad9891f><div class="aside" data-v-4ad9891f><div class="aside-curtain" data-v-4ad9891f></div><div class="aside-container" data-v-4ad9891f><div class="aside-content" data-v-4ad9891f><div class="VPDocAside" data-v-4ad9891f data-v-00c6d4f2><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" role="navigation" data-v-00c6d4f2 data-v-48e05f7c><div class="content" data-v-48e05f7c><div class="outline-marker" data-v-48e05f7c></div><div class="outline-title" role="heading" aria-level="2" data-v-48e05f7c>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-48e05f7c><span class="visually-hidden" id="doc-outline-aria-label" data-v-48e05f7c> Table of Contents for current page </span><ul class="root" data-v-48e05f7c data-v-1d1e520e><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-00c6d4f2></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-4ad9891f><div class="content-container" data-v-4ad9891f><!--[--><!--]--><!----><main class="main" data-v-4ad9891f><div style="position:relative;" class="vp-doc _article_%E4%BB%8E0%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E5%B9%B4%E5%BA%A6%E6%8A%A5%E5%91%8A" data-v-4ad9891f><div><h1 id="从0实现一个年度报告" tabindex="-1">从0实现一个年度报告 <a class="header-anchor" href="#从0实现一个年度报告" aria-label="Permalink to &quot;从0实现一个年度报告&quot;"></a></h1><p>每到年底各大应用都会推出自己的年终总结报告,统计出用户一年来在应用内的行为展示给用户,供用户记录、分享。</p><p>今年掘金社区推出了自己的<a href="https://zjsms.com/hbdA5jR" target="_blank" rel="noreferrer">2022掘友年度报告</a>这次我们仿照这个报告从0开始自己实现一个年终总结报告页面</p><h2 id="实现难点" tabindex="-1">实现难点 <a class="header-anchor" href="#实现难点" aria-label="Permalink to &quot;实现难点&quot;"></a></h2><h3 id="_1-数据模拟" tabindex="-1">1. 数据模拟 <a class="header-anchor" href="#_1-数据模拟" aria-label="Permalink to &quot;1. 数据模拟&quot;"></a></h3><p>一般情况下是根据用户UID到后端去请求相关接口获得统计数据。</p><p>例如掘金的接口为<code>https://api.juejin.cn/event_api/v1/annual/annual_summary?aid=xxxxxx</code></p><p>本次后端使用<code>NodeJS</code>实现了一个爬虫可以将用户数据统计完成后导出JSON格式的数据将此数据粘贴到前端页面的输入框即可生成自己的报告</p><h3 id="_2-屏幕适配" tabindex="-1">2. 屏幕适配 <a class="header-anchor" href="#_2-屏幕适配" aria-label="Permalink to &quot;2. 屏幕适配&quot;"></a></h3><p>可以观察到在PC端和在手机端访问年度报告展示的效果是不一样的。</p><p>本次考虑使用媒体查询来实现这个功能:</p><ul><li>宽屏则展示背景,页面切换也使用背景中的上下切换按钮</li><li>小屏则隐藏背景,让内容填满屏幕,页面切换通过滑动事件监听</li></ul><h3 id="_3-动画效果" tabindex="-1">3. 动画效果 <a class="header-anchor" href="#_3-动画效果" aria-label="Permalink to &quot;3. 动画效果&quot;"></a></h3><p>动画分为文本与背景元素的动画</p><ul><li>背景元素的动画使用了SVG动画 <ul><li>动画中不动的部分直接使用<code>.png</code>图片</li><li>运动的部分使用SVG动画绘制如克里克的眼睛、尾巴</li></ul></li><li>文本的动画使用了<code>CSS Animation</code>渐显的效果 <ul><li>不同段落之间通过<code>animation-delay</code>属性,彼此相差<code>1000ms</code></li></ul></li></ul><p>背景动画容器的四个位置:<code>左上角</code> <code>右下角</code> <code>中间部分</code> <code>中间(悬浮气泡)</code>。不同位置的动画容器都采用绝对定位<code>position: absolute;</code>,辅以<code>z-index</code>实现层叠</p><p>囿于工期,本次的背景动画直接采用静态图片+<code>CSS Animation</code>实现上下浮动的效果</p><h3 id="_4-音乐播放" tabindex="-1">4. 音乐播放 <a class="header-anchor" href="#_4-音乐播放" aria-label="Permalink to &quot;4. 音乐播放&quot;"></a></h3><p>通过<code>Audio</code>接口访问网络音乐链接,控制音乐相关功能</p><ul><li>进入页面开始播放</li><li>离开页面暂停播放</li><li>支持点击按钮切换播放状态</li></ul><h2 id="用户数据" tabindex="-1">用户数据 <a class="header-anchor" href="#用户数据" aria-label="Permalink to &quot;用户数据&quot;"></a></h2><h3 id="用户数据内容" tabindex="-1">用户数据内容 <a class="header-anchor" href="#用户数据内容" aria-label="Permalink to &quot;用户数据内容&quot;"></a></h3><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">- 用户名</span></span>
<span class="line"><span style="color:#e1e4e8;">- 注册时间 距今天数</span></span>
<span class="line"><span style="color:#e1e4e8;">- 创作相关</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 发布文章数</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 总阅读数 总赞数 总评论数</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 掘力值增长 超过人数百分比</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 最受欢迎的文章标题</span></span>
<span class="line"><span style="color:#e1e4e8;">- 社交相关</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 多少位掘友看过你的文章</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 点赞最多的掘友 评论最多的掘友</span></span>
<span class="line"><span style="color:#e1e4e8;">- 学习相关</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 阅读文章数 点赞数 评论数</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 总阅读字数</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 最关注的技术领域TOP3</span></span>
<span class="line"><span style="color:#e1e4e8;">- 沸点相关</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 发布沸点数 互动掘友数 点赞数 收赞数</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 互动最频繁的掘友</span></span>
<span class="line"><span style="color:#e1e4e8;">- 深夜阅读</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 最晚一次阅读时间</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 阅读的文章标题</span></span>
<span class="line"><span style="color:#e1e4e8;">- 早起阅读</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 最晚一次阅读时间</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 阅读的文章标题</span></span>
<span class="line"><span style="color:#e1e4e8;">- 最终总结</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 用户名</span></span>
<span class="line"><span style="color:#e1e4e8;"> - 获得成就 饼图</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">- 用户名</span></span>
<span class="line"><span style="color:#24292e;">- 注册时间 距今天数</span></span>
<span class="line"><span style="color:#24292e;">- 创作相关</span></span>
<span class="line"><span style="color:#24292e;"> - 发布文章数</span></span>
<span class="line"><span style="color:#24292e;"> - 总阅读数 总赞数 总评论数</span></span>
<span class="line"><span style="color:#24292e;"> - 掘力值增长 超过人数百分比</span></span>
<span class="line"><span style="color:#24292e;"> - 最受欢迎的文章标题</span></span>
<span class="line"><span style="color:#24292e;">- 社交相关</span></span>
<span class="line"><span style="color:#24292e;"> - 多少位掘友看过你的文章</span></span>
<span class="line"><span style="color:#24292e;"> - 点赞最多的掘友 评论最多的掘友</span></span>
<span class="line"><span style="color:#24292e;">- 学习相关</span></span>
<span class="line"><span style="color:#24292e;"> - 阅读文章数 点赞数 评论数</span></span>
<span class="line"><span style="color:#24292e;"> - 总阅读字数</span></span>
<span class="line"><span style="color:#24292e;"> - 最关注的技术领域TOP3</span></span>
<span class="line"><span style="color:#24292e;">- 沸点相关</span></span>
<span class="line"><span style="color:#24292e;"> - 发布沸点数 互动掘友数 点赞数 收赞数</span></span>
<span class="line"><span style="color:#24292e;"> - 互动最频繁的掘友</span></span>
<span class="line"><span style="color:#24292e;">- 深夜阅读</span></span>
<span class="line"><span style="color:#24292e;"> - 最晚一次阅读时间</span></span>
<span class="line"><span style="color:#24292e;"> - 阅读的文章标题</span></span>
<span class="line"><span style="color:#24292e;">- 早起阅读</span></span>
<span class="line"><span style="color:#24292e;"> - 最晚一次阅读时间</span></span>
<span class="line"><span style="color:#24292e;"> - 阅读的文章标题</span></span>
<span class="line"><span style="color:#24292e;">- 最终总结</span></span>
<span class="line"><span style="color:#24292e;"> - 用户名</span></span>
<span class="line"><span style="color:#24292e;"> - 获得成就 饼图</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><h3 id="数据模拟" tabindex="-1">数据模拟 <a class="header-anchor" href="#数据模拟" aria-label="Permalink to &quot;数据模拟&quot;"></a></h3><p>根据不同页面分配不同的字段与数据我根据自己的报告模拟了以下JSON数据</p><div class="language-json vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;">{</span><span style="color:#79B8FF;">&quot;pages&quot;</span><span style="color:#E1E4E8;">:[{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;userName&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;Ziu&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;enterDay&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1647619200000</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;tillNow&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">291</span><span style="color:#E1E4E8;">}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;publishArticle&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">187</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;getReader&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">78959</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;getLike&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">393</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;getComment&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">13</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;increment&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">3693</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;rate&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">0.9773</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;mostPopularArticle&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;深入理解浏览器缓存原理&quot;</span><span style="color:#E1E4E8;">}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">2</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;growFriends&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">2861</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;mostLike&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;老边&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;mostComment&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;重载新生&quot;</span><span style="color:#E1E4E8;">}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">3</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;mostGoodAt&quot;</span><span style="color:#E1E4E8;">:[</span><span style="color:#9ECBFF;">&quot;JavaScript&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;Vue3&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;TypeScript&quot;</span><span style="color:#E1E4E8;">]}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">4</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;readed&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1397</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;like&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1347</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;comment&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1345</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;words&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;244万&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;mostFocus&quot;</span><span style="color:#E1E4E8;">:[</span><span style="color:#9ECBFF;">&quot;前端&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;JavaScript&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;Vue.js&quot;</span><span style="color:#E1E4E8;">]}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">5</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;oftenRead&quot;</span><span style="color:#E1E4E8;">:[{</span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;seloven&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;followed&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">},{</span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;掘金酱&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;followed&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">},{</span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;CLICK克里克&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;followed&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">},{</span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;稀土君&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;followed&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">},{</span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;cc123nice&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;followed&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">}]}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">6</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;publishPin&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">395</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;interact&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1283</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;like&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">705</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;getLike&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">374</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;mostInteractWith&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;狗哥哥&quot;</span><span style="color:#E1E4E8;">}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">7</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;mostLateTime&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1665768240000</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;publishArticle&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;深入理解浏览器缓存原理&quot;</span><span style="color:#E1E4E8;">}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">8</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;mostEarlyTime&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">1661208660000</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;publishArticle&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;深入理解Proxy与Reflect&quot;</span><span style="color:#E1E4E8;">}},{</span><span style="color:#79B8FF;">&quot;id&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#79B8FF;">9</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;data&quot;</span><span style="color:#E1E4E8;">:{</span><span style="color:#79B8FF;">&quot;nickName&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;Ziu&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;ability&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;学习力&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;analysis&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;滴水石穿,读百篇尽显敏而好学&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">&quot;medal&quot;</span><span style="color:#E1E4E8;">:[</span><span style="color:#9ECBFF;">&quot;与你同行&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;笔耕不辍&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;博览群文&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;高才掘学&quot;</span><span style="color:#E1E4E8;">,</span><span style="color:#9ECBFF;">&quot;前排围观&quot;</span><span style="color:#E1E4E8;">]}}]}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{</span><span style="color:#005CC5;">&quot;pages&quot;</span><span style="color:#24292E;">:[{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;userName&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;Ziu&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;enterDay&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1647619200000</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;tillNow&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">291</span><span style="color:#24292E;">}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;publishArticle&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">187</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;getReader&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">78959</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;getLike&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">393</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;getComment&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">13</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;increment&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">3693</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;rate&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">0.9773</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;mostPopularArticle&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;深入理解浏览器缓存原理&quot;</span><span style="color:#24292E;">}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">2</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;growFriends&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">2861</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;mostLike&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;老边&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;mostComment&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;重载新生&quot;</span><span style="color:#24292E;">}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">3</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;mostGoodAt&quot;</span><span style="color:#24292E;">:[</span><span style="color:#032F62;">&quot;JavaScript&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;Vue3&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;TypeScript&quot;</span><span style="color:#24292E;">]}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">4</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;readed&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1397</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;like&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1347</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;comment&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1345</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;words&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;244万&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;mostFocus&quot;</span><span style="color:#24292E;">:[</span><span style="color:#032F62;">&quot;前端&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;JavaScript&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;Vue.js&quot;</span><span style="color:#24292E;">]}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">5</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;oftenRead&quot;</span><span style="color:#24292E;">:[{</span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;seloven&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;followed&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">},{</span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;掘金酱&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;followed&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">},{</span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;CLICK克里克&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;followed&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">},{</span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;稀土君&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;followed&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">},{</span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;cc123nice&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;followed&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">}]}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">6</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;publishPin&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">395</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;interact&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1283</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;like&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">705</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;getLike&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">374</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;mostInteractWith&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;狗哥哥&quot;</span><span style="color:#24292E;">}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">7</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;mostLateTime&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1665768240000</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;publishArticle&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;深入理解浏览器缓存原理&quot;</span><span style="color:#24292E;">}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">8</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;mostEarlyTime&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">1661208660000</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;publishArticle&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;深入理解Proxy与Reflect&quot;</span><span style="color:#24292E;">}},{</span><span style="color:#005CC5;">&quot;id&quot;</span><span style="color:#24292E;">:</span><span style="color:#005CC5;">9</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;data&quot;</span><span style="color:#24292E;">:{</span><span style="color:#005CC5;">&quot;nickName&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;Ziu&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;ability&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;学习力&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;analysis&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;滴水石穿,读百篇尽显敏而好学&quot;</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">&quot;medal&quot;</span><span style="color:#24292E;">:[</span><span style="color:#032F62;">&quot;与你同行&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;笔耕不辍&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;博览群文&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;高才掘学&quot;</span><span style="color:#24292E;">,</span><span style="color:#032F62;">&quot;前排围观&quot;</span><span style="color:#24292E;">]}}]}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><h2 id="编码中遇到的问题" tabindex="-1">编码中遇到的问题 <a class="header-anchor" href="#编码中遇到的问题" aria-label="Permalink to &quot;编码中遇到的问题&quot;"></a></h2><h3 id="音乐自动播放的问题" tabindex="-1">音乐自动播放的问题 <a class="header-anchor" href="#音乐自动播放的问题" aria-label="Permalink to &quot;音乐自动播放的问题&quot;"></a></h3><p>之前我希望不操作DOM而是通过<code>new Audio()</code>更优雅的实现音频播放。实际情况是:浏览器禁用了无用户操作的音频自动播放,要想实现自动播放有两种解决方法:</p><ul><li>HTML标签<code>&lt;audio&gt;</code>添加<code>autoplay</code>属性 后续播放/暂停都需要操作DOM</li><li>为界面添加监听器,监听到用户操作后手动触发<code>audio.play()</code></li></ul><p>为了保证功能实现的稳定性,我选择了前者。</p><div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">// useAudio.js</span></span>
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> { ref } </span><span style="color:#F97583;">from</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;vue&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">defaultURL</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;https://xxxxxxxxxxxxxxxxxxxxxxxx.mp3&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">export</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">default</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">function</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">useAudio</span><span style="color:#E1E4E8;">(</span><span style="color:#FFAB70;">url</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> defaultURL) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">audio</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">new</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">Audio</span><span style="color:#E1E4E8;">(url)</span></span>
<span class="line"><span style="color:#E1E4E8;"> audio.loop </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">true</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">playStatus</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">ref</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">false</span><span style="color:#E1E4E8;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">play</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> () </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;"> audio.</span><span style="color:#B392F0;">play</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> playStatus.value </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">true</span></span>
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">pause</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> () </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;"> audio.</span><span style="color:#B392F0;">pause</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> playStatus.value </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">false</span></span>
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;"> audio, play, pause, playStatus</span></span>
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">// useAudio.js</span></span>
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> { ref } </span><span style="color:#D73A49;">from</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;vue&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">defaultURL</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;https://xxxxxxxxxxxxxxxxxxxxxxxx.mp3&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">export</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">default</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">function</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">useAudio</span><span style="color:#24292E;">(</span><span style="color:#E36209;">url</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> defaultURL) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">audio</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">new</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">Audio</span><span style="color:#24292E;">(url)</span></span>
<span class="line"><span style="color:#24292E;"> audio.loop </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">true</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">playStatus</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">ref</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">false</span><span style="color:#24292E;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">play</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> () </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;"> audio.</span><span style="color:#6F42C1;">play</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> playStatus.value </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">true</span></span>
<span class="line"><span style="color:#24292E;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">pause</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> () </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;"> audio.</span><span style="color:#6F42C1;">pause</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> playStatus.value </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">false</span></span>
<span class="line"><span style="color:#24292E;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;"> audio, play, pause, playStatus</span></span>
<span class="line"><span style="color:#24292E;"> }</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><h3 id="vnode调整样式的问题" tabindex="-1">VNode调整样式的问题 <a class="header-anchor" href="#vnode调整样式的问题" aria-label="Permalink to &quot;VNode调整样式的问题&quot;"></a></h3><p>项目使用的框架是Vue3部分页面使用到了JSX语法众所周知JSX语法定义的组件返回的是一个VNode树要想统一为树上元素添加渐变的样式则需要遍历他们。</p><p>需要遍历树上所有元素,并分别为他们添加不同值的<code>animation-delay</code>属性:</p><div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">children</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">DOM</span><span style="color:#E1E4E8;">.children</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">for</span><span style="color:#E1E4E8;"> (</span><span style="color:#F97583;">let</span><span style="color:#E1E4E8;"> i </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">; i </span><span style="color:#F97583;">&lt;</span><span style="color:#E1E4E8;"> children.</span><span style="color:#79B8FF;">length</span><span style="color:#E1E4E8;">; i</span><span style="color:#F97583;">++</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">child</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> children[i]</span></span>
<span class="line"><span style="color:#E1E4E8;"> child.props</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> (child.props.style </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> { animationDelay: </span><span style="color:#9ECBFF;">`${</span><span style="color:#E1E4E8;">i</span><span style="color:#9ECBFF;"> </span><span style="color:#F97583;">*</span><span style="color:#9ECBFF;"> </span><span style="color:#79B8FF;">1000</span><span style="color:#9ECBFF;">}ms`</span><span style="color:#E1E4E8;"> })</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> Object.</span><span style="color:#B392F0;">assign</span><span style="color:#E1E4E8;">(child, {</span></span>
<span class="line"><span style="color:#E1E4E8;"> props: { style: { animationDelay: </span><span style="color:#9ECBFF;">`${</span><span style="color:#E1E4E8;">i</span><span style="color:#9ECBFF;"> </span><span style="color:#F97583;">*</span><span style="color:#9ECBFF;"> </span><span style="color:#79B8FF;">1000</span><span style="color:#9ECBFF;">}ms`</span><span style="color:#E1E4E8;"> } }</span></span>
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
<span class="line"><span style="color:#E1E4E8;"> }</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">children</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">DOM</span><span style="color:#24292E;">.children</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">for</span><span style="color:#24292E;"> (</span><span style="color:#D73A49;">let</span><span style="color:#24292E;"> i </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">1</span><span style="color:#24292E;">; i </span><span style="color:#D73A49;">&lt;</span><span style="color:#24292E;"> children.</span><span style="color:#005CC5;">length</span><span style="color:#24292E;">; i</span><span style="color:#D73A49;">++</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">child</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> children[i]</span></span>
<span class="line"><span style="color:#24292E;"> child.props</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> (child.props.style </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> { animationDelay: </span><span style="color:#032F62;">`${</span><span style="color:#24292E;">i</span><span style="color:#032F62;"> </span><span style="color:#D73A49;">*</span><span style="color:#032F62;"> </span><span style="color:#005CC5;">1000</span><span style="color:#032F62;">}ms`</span><span style="color:#24292E;"> })</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> Object.</span><span style="color:#6F42C1;">assign</span><span style="color:#24292E;">(child, {</span></span>
<span class="line"><span style="color:#24292E;"> props: { style: { animationDelay: </span><span style="color:#032F62;">`${</span><span style="color:#24292E;">i</span><span style="color:#032F62;"> </span><span style="color:#D73A49;">*</span><span style="color:#032F62;"> </span><span style="color:#005CC5;">1000</span><span style="color:#032F62;">}ms`</span><span style="color:#24292E;"> } }</span></span>
<span class="line"><span style="color:#24292E;"> })</span></span>
<span class="line"><span style="color:#24292E;"> }</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p><code>style</code>属性并不是VNode的直接属性而放在<code>props</code>上的</p><h3 id="监听animation结束事件并更新响应式变量" tabindex="-1">监听<code>Animation</code>结束事件并更新响应式变量 <a class="header-anchor" href="#监听animation结束事件并更新响应式变量" aria-label="Permalink to &quot;监听`Animation`结束事件并更新响应式变量&quot;"></a></h3><p>如果当前页所有的动画都播放完毕则需要将播放完的事件通知给JavaScript并将状态更新到响应式的变量中</p><p>在前文遍历DOM树时为树中最后一个动画节点添加<code>animationend</code>监听回调,回调函数中执行<code>document.dispatchEvent(e)</code>,其中<code>e</code>是通过<code>const e = new CustomEvent(&#39;custom-animationend&#39;)</code>创建的自定义事件</p><p>回调触发时,在别处的<code>onMounted</code>回调内监听该自定义事件的触发,并更新响应式变量</p><h3 id="切换页面支持触控滑动滚轮键盘" tabindex="-1">切换页面支持触控滑动滚轮键盘 <a class="header-anchor" href="#切换页面支持触控滑动滚轮键盘" aria-label="Permalink to &quot;切换页面支持触控滑动滚轮键盘&quot;"></a></h3><p>由于年终总结报告需要考虑到多种终端用户的体验,所以需要对翻页操作进行更多的优化</p><p>监听页面的触控滑动事件、滚轮滚动事件,并且匹配上翻页操作</p><div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 监听移动端滑动事件</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">let</span><span style="color:#E1E4E8;"> startY </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">0</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">let</span><span style="color:#E1E4E8;"> endY </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">0</span></span>
<span class="line"><span style="color:#E1E4E8;"> document.</span><span style="color:#B392F0;">addEventListener</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;touchstart&#39;</span><span style="color:#E1E4E8;">, (</span><span style="color:#FFAB70;">e</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;"> startY </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> e.touches[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">].clientY</span></span>
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
<span class="line"><span style="color:#E1E4E8;"> document.</span><span style="color:#B392F0;">addEventListener</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;touchend&#39;</span><span style="color:#E1E4E8;">, (</span><span style="color:#FFAB70;">e</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;"> endY </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> e.changedTouches[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">].clientY</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (endY </span><span style="color:#F97583;">-</span><span style="color:#E1E4E8;"> startY </span><span style="color:#F97583;">&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">50</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">prevPage</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (endY </span><span style="color:#F97583;">-</span><span style="color:#E1E4E8;"> startY </span><span style="color:#F97583;">&lt;</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">-</span><span style="color:#79B8FF;">50</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">nextPage</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 监听鼠标滚轮事件</span></span>
<span class="line"><span style="color:#E1E4E8;"> document.</span><span style="color:#B392F0;">addEventListener</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;wheel&#39;</span><span style="color:#E1E4E8;">, (</span><span style="color:#FFAB70;">e</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (e.deltaY </span><span style="color:#F97583;">&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">nextPage</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (e.deltaY </span><span style="color:#F97583;">&lt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">prevPage</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
<span class="line"><span style="color:#E1E4E8;"> })</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 监听键盘事件</span></span>
<span class="line"><span style="color:#E1E4E8;"> document.</span><span style="color:#B392F0;">addEventListener</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;keydown&#39;</span><span style="color:#E1E4E8;">, (</span><span style="color:#FFAB70;">e</span><span style="color:#E1E4E8;">) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (e.key </span><span style="color:#F97583;">===</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;ArrowUp&#39;</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">prevPage</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (e.key </span><span style="color:#F97583;">===</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;ArrowDown&#39;</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">nextPage</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#E1E4E8;"> }</span></span>
<span class="line"><span style="color:#E1E4E8;"> })</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 监听移动端滑动事件</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">let</span><span style="color:#24292E;"> startY </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">0</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">let</span><span style="color:#24292E;"> endY </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">0</span></span>
<span class="line"><span style="color:#24292E;"> document.</span><span style="color:#6F42C1;">addEventListener</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;touchstart&#39;</span><span style="color:#24292E;">, (</span><span style="color:#E36209;">e</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;"> startY </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> e.touches[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">].clientY</span></span>
<span class="line"><span style="color:#24292E;"> })</span></span>
<span class="line"><span style="color:#24292E;"> document.</span><span style="color:#6F42C1;">addEventListener</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;touchend&#39;</span><span style="color:#24292E;">, (</span><span style="color:#E36209;">e</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;"> endY </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> e.changedTouches[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">].clientY</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (endY </span><span style="color:#D73A49;">-</span><span style="color:#24292E;"> startY </span><span style="color:#D73A49;">&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">50</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">prevPage</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (endY </span><span style="color:#D73A49;">-</span><span style="color:#24292E;"> startY </span><span style="color:#D73A49;">&lt;</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">-</span><span style="color:#005CC5;">50</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">nextPage</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> }</span></span>
<span class="line"><span style="color:#24292E;"> })</span></span>
<span class="line"><span style="color:#24292E;"> </span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 监听鼠标滚轮事件</span></span>
<span class="line"><span style="color:#24292E;"> document.</span><span style="color:#6F42C1;">addEventListener</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;wheel&#39;</span><span style="color:#24292E;">, (</span><span style="color:#E36209;">e</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (e.deltaY </span><span style="color:#D73A49;">&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">0</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">nextPage</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (e.deltaY </span><span style="color:#D73A49;">&lt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">0</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">prevPage</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> }</span></span>
<span class="line"><span style="color:#24292E;"> })</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 监听键盘事件</span></span>
<span class="line"><span style="color:#24292E;"> document.</span><span style="color:#6F42C1;">addEventListener</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;keydown&#39;</span><span style="color:#24292E;">, (</span><span style="color:#E36209;">e</span><span style="color:#24292E;">) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (e.key </span><span style="color:#D73A49;">===</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;ArrowUp&#39;</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">prevPage</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (e.key </span><span style="color:#D73A49;">===</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;ArrowDown&#39;</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6F42C1;">nextPage</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#24292E;"> }</span></span>
<span class="line"><span style="color:#24292E;"> })</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br></div></div><h3 id="代码打包" tabindex="-1">代码打包 <a class="header-anchor" href="#代码打包" aria-label="Permalink to &quot;代码打包&quot;"></a></h3><p>由于最后需要将项目放到码上掘金平台运行,所以需要考虑静态资源的加载问题</p><p>这里我使用到了Vite提供的类似<code>file-loader</code>的功能可以将大小在指定阈值下的图片资源直接转为行内的DataURL配置选项是<code>config.build.assetsInlineLimit</code>,这样所有的图片资源都不必考虑外部引入的问题,直接内嵌进代码。</p><h2 id="技术介绍" tabindex="-1">技术介绍 <a class="header-anchor" href="#技术介绍" aria-label="Permalink to &quot;技术介绍&quot;"></a></h2><p>主界面使用的是Vue3的<code>SFC</code>,主要逻辑都在单文件组件中完成。通过<code>JSX</code>语法编写不同页面的内容,这样更方便我们为每个节点添加不同的动画。</p><p><code>JSX</code>编写的组件通过全局注册后,在<code>SFC</code>中通过<code>&lt;Component&gt;</code>动态加载。</p><p>图片资源方面使用到了雪碧图部署后可以降低客户端发起HTTP请求频次提高性能</p><p>代码复用方面,样式代码都抽离为单个的<code>xxxx.less</code>文件,哪里用到了直接导入即可</p><p>使用到了<code>Pinia</code>状态管理库,将<code>switching</code> <code>pageId</code> <code>audioStatus</code>等全局状态放到其中管理非常方便,避免了<code>provide</code><code>inject</code>的繁琐</p><h2 id="功能介绍" tabindex="-1">功能介绍 <a class="header-anchor" href="#功能介绍" aria-label="Permalink to &quot;功能介绍&quot;"></a></h2><ul><li>支持PC端/移动端展示不同样式 <ul><li>PC端左侧有控制栏 支持控制音乐播放 切换页面</li><li>移动端右上角控制音乐 滑动切换页面</li></ul></li><li>页面之间切换有动态效果 文字逐行展示</li><li>左上角、右下角会出现矢量动图</li></ul><h2 id="demo展示" tabindex="-1">Demo展示 <a class="header-anchor" href="#demo展示" aria-label="Permalink to &quot;Demo展示&quot;"></a></h2><p><a href="https://juejin-annual-report.vercel.app/" target="_blank" rel="noreferrer">Demo(Vercel)</a></p><p><a href="https://code.juejin.cn/pen/7184691373911015459" target="_blank" rel="noreferrer">jcode</a></p></div></div></main><footer class="VPDocFooter" data-v-4ad9891f data-v-3ec2f4a2><!--[--><!--]--><div class="edit-info" data-v-3ec2f4a2><div class="edit-link" data-v-3ec2f4a2><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/ZiuChen/ZiuChen.github.io/edit/main/docs/article/从0实现一个年度报告.md" target="_blank" rel="noreferrer" data-v-3ec2f4a2><!--[--><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="edit-link-icon" aria-label="edit icon" data-v-3ec2f4a2><path d="M18,23H4c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h7c0.6,0,1,0.4,1,1s-0.4,1-1,1H4C3.4,5,3,5.4,3,6v14c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1v-7c0-0.6,0.4-1,1-1s1,0.4,1,1v7C21,21.7,19.7,23,18,23z"></path><path d="M8,17c-0.3,0-0.5-0.1-0.7-0.3C7,16.5,6.9,16.1,7,15.8l1-4c0-0.2,0.1-0.3,0.3-0.5l9.5-9.5c1.2-1.2,3.2-1.2,4.4,0c1.2,1.2,1.2,3.2,0,4.4l-9.5,9.5c-0.1,0.1-0.3,0.2-0.5,0.3l-4,1C8.2,17,8.1,17,8,17zM9.9,12.5l-0.5,2.1l2.1-0.5l9.3-9.3c0.4-0.4,0.4-1.1,0-1.6c-0.4-0.4-1.2-0.4-1.6,0l0,0L9.9,12.5z M18.5,2.5L18.5,2.5L18.5,2.5z"></path></svg> Edit this page on GitHub<!--]--></a></div><div class="last-updated" data-v-3ec2f4a2><p class="VPLastUpdated" data-v-3ec2f4a2 data-v-a4c9a2aa>Updated Date: <time datetime="2023-11-16T16:33:46.000Z" data-v-a4c9a2aa></time></p></div></div><nav class="prev-next" data-v-3ec2f4a2><div class="pager" data-v-3ec2f4a2><a class="pager-link prev" href="/article/%E4%B8%80%E6%96%87%E8%AF%BB%E6%87%82%E5%87%BD%E6%95%B0%E4%B8%ADthis%E6%8C%87%E5%90%91%E9%97%AE%E9%A2%98.html" data-v-3ec2f4a2><span class="desc" data-v-3ec2f4a2>Previous page</span><span class="title" data-v-3ec2f4a2>一文读懂函数中this指向问题</span></a></div><div class="pager" data-v-3ec2f4a2><a class="pager-link next" href="/article/%E5%BD%BB%E5%BA%95%E6%90%9E%E6%87%82%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%95%B0%E6%8D%AE%E5%B1%9E%E6%80%A7%E6%8F%8F%E8%BF%B0%E7%AC%A6%E3%80%81%E5%AD%98%E5%82%A8%E5%B1%9E%E6%80%A7%E6%8F%8F%E8%BF%B0%E7%AC%A6.html" data-v-3ec2f4a2><span class="desc" data-v-3ec2f4a2>Next page</span><span class="title" data-v-3ec2f4a2>彻底搞懂对象的数据属性描述符、存储属性描述符</span></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-c9141815 data-v-9d485890><div class="container" data-v-9d485890><p class="message" data-v-9d485890>Released under the MIT License.</p><p class="copyright" data-v-9d485890>Copyright © 2019-present Ziu Chen</p></div></footer><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"note_mysql.md\":\"ff8922c9\",\"article_深入理解浏览器运行原理.md\":\"8c6f3275\",\"project_smartwordbreak_index.md\":\"af309eda\",\"project_smartwordbreak_log_index.md\":\"31ac59f5\",\"project_smartwordbreak_statement_index.md\":\"81fd9b75\",\"works_contribution.md\":\"8306e443\",\"project_clipboardmanager_guide_index.md\":\"dccd8f03\",\"article_浅析defineproperty与proxy实现的双向绑定.md\":\"4637264b\",\"index.md\":\"630640f7\",\"note_front-end engineering.md\":\"83907b9b\",\"article_一文读懂伪类与伪元素.md\":\"71e171a9\",\"article_一文读懂事件冒泡与事件捕获.md\":\"3070d1c2\",\"note_css.md\":\"03b93408\",\"self_index.md\":\"bfa7a821\",\"project_jsrunner_index.md\":\"643e2654\",\"project_markdown_index.md\":\"dae1c90a\",\"project_markdown_shortcut_index.md\":\"a8947c74\",\"project_markdown_log_index.md\":\"1f92f094\",\"article_彻底搞懂对象的数据属性描述符、存储属性描述符.md\":\"03c60053\",\"works_opensource.md\":\"41143a1c\",\"note_ssr.md\":\"be3c09d1\",\"project_clipboardmanager_log_index.md\":\"b71f99ad\",\"project_clipboardmanager_statement_index.md\":\"ea3425cd\",\"article_深入理解proxy与reflect.md\":\"94ee110c\",\"article_【快手】深入理解前端面试题.md\":\"d7a7227f\",\"article_从0实现一个年度报告.md\":\"91662ae0\",\"article_【2023】青训营 - 前端练习题汇总解析.md\":\"37fd1957\",\"article_深入vue3源码看看vue.use后究竟发生了什么.md\":\"636ae3ca\",\"note_javascript.md\":\"1094591b\",\"note_redux.md\":\"046d6b05\",\"article_深入javascript数据类型.md\":\"9097d859\",\"article_深入理解浏览器缓存机制.md\":\"ce1c6591\",\"article_【字节跳动】前端面试题总结.md\":\"429af843\",\"project_jsrunner_log_index.md\":\"90b9639e\",\"article_一文读懂函数中this指向问题.md\":\"e7119865\",\"note_react router.md\":\"27eec1ee\",\"note_react hooks.md\":\"81283fc9\",\"article_【用友金融】前端面试题总结.md\":\"8ced60ed\",\"project_clipboardmanager_index.md\":\"41ff38a8\",\"note_react.md\":\"4d7f393e\",\"note_javascriptenhanced.md\":\"a36ac08d\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"ZiuChen\",\"description\":\"Unlimited Progress.\",\"base\":\"/\",\"head\":[],\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.png\",\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"我的项目\",\"items\":[{\"text\":\"超级剪贴板\",\"link\":\"/project/ClipboardManager/\"},{\"text\":\"超级Markdown\",\"link\":\"/project/Markdown/\"},{\"text\":\"超级JavaScript\",\"link\":\"/project/JSRunner/\"},{\"text\":\"超级分词\",\"link\":\"/project/SmartWordBreak/\"}]},{\"text\":\"开源作品\",\"items\":[{\"text\":\"个人作品\",\"link\":\"/works/opensource\"},{\"text\":\"社区贡献\",\"link\":\"/works/contribution\"}]},{\"text\":\"学习笔记\",\"items\":[{\"text\":\"JavaScript基础\",\"link\":\"/note/JavaScript\"},{\"text\":\"CSS基础\",\"link\":\"/note/CSS\"},{\"text\":\"JavaScript进阶\",\"link\":\"/note/JavaScriptEnhanced\"},{\"text\":\"前端工程化\",\"link\":\"/note/Front-end Engineering\"},{\"text\":\"服务端渲染\",\"link\":\"/note/SSR\"},{\"text\":\"React基础\",\"link\":\"/note/React\"},{\"text\":\"React Hooks\",\"link\":\"/note/React Hooks\"},{\"text\":\"Redux\",\"link\":\"/note/Redux\"},{\"text\":\"React Router\",\"link\":\"/note/React Router\"},{\"text\":\"MySQL\",\"link\":\"/note/MySQL\"}]},{\"text\":\"个人介绍\",\"link\":\"/self/\"}],\"sidebar\":[{\"text\":\"我的项目\",\"items\":[{\"text\":\"超级剪贴板\",\"link\":\"/project/ClipboardManager/\"},{\"text\":\"超级Markdown\",\"link\":\"/project/Markdown/\"},{\"text\":\"超级JavaScript\",\"link\":\"/project/JSRunner/\"},{\"text\":\"超级分词\",\"link\":\"/project/SmartWordBreak/\"}]},{\"text\":\"开源作品\",\"collapsed\":true,\"items\":[{\"text\":\"个人作品\",\"link\":\"/works/opensource\"},{\"text\":\"社区贡献\",\"link\":\"/works/contribution\"}]},{\"text\":\"文章归档\",\"collapsed\":true,\"items\":[{\"text\":\"【2023】青训营 - 前端练习题汇总解析\",\"link\":\"/article/【2023】青训营 - 前端练习题汇总解析\"},{\"text\":\"【字节跳动】前端面试题总结\",\"link\":\"/article/【字节跳动】前端面试题总结\"},{\"text\":\"【快手】深入理解前端面试题\",\"link\":\"/article/【快手】深入理解前端面试题\"},{\"text\":\"【用友金融】前端面试题总结\",\"link\":\"/article/【用友金融】前端面试题总结\"},{\"text\":\"一文读懂事件冒泡与事件捕获\",\"link\":\"/article/一文读懂事件冒泡与事件捕获\"},{\"text\":\"一文读懂伪类与伪元素\",\"link\":\"/article/一文读懂伪类与伪元素\"},{\"text\":\"一文读懂函数中this指向问题\",\"link\":\"/article/一文读懂函数中this指向问题\"},{\"text\":\"从0实现一个年度报告\",\"link\":\"/article/从0实现一个年度报告\"},{\"text\":\"彻底搞懂对象的数据属性描述符、存储属性描述符\",\"link\":\"/article/彻底搞懂对象的数据属性描述符、存储属性描述符\"},{\"text\":\"浅析defineProperty与Proxy实现的双向绑定\",\"link\":\"/article/浅析defineProperty与Proxy实现的双向绑定\"},{\"text\":\"深入JavaScript数据类型\",\"link\":\"/article/深入JavaScript数据类型\"},{\"text\":\"深入Vue3源码看看Vue.use后究竟发生了什么\",\"link\":\"/article/深入Vue3源码看看Vue.use后究竟发生了什么\"},{\"text\":\"深入理解Proxy与Reflect\",\"link\":\"/article/深入理解Proxy与Reflect\"},{\"text\":\"深入理解浏览器缓存机制\",\"link\":\"/article/深入理解浏览器缓存机制\"},{\"text\":\"深入理解浏览器运行原理\",\"link\":\"/article/深入理解浏览器运行原理\"}]},{\"text\":\"学习笔记\",\"collapsed\":true,\"items\":[{\"text\":\"JavaScript基础\",\"link\":\"/note/JavaScript\"},{\"text\":\"CSS基础\",\"link\":\"/note/CSS\"},{\"text\":\"JavaScript进阶\",\"link\":\"/note/JavaScriptEnhanced\"},{\"text\":\"前端工程化\",\"link\":\"/note/Front-end Engineering\"},{\"text\":\"服务端渲染\",\"link\":\"/note/SSR\"},{\"text\":\"React基础\",\"link\":\"/note/React\"},{\"text\":\"React Hooks\",\"link\":\"/note/React Hooks\"},{\"text\":\"Redux\",\"link\":\"/note/Redux\"},{\"text\":\"React Router\",\"link\":\"/note/React Router\"},{\"text\":\"MySQL\",\"link\":\"/note/MySQL\"}]}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/ZiuChen\"},{\"icon\":{\"svg\":\"<svg width=\\\"36\\\" height=\\\"28\\\" viewBox=\\\"0 0 36 28\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" d=\\\"M17.5875 6.77268L21.8232 3.40505L17.5875 0.00748237L17.5837 0L13.3555 3.39757L17.5837 6.76894L17.5875 6.77268ZM17.5863 17.3955H17.59L28.5161 8.77432L25.5526 6.39453L17.59 12.6808H17.5863L17.5825 12.6845L9.61993 6.40201L6.66016 8.78181L17.5825 17.3992L17.5863 17.3955ZM17.5828 23.2891L17.5865 23.2854L32.2133 11.7456L35.1768 14.1254L28.5238 19.3752L17.5865 28L0.284376 14.3574L0 14.1291L2.95977 11.7531L17.5828 23.2891Z\\\" fill=\\\"#1E80FF\\\"/></svg>\"},\"link\":\"https://juejin.cn/user/1887205216238477\"}],\"editLink\":{\"pattern\":\"https://github.com/ZiuChen/ZiuChen.github.io/edit/main/docs/:path\",\"text\":\"Edit this page on GitHub\"},\"footer\":{\"message\":\"Released under the MIT License.\",\"copyright\":\"Copyright © 2019-present Ziu Chen\"},\"lastUpdatedText\":\"Updated Date\",\"search\":{\"provider\":\"algolia\",\"options\":{\"appId\":\"LFZ2CPWWUG\",\"apiKey\":\"b4fd296ea5e467b3ac4a582160ff3122\",\"indexName\":\"ziuchenio\"}}},\"locales\":{},\"scrollOffset\":90,\"cleanUrls\":false}");</script>
</body>
</html>