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

115 lines
88 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

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.60c127af.css" as="style">
<link rel="modulepreload" href="/assets/chunks/VPAlgoliaSearchBox.7b810437.js">
<link rel="modulepreload" href="/assets/app.6cf9e426.js">
<link rel="modulepreload" href="/assets/article_从0实现一个年度报告.md.2fe79340.lean.js">
<link rel="icon" href="/logo.png">
<script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-3af881ed><!--[--><!--]--><!--[--><span tabindex="-1" data-v-00bddfc0></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-00bddfc0> Skip to content </a><!--]--><!----><header class="VPNav" data-v-3af881ed data-v-3796071a><div class="VPNavBar has-sidebar" data-v-3796071a data-v-fe00b0e5><div class="container" data-v-fe00b0e5><div class="title" data-v-fe00b0e5><div class="VPNavBarTitle has-sidebar" data-v-fe00b0e5 data-v-a7f91dcc><a class="title" href="/" data-v-a7f91dcc><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logo.png" alt data-v-dca92699><!--]--><!--[-->ZiuChen<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-fe00b0e5><div class="curtain" data-v-fe00b0e5></div><div class="content-body" data-v-fe00b0e5><!--[--><!--]--><div class="VPNavBarSearch search" data-v-fe00b0e5 style="--6dc8a562:&#39;Meta&#39;;"><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"><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-fe00b0e5 data-v-a4f7fa5c><span id="main-nav-aria-label" class="visually-hidden" data-v-a4f7fa5c>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/" data-v-a4f7fa5c data-v-1a106a35 data-v-8dd200cc><!--[-->首页<!--]--><!----></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-a4f7fa5c data-v-e76b733c><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-e76b733c><span class="text" data-v-e76b733c><!----> 我的项目 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-e76b733c><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-e76b733c><div class="VPMenu" data-v-e76b733c data-v-faf23071><div class="items" data-v-faf23071><!--[--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/project/ClipboardManager/" data-v-c0d2d58e data-v-8dd200cc><!--[-->超级剪贴板<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/project/SmartWordBreak/" data-v-c0d2d58e data-v-8dd200cc><!--[-->超级分词<!--]--><!----></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-a4f7fa5c data-v-e76b733c><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-e76b733c><span class="text" data-v-e76b733c><!----> 开源作品 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-e76b733c><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-e76b733c><div class="VPMenu" data-v-e76b733c data-v-faf23071><div class="items" data-v-faf23071><!--[--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/works/opensource.html" data-v-c0d2d58e data-v-8dd200cc><!--[-->个人作品<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/works/contribution.html" data-v-c0d2d58e data-v-8dd200cc><!--[-->社区贡献<!--]--><!----></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-a4f7fa5c data-v-e76b733c><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-e76b733c><span class="text" data-v-e76b733c><!----> 学习笔记 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-e76b733c><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-e76b733c><div class="VPMenu" data-v-e76b733c data-v-faf23071><div class="items" data-v-faf23071><!--[--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/note/JavaScript.html" data-v-c0d2d58e data-v-8dd200cc><!--[-->JavaScript基础<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/note/CSS.html" data-v-c0d2d58e data-v-8dd200cc><!--[-->CSS基础<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/note/JavaScriptEnhanced.html" data-v-c0d2d58e data-v-8dd200cc><!--[-->JavaScript进阶<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/note/Front-end%20Engineering.html" data-v-c0d2d58e data-v-8dd200cc><!--[-->前端工程化<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-faf23071 data-v-c0d2d58e><a class="VPLink link" href="/note/SSR.html" data-v-c0d2d58e data-v-8dd200cc><!--[-->服务端渲染<!--]--><!----></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/self/" data-v-a4f7fa5c data-v-1a106a35 data-v-8dd200cc><!--[-->个人介绍<!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-fe00b0e5 data-v-2d4753dd><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-2d4753dd data-v-867372a0 data-v-dc009bc3><span class="check" data-v-dc009bc3><span class="icon" data-v-dc009bc3><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-867372a0><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-867372a0><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-fe00b0e5 data-v-f0005c73 data-v-819d8281><!--[--><a class="VPSocialLink" href="https://ziuchen.github.io/" target="_blank" rel="noopener" data-v-819d8281 data-v-ba84061a><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" href="https://juejin.cn/user/1887205216238477" target="_blank" rel="noopener" data-v-819d8281 data-v-ba84061a><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-fe00b0e5 data-v-0467f0ad data-v-e76b733c><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-e76b733c><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-e76b733c><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-e76b733c><div class="VPMenu" data-v-e76b733c data-v-faf23071><!----><!--[--><!--[--><!----><div class="group" data-v-0467f0ad><div class="item appearance" data-v-0467f0ad><p class="label" data-v-0467f0ad>Appearance</p><div class="appearance-action" data-v-0467f0ad><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-0467f0ad data-v-867372a0 data-v-dc009bc3><span class="check" data-v-dc009bc3><span class="icon" data-v-dc009bc3><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-867372a0><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-867372a0><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-0467f0ad><div class="item social-links" data-v-0467f0ad><div class="VPSocialLinks social-links-list" data-v-0467f0ad data-v-819d8281><!--[--><a class="VPSocialLink" href="https://ziuchen.github.io/" target="_blank" rel="noopener" data-v-819d8281 data-v-ba84061a><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" href="https://juejin.cn/user/1887205216238477" target="_blank" rel="noopener" data-v-819d8281 data-v-ba84061a><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-fe00b0e5 data-v-f1813d69><span class="container" data-v-f1813d69><span class="top" data-v-f1813d69></span><span class="middle" data-v-f1813d69></span><span class="bottom" data-v-f1813d69></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav" data-v-3af881ed data-v-07d63927><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-07d63927><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-07d63927><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-07d63927>Menu</span></button><a class="top-link" href="#" data-v-07d63927>Return to top</a></div><aside class="VPSidebar" data-v-3af881ed data-v-eec6a639><div class="curtain" data-v-eec6a639></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-eec6a639><span class="visually-hidden" id="sidebar-aria-label" data-v-eec6a639> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-eec6a639><section class="VPSidebarItem level-0 collapsible" data-v-eec6a639 data-v-66b47b62><div class="item" role="button" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link" data-v-66b47b62 data-v-8dd200cc><!--[--><h2 class="text" data-v-66b47b62>我的项目</h2><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-66b47b62><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-66b47b62><!--[--><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/project/ClipboardManager/" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>超级剪贴板</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/project/SmartWordBreak/" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>超级分词</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><!--]--></div></section></div><div class="group" data-v-eec6a639><section class="VPSidebarItem level-0 collapsible" data-v-eec6a639 data-v-66b47b62><div class="item" role="button" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link" data-v-66b47b62 data-v-8dd200cc><!--[--><h2 class="text" data-v-66b47b62>开源作品</h2><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-66b47b62><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-66b47b62><!--[--><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/works/opensource.html" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>个人作品</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/works/contribution.html" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>社区贡献</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><!--]--></div></section></div><div class="group" data-v-eec6a639><section class="VPSidebarItem level-0 collapsible has-active" data-v-eec6a639 data-v-66b47b62><div class="item" role="button" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link" data-v-66b47b62 data-v-8dd200cc><!--[--><h2 class="text" data-v-66b47b62>文章归档</h2><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-66b47b62><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-66b47b62><!--[--><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>【2023】青训营 - 前端练习题汇总解析</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>一文读懂事件冒泡与事件捕获</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>一文读懂伪类与伪元素</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>一文读懂函数中this指向问题</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link is-active has-active" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>从0实现一个年度报告</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>彻底搞懂对象的数据属性描述符、存储属性描述符</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>深入Vue3源码看看Vue.use后究竟发生了什么</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>深入理解Proxy与Reflect</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>深入理解浏览器缓存机制</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></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-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>深入理解浏览器运行原理</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><!--]--></div></section></div><div class="group" data-v-eec6a639><section class="VPSidebarItem level-0 collapsible" data-v-eec6a639 data-v-66b47b62><div class="item" role="button" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link" data-v-66b47b62 data-v-8dd200cc><!--[--><h2 class="text" data-v-66b47b62>学习笔记</h2><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-66b47b62><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-66b47b62><!--[--><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/note/JavaScript.html" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>JavaScript基础</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/note/CSS.html" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>CSS基础</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/note/JavaScriptEnhanced.html" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>JavaScript进阶</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/note/Front-end%20Engineering.html" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>前端工程化</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-66b47b62 data-v-66b47b62><div class="item" data-v-66b47b62><div class="indicator" data-v-66b47b62></div><a class="VPLink link link" href="/note/SSR.html" data-v-66b47b62 data-v-8dd200cc><!--[--><p class="text" data-v-66b47b62>服务端渲染</p><!--]--><!----></a><div class="caret" role="button" data-v-66b47b62><!----></div></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-3af881ed data-v-e31feb0e><div class="VPDoc has-sidebar has-aside" data-v-e31feb0e data-v-30dabfe4><div class="container" data-v-30dabfe4><div class="aside" data-v-30dabfe4><div class="aside-curtain" data-v-30dabfe4></div><div class="aside-container" data-v-30dabfe4><div class="aside-content" data-v-30dabfe4><div class="VPDocAside" data-v-30dabfe4 data-v-7110f5c9><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-7110f5c9 data-v-9c6f1a55><div class="content" data-v-9c6f1a55><div class="outline-marker" data-v-9c6f1a55></div><div class="outline-title" data-v-9c6f1a55>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-9c6f1a55><span class="visually-hidden" id="doc-outline-aria-label" data-v-9c6f1a55> Table of Contents for current page </span><ul class="root" data-v-9c6f1a55 data-v-02afc12d><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-7110f5c9></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-30dabfe4><div class="content-container" data-v-30dabfe4><!--[--><!--]--><main class="main" data-v-30dabfe4><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-30dabfe4><div><h1 id="从0实现一个年度报告" tabindex="-1">从0实现一个年度报告 <a class="header-anchor" href="#从0实现一个年度报告" aria-hidden="true">#</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-hidden="true">#</a></h2><h3 id="_1-数据模拟" tabindex="-1">1. 数据模拟 <a class="header-anchor" href="#_1-数据模拟" aria-hidden="true">#</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-hidden="true">#</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-hidden="true">#</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-hidden="true">#</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-hidden="true">#</a></h2><h3 id="用户数据内容" tabindex="-1">用户数据内容 <a class="header-anchor" href="#用户数据内容" aria-hidden="true">#</a></h3><div class="language- line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">- 用户名</span></span>
<span class="line"><span style="color:#A6ACCD;">- 注册时间 距今天数</span></span>
<span class="line"><span style="color:#A6ACCD;">- 创作相关</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 发布文章数</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 总阅读数 总赞数 总评论数</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 掘力值增长 超过人数百分比</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 最受欢迎的文章标题</span></span>
<span class="line"><span style="color:#A6ACCD;">- 社交相关</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 多少位掘友看过你的文章</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 点赞最多的掘友 评论最多的掘友</span></span>
<span class="line"><span style="color:#A6ACCD;">- 学习相关</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 阅读文章数 点赞数 评论数</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 总阅读字数</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 最关注的技术领域TOP3</span></span>
<span class="line"><span style="color:#A6ACCD;">- 沸点相关</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 发布沸点数 互动掘友数 点赞数 收赞数</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 互动最频繁的掘友</span></span>
<span class="line"><span style="color:#A6ACCD;">- 深夜阅读</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 最晚一次阅读时间</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 阅读的文章标题</span></span>
<span class="line"><span style="color:#A6ACCD;">- 早起阅读</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 最晚一次阅读时间</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 阅读的文章标题</span></span>
<span class="line"><span style="color:#A6ACCD;">- 最终总结</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 用户名</span></span>
<span class="line"><span style="color:#A6ACCD;"> - 获得成就 饼图</span></span>
<span class="line"><span style="color:#A6ACCD;"></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-hidden="true">#</a></h3><p>根据不同页面分配不同的字段与数据我根据自己的报告模拟了以下JSON数据</p><div class="language-json line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C792EA;">pages</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:[{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">userName</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">enterDay</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1647619200000</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">tillNow</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">291</span><span style="color:#89DDFF;">}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">publishArticle</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">187</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">getReader</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">78959</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">getLike</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">393</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">getComment</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">13</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">increment</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">3693</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">rate</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">0.9773</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostPopularArticle</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">深入理解浏览器缓存原理</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">growFriends</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">2861</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostLike</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">老边</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostComment</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">重载新生</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">3</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostGoodAt</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:[</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">JavaScript</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Vue3</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">TypeScript</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">]}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">4</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">readed</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1397</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">like</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1347</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">comment</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1345</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">words</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">244万</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostFocus</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:[</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">前端</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">JavaScript</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Vue.js</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">]}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">5</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">oftenRead</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:[{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">seloven</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">followed</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">掘金酱</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">followed</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">CLICK克里克</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">followed</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">稀土君</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">followed</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">cc123nice</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F07178;">followed</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">}]}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">6</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">publishPin</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">395</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">interact</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1283</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">like</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">705</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">getLike</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">374</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostInteractWith</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">狗哥哥</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">7</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostLateTime</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1665768240000</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">publishArticle</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">深入理解浏览器缓存原理</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">8</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">mostEarlyTime</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">1661208660000</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">publishArticle</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">深入理解Proxy与Reflect</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">}},{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#F78C6C;">9</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#FFCB6B;">data</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:{</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">nickName</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">ability</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">学习力</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">analysis</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">滴水石穿,读百篇尽显敏而好学</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#F78C6C;">medal</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">:[</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">与你同行</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">笔耕不辍</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">博览群文</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">高才掘学</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">前排围观</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">]}}]}</span></span>
<span class="line"></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-hidden="true">#</a></h2><h3 id="音乐自动播放的问题" tabindex="-1">音乐自动播放的问题 <a class="header-anchor" href="#音乐自动播放的问题" aria-hidden="true">#</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 line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// useAudio.js</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">import</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ref</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">vue</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> defaultURL </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">https://xxxxxxxxxxxxxxxxxxxxxxxx.mp3</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">export</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">default</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">useAudio</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">url</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> defaultURL</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">audio</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">new</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">Audio</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">url</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">audio</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">loop</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">playStatus</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">ref</span><span style="color:#F07178;">(</span><span style="color:#FF9CAC;">false</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">play</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">audio</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">play</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">playStatus</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">pause</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">audio</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">pause</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">playStatus</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">false</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">audio</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">play</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">pause</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">playStatus</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></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-hidden="true">#</a></h3><p>项目使用的框架是Vue3部分页面使用到了JSX语法众所周知JSX语法定义的组件返回的是一个VNode树要想统一为树上元素添加渐变的样式则需要遍历他们。</p><p>需要遍历树上所有元素,并分别为他们添加不同值的<code>animation-delay</code>属性:</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> children </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> DOM</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">children</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;">&lt;</span><span style="color:#A6ACCD;"> children</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> i</span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">child</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">children</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">child</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">props</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">?</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">child</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">props</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">style</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> animationDelay</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">`${</span><span style="color:#A6ACCD;">i </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">ms</span><span style="color:#89DDFF;">`</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Object</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">assign</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">child</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> props</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> style</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> animationDelay</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">`${</span><span style="color:#A6ACCD;">i </span><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">ms</span><span style="color:#89DDFF;">`</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></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-hidden="true">#</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-hidden="true">#</a></h3><p>由于年终总结报告需要考虑到多种终端用户的体验,所以需要对翻页操作进行更多的优化</p><p>监听页面的触控滑动事件、滚轮滚动事件,并且匹配上翻页操作</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// 监听移动端滑动事件</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> startY </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> endY </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
<span class="line"><span style="color:#A6ACCD;"> document</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">touchstart</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">startY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">touches</span><span style="color:#F07178;">[</span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">clientY</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;"> document</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">touchend</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">endY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">changedTouches</span><span style="color:#F07178;">[</span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">]</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">clientY</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">endY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">startY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">50</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">prevPage</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">endY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">startY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F78C6C;">50</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">nextPage</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// 监听鼠标滚轮事件</span></span>
<span class="line"><span style="color:#A6ACCD;"> document</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">wheel</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">deltaY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">nextPage</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">deltaY</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">prevPage</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;"> </span><span style="color:#676E95;font-style:italic;">// 监听键盘事件</span></span>
<span class="line"><span style="color:#A6ACCD;"> document</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">addEventListener</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">keydown</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">e</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">key</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">ArrowUp</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">prevPage</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">e</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">key</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">ArrowDown</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#82AAFF;">nextPage</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></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-hidden="true">#</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-hidden="true">#</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-hidden="true">#</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-hidden="true">#</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-30dabfe4 data-v-cc0f9778><div class="edit-info" data-v-cc0f9778><div class="edit-link" data-v-cc0f9778><a class="VPLink link edit-link-button" href="https://github.com/ZiuChen/ZiuChen.github.io/edit/main/docs/article/从0实现一个年度报告.md" target="_blank" rel="noreferrer" data-v-cc0f9778 data-v-8dd200cc><!--[--><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="edit-link-icon" data-v-cc0f9778><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-cc0f9778><p class="VPLastUpdated" data-v-cc0f9778 data-v-de6a4e1f>Updated Date: <time datetime="2023-02-15T13:53:37.000Z" data-v-de6a4e1f></time></p></div></div><div class="prev-next" data-v-cc0f9778><div class="pager" data-v-cc0f9778><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-cc0f9778><span class="desc" data-v-cc0f9778>Previous page</span><span class="title" data-v-cc0f9778>一文读懂函数中this指向问题</span></a></div><div class="has-prev pager" data-v-cc0f9778><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-cc0f9778><span class="desc" data-v-cc0f9778>Next page</span><span class="title" data-v-cc0f9778>彻底搞懂对象的数据属性描述符、存储属性描述符</span></a></div></div></footer><!--[--><!--]--></div></div></div></div></div><footer class="VPFooter has-sidebar" data-v-3af881ed data-v-8b655284><div class="container" data-v-8b655284><p class="message" data-v-8b655284>Released under the MIT License.</p><p class="copyright" data-v-8b655284>Copyright © 2019-present Ziu Chen</p></div></footer><!--[--><!--]--></div></div>
<script>__VP_HASH_MAP__ = JSON.parse("{\"article_深入vue3源码看看vue.use后究竟发生了什么.md\":\"55a883c8\",\"article_一文读懂伪类与伪元素.md\":\"eff1b557\",\"article_彻底搞懂对象的数据属性描述符、存储属性描述符.md\":\"d8143a19\",\"article_从0实现一个年度报告.md\":\"2fe79340\",\"article_一文读懂函数中this指向问题.md\":\"231015d6\",\"article_【2023】青训营 - 前端练习题汇总解析.md\":\"4eb34c9d\",\"article_一文读懂事件冒泡与事件捕获.md\":\"1c409bb8\",\"article_深入理解proxy与reflect.md\":\"ed1492ff\",\"index.md\":\"c9a62842\",\"article_深入理解浏览器运行原理.md\":\"68a5a9e3\",\"article_深入理解浏览器缓存机制.md\":\"ffa7c337\",\"note_javascript.md\":\"c3b70a43\",\"note_front-end engineering.md\":\"9c830697\",\"note_css.md\":\"02e58778\",\"project_smartwordbreak_index.md\":\"3f252c44\",\"project_smartwordbreak_log_index.md\":\"aa668ca0\",\"project_smartwordbreak_statement_index.md\":\"a6c8991d\",\"works_contribution.md\":\"2de3214c\",\"self_index.md\":\"61d9fe32\",\"works_opensource.md\":\"4873ace6\",\"project_clipboardmanager_guide_index.md\":\"5d1aeccd\",\"project_clipboardmanager_statement_index.md\":\"266e3976\",\"project_clipboardmanager_index.md\":\"b1dec137\",\"note_ssr.md\":\"5e6cefdd\",\"project_clipboardmanager_vip_index.md\":\"64066399\",\"project_clipboardmanager_log_index.md\":\"e647084b\",\"note_javascriptenhanced.md\":\"30fbee05\"}")</script>
<script type="module" async src="/assets/app.6cf9e426.js"></script>
</body>
</html>