mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-12-17 16:34:17 +08:00
Deploying to gh-pages from @ ZiuChen/ZiuChen.github.io@294874351c 🚀
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{j as o,am as p,an as u,ao as l,ap as c,aq as f,ar as d,as as m,at as h,au as A,av as g,Y as v,d as P,u as _,l as y,z as w,aw as C,ax as E,ay as R,aa as b}from"./chunks/framework.BFSS5Pox.js";import{t as S}from"./chunks/theme.eZnkaVJV.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=_();return y(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),E(),R(),s.setup&&s.setup(),()=>b(s.Layout)}});async function D(){globalThis.__VITEPRESS__=!0;const e=x(),a=j();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function j(){return h(T)}function x(){let e=o,a;return A(t=>{let n=g(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=v(()=>import(n),[])),o&&(e=!1),r},s.NotFound)}o&&D().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{D as createApp};
|
||||
import{V as o,am as p,an as u,ao as l,ap as c,aq as f,ar as d,as as m,at as h,au as A,av as g,Y as v,d as P,u as _,k as y,y as w,aw as C,ax as E,ay as R,aa as b}from"./chunks/framework.DKE0jNKv.js";import{t as S}from"./chunks/theme.CuFF5wLM.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=_();return y(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),E(),R(),s.setup&&s.setup(),()=>b(s.Layout)}});async function D(){globalThis.__VITEPRESS__=!0;const e=x(),a=V();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function V(){return h(T)}function x(){let e=o,a;return A(t=>{let n=g(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=v(()=>import(n),[])),o&&(e=!1),r},s.NotFound)}o&&D().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{D as createApp};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as a,o as n,ai as i}from"./chunks/framework.BFSS5Pox.js";const u=JSON.parse('{"title":"【2023】青训营 - 前端练习题汇总解析","description":"","frontmatter":{},"headers":[],"relativePath":"article/【2023】青训营 - 前端练习题汇总解析.md","filePath":"article/【2023】青训营 - 前端练习题汇总解析.md","lastUpdated":1712924096000}'),l={name:"article/【2023】青训营 - 前端练习题汇总解析.md"},p=i(`<h1 id="【2023】青训营-前端练习题汇总解析" tabindex="-1">【2023】青训营 - 前端练习题汇总解析 <a class="header-anchor" href="#【2023】青训营-前端练习题汇总解析" aria-label="Permalink to "【2023】青训营 - 前端练习题汇总解析""></a></h1><p>汇总了青训营官方账号每天发布的练习题,并且给出了答案、做了简单解析与知识扩充,有不足之处欢迎一起交流学习。</p><p>每天的选择题不同,而编程题是一样的,直接去Leetcode刷题即可。</p><h2 id="选择题" tabindex="-1">选择题 <a class="header-anchor" href="#选择题" aria-label="Permalink to "选择题""></a></h2><h3 id="day-1" tabindex="-1">DAY 1 <a class="header-anchor" href="#day-1" aria-label="Permalink to "DAY 1""></a></h3><h4 id="题目描述" tabindex="-1">题目描述 <a class="header-anchor" href="#题目描述" aria-label="Permalink to "题目描述""></a></h4><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>选择题 1: </span></span>
|
||||
import{_ as s,c as a,o as n,ai as i}from"./chunks/framework.DKE0jNKv.js";const u=JSON.parse('{"title":"【2023】青训营 - 前端练习题汇总解析","description":"","frontmatter":{},"headers":[],"relativePath":"article/【2023】青训营 - 前端练习题汇总解析.md","filePath":"article/【2023】青训营 - 前端练习题汇总解析.md","lastUpdated":1713715656000}'),l={name:"article/【2023】青训营 - 前端练习题汇总解析.md"},p=i(`<h1 id="【2023】青训营-前端练习题汇总解析" tabindex="-1">【2023】青训营 - 前端练习题汇总解析 <a class="header-anchor" href="#【2023】青训营-前端练习题汇总解析" aria-label="Permalink to "【2023】青训营 - 前端练习题汇总解析""></a></h1><p>汇总了青训营官方账号每天发布的练习题,并且给出了答案、做了简单解析与知识扩充,有不足之处欢迎一起交流学习。</p><p>每天的选择题不同,而编程题是一样的,直接去Leetcode刷题即可。</p><h2 id="选择题" tabindex="-1">选择题 <a class="header-anchor" href="#选择题" aria-label="Permalink to "选择题""></a></h2><h3 id="day-1" tabindex="-1">DAY 1 <a class="header-anchor" href="#day-1" aria-label="Permalink to "DAY 1""></a></h3><h4 id="题目描述" tabindex="-1">题目描述 <a class="header-anchor" href="#题目描述" aria-label="Permalink to "题目描述""></a></h4><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>选择题 1: </span></span>
|
||||
<span class="line"><span>下列哪些是 HTML5 的新特性? </span></span>
|
||||
<span class="line"><span>A. 语义标签 </span></span>
|
||||
<span class="line"><span>B. Canvas 绘图 </span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as a,o as n,ai as i}from"./chunks/framework.BFSS5Pox.js";const u=JSON.parse('{"title":"【2023】青训营 - 前端练习题汇总解析","description":"","frontmatter":{},"headers":[],"relativePath":"article/【2023】青训营 - 前端练习题汇总解析.md","filePath":"article/【2023】青训营 - 前端练习题汇总解析.md","lastUpdated":1712924096000}'),l={name:"article/【2023】青训营 - 前端练习题汇总解析.md"},p=i("",150),e=[p];function t(r,h,k,d,c,o){return n(),a("div",null,e)}const g=s(l,[["render",t]]);export{u as __pageData,g as default};
|
||||
import{_ as s,c as a,o as n,ai as i}from"./chunks/framework.DKE0jNKv.js";const u=JSON.parse('{"title":"【2023】青训营 - 前端练习题汇总解析","description":"","frontmatter":{},"headers":[],"relativePath":"article/【2023】青训营 - 前端练习题汇总解析.md","filePath":"article/【2023】青训营 - 前端练习题汇总解析.md","lastUpdated":1713715656000}'),l={name:"article/【2023】青训营 - 前端练习题汇总解析.md"},p=i("",150),e=[p];function t(r,h,k,d,c,o){return n(),a("div",null,e)}const g=s(l,[["render",t]]);export{u as __pageData,g as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const o=JSON.parse('{"title":"【字节跳动】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【字节跳动】前端面试题总结.md","filePath":"article/【字节跳动】前端面试题总结.md","lastUpdated":1712924096000}'),l={name:"article/【字节跳动】前端面试题总结.md"},e=n(`<h1 id="【字节跳动】前端面试题总结" tabindex="-1">【字节跳动】前端面试题总结 <a class="header-anchor" href="#【字节跳动】前端面试题总结" aria-label="Permalink to "【字节跳动】前端面试题总结""></a></h1><h2 id="看代码说结果" tabindex="-1">看代码说结果 <a class="header-anchor" href="#看代码说结果" aria-label="Permalink to "看代码说结果""></a></h2><h3 id="代码输出结果1" tabindex="-1">代码输出结果1 <a class="header-anchor" href="#代码输出结果1" aria-label="Permalink to "代码输出结果1""></a></h3><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">([</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'1'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'2'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'3'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">].</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">map</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(parseInt))</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>[1, NaN, NaN]</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><h3 id="代码输出结果2" tabindex="-1">代码输出结果2 <a class="header-anchor" href="#代码输出结果2" aria-label="Permalink to "代码输出结果2""></a></h3><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">let</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [a </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, b] </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> []</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const o=JSON.parse('{"title":"【字节跳动】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【字节跳动】前端面试题总结.md","filePath":"article/【字节跳动】前端面试题总结.md","lastUpdated":1713715656000}'),l={name:"article/【字节跳动】前端面试题总结.md"},e=n(`<h1 id="【字节跳动】前端面试题总结" tabindex="-1">【字节跳动】前端面试题总结 <a class="header-anchor" href="#【字节跳动】前端面试题总结" aria-label="Permalink to "【字节跳动】前端面试题总结""></a></h1><h2 id="看代码说结果" tabindex="-1">看代码说结果 <a class="header-anchor" href="#看代码说结果" aria-label="Permalink to "看代码说结果""></a></h2><h3 id="代码输出结果1" tabindex="-1">代码输出结果1 <a class="header-anchor" href="#代码输出结果1" aria-label="Permalink to "代码输出结果1""></a></h3><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">([</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'1'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'2'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'3'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">].</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">map</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(parseInt))</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>[1, NaN, NaN]</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><h3 id="代码输出结果2" tabindex="-1">代码输出结果2 <a class="header-anchor" href="#代码输出结果2" aria-label="Permalink to "代码输出结果2""></a></h3><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">let</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [a </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, b] </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> []</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(a, b)</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></div></div><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>1 undefined</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><h3 id="代码输出结果3" tabindex="-1">代码输出结果3 <a class="header-anchor" href="#代码输出结果3" aria-label="Permalink to "代码输出结果3""></a></h3><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">then</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const o=JSON.parse('{"title":"【字节跳动】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【字节跳动】前端面试题总结.md","filePath":"article/【字节跳动】前端面试题总结.md","lastUpdated":1712924096000}'),l={name:"article/【字节跳动】前端面试题总结.md"},e=n("",36),h=[e];function p(t,k,r,d,E,c){return a(),i("div",null,h)}const y=s(l,[["render",p]]);export{o as __pageData,y as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const o=JSON.parse('{"title":"【字节跳动】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【字节跳动】前端面试题总结.md","filePath":"article/【字节跳动】前端面试题总结.md","lastUpdated":1713715656000}'),l={name:"article/【字节跳动】前端面试题总结.md"},e=n("",36),h=[e];function p(t,k,r,d,E,c){return a(),i("div",null,h)}const y=s(l,[["render",p]]);export{o as __pageData,y as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"【快手】深入理解前端面试题","description":"","frontmatter":{},"headers":[],"relativePath":"article/【快手】深入理解前端面试题.md","filePath":"article/【快手】深入理解前端面试题.md","lastUpdated":1712924096000}'),l={name:"article/【快手】深入理解前端面试题.md"},e=n(`<h1 id="【快手】深入理解前端面试题" tabindex="-1">【快手】深入理解前端面试题 <a class="header-anchor" href="#【快手】深入理解前端面试题" aria-label="Permalink to "【快手】深入理解前端面试题""></a></h1><h2 id="快手一面" tabindex="-1">快手一面 <a class="header-anchor" href="#快手一面" aria-label="Permalink to "快手一面""></a></h2><h3 id="vue生命周期" tabindex="-1">Vue生命周期 <a class="header-anchor" href="#vue生命周期" aria-label="Permalink to "Vue生命周期""></a></h3><p><code>beforeCreate created beforeMount mounted</code></p><p><code>beforeUpdate updated</code></p><p><code>beforeDestory destoryed</code></p><p>Vue3移除了<code>beforeCreate</code> <code>created</code>两个声明周期钩子,这是因为setup发生在开始创建组件之前,在<code>beforeCreate</code>和<code>created</code>之前执行</p><p>可以在setup中使用的生命周期函数:<code>onMounted</code> <code>onUpdated</code> <code>onUnmounted</code> <code>onBeforeUpdate</code>这几个,</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a299bd2229fb45d68a1cdd8731c94449~tplv-k3u1fbpfcp-zoom-1.image" alt="Vue 生命周期" loading="lazy"></p><h3 id="网络请求一般在什么时候发起-为什么" tabindex="-1">网络请求一般在什么时候发起,为什么 <a class="header-anchor" href="#网络请求一般在什么时候发起-为什么" aria-label="Permalink to "网络请求一般在什么时候发起,为什么""></a></h3><p>越早越好,一般是放在<code>created</code>或<code>onMounted</code>或者<code>setup</code>中</p><ul><li><code>created</code>(vue2) 此时组件内的基本数据已经创建好,组件的模板结构尚未生成</li><li><code>mounted</code>(vue2) <code>onMounted</code>(vue3) 组件挂载到DOM树上,可以获取到DOM</li><li><code>setup</code>(vue3) 时机要早于<code>beforeCreated</code>和<code>created</code> 所以在setup中发起网络请求也可以</li></ul><h3 id="setup的执行时机相当于哪个生命周期" tabindex="-1">setup的执行时机相当于哪个生命周期 <a class="header-anchor" href="#setup的执行时机相当于哪个生命周期" aria-label="Permalink to "setup的执行时机相当于哪个生命周期""></a></h3><p><code>setup</code>的执行要早于<code>beforeCreated</code>和<code>created</code>,可以认为相当于这两个生命周期</p><h3 id="vue2和vue3的响应式原理" tabindex="-1">Vue2和Vue3的响应式原理 <a class="header-anchor" href="#vue2和vue3的响应式原理" aria-label="Permalink to "Vue2和Vue3的响应式原理""></a></h3><h4 id="vue2响应式原理" tabindex="-1">Vue2响应式原理 <a class="header-anchor" href="#vue2响应式原理" aria-label="Permalink to "Vue2响应式原理""></a></h4><p>全部使用<code>Object.defineProperty()</code>中的set与get函数</p><h4 id="vue3响应式原理" tabindex="-1">Vue3响应式原理 <a class="header-anchor" href="#vue3响应式原理" aria-label="Permalink to "Vue3响应式原理""></a></h4><p><code>ref</code>使用的是<code>Object.defineProperty()</code>,而<code>reactive</code>使用的是<code>Proxy</code></p><p><code>Proxy</code>可以直接深度代理一个对象,通过设置handler中的捕获器可以对对象创建一个代理,将各种行为监听并且同步到对象本身上</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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> obj</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"【快手】深入理解前端面试题","description":"","frontmatter":{},"headers":[],"relativePath":"article/【快手】深入理解前端面试题.md","filePath":"article/【快手】深入理解前端面试题.md","lastUpdated":1713715656000}'),l={name:"article/【快手】深入理解前端面试题.md"},e=n(`<h1 id="【快手】深入理解前端面试题" tabindex="-1">【快手】深入理解前端面试题 <a class="header-anchor" href="#【快手】深入理解前端面试题" aria-label="Permalink to "【快手】深入理解前端面试题""></a></h1><h2 id="快手一面" tabindex="-1">快手一面 <a class="header-anchor" href="#快手一面" aria-label="Permalink to "快手一面""></a></h2><h3 id="vue生命周期" tabindex="-1">Vue生命周期 <a class="header-anchor" href="#vue生命周期" aria-label="Permalink to "Vue生命周期""></a></h3><p><code>beforeCreate created beforeMount mounted</code></p><p><code>beforeUpdate updated</code></p><p><code>beforeDestory destoryed</code></p><p>Vue3移除了<code>beforeCreate</code> <code>created</code>两个声明周期钩子,这是因为setup发生在开始创建组件之前,在<code>beforeCreate</code>和<code>created</code>之前执行</p><p>可以在setup中使用的生命周期函数:<code>onMounted</code> <code>onUpdated</code> <code>onUnmounted</code> <code>onBeforeUpdate</code>这几个,</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a299bd2229fb45d68a1cdd8731c94449~tplv-k3u1fbpfcp-zoom-1.image" alt="Vue 生命周期" loading="lazy"></p><h3 id="网络请求一般在什么时候发起-为什么" tabindex="-1">网络请求一般在什么时候发起,为什么 <a class="header-anchor" href="#网络请求一般在什么时候发起-为什么" aria-label="Permalink to "网络请求一般在什么时候发起,为什么""></a></h3><p>越早越好,一般是放在<code>created</code>或<code>onMounted</code>或者<code>setup</code>中</p><ul><li><code>created</code>(vue2) 此时组件内的基本数据已经创建好,组件的模板结构尚未生成</li><li><code>mounted</code>(vue2) <code>onMounted</code>(vue3) 组件挂载到DOM树上,可以获取到DOM</li><li><code>setup</code>(vue3) 时机要早于<code>beforeCreated</code>和<code>created</code> 所以在setup中发起网络请求也可以</li></ul><h3 id="setup的执行时机相当于哪个生命周期" tabindex="-1">setup的执行时机相当于哪个生命周期 <a class="header-anchor" href="#setup的执行时机相当于哪个生命周期" aria-label="Permalink to "setup的执行时机相当于哪个生命周期""></a></h3><p><code>setup</code>的执行要早于<code>beforeCreated</code>和<code>created</code>,可以认为相当于这两个生命周期</p><h3 id="vue2和vue3的响应式原理" tabindex="-1">Vue2和Vue3的响应式原理 <a class="header-anchor" href="#vue2和vue3的响应式原理" aria-label="Permalink to "Vue2和Vue3的响应式原理""></a></h3><h4 id="vue2响应式原理" tabindex="-1">Vue2响应式原理 <a class="header-anchor" href="#vue2响应式原理" aria-label="Permalink to "Vue2响应式原理""></a></h4><p>全部使用<code>Object.defineProperty()</code>中的set与get函数</p><h4 id="vue3响应式原理" tabindex="-1">Vue3响应式原理 <a class="header-anchor" href="#vue3响应式原理" aria-label="Permalink to "Vue3响应式原理""></a></h4><p><code>ref</code>使用的是<code>Object.defineProperty()</code>,而<code>reactive</code>使用的是<code>Proxy</code></p><p><code>Proxy</code>可以直接深度代理一个对象,通过设置handler中的捕获器可以对对象创建一个代理,将各种行为监听并且同步到对象本身上</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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> obj</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Ziu'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">18</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"【快手】深入理解前端面试题","description":"","frontmatter":{},"headers":[],"relativePath":"article/【快手】深入理解前端面试题.md","filePath":"article/【快手】深入理解前端面试题.md","lastUpdated":1712924096000}'),l={name:"article/【快手】深入理解前端面试题.md"},e=n("",87),p=[e];function h(t,k,r,E,d,c){return a(),i("div",null,p)}const y=s(l,[["render",h]]);export{g as __pageData,y as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"【快手】深入理解前端面试题","description":"","frontmatter":{},"headers":[],"relativePath":"article/【快手】深入理解前端面试题.md","filePath":"article/【快手】深入理解前端面试题.md","lastUpdated":1713715656000}'),l={name:"article/【快手】深入理解前端面试题.md"},e=n("",87),p=[e];function h(t,k,r,E,d,c){return a(),i("div",null,p)}const y=s(l,[["render",h]]);export{g as __pageData,y as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"【用友金融】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【用友金融】前端面试题总结.md","filePath":"article/【用友金融】前端面试题总结.md","lastUpdated":1712924096000}'),l={name:"article/【用友金融】前端面试题总结.md"},e=n(`<h1 id="【用友金融】前端面试题总结" tabindex="-1">【用友金融】前端面试题总结 <a class="header-anchor" href="#【用友金融】前端面试题总结" aria-label="Permalink to "【用友金融】前端面试题总结""></a></h1><h2 id="回流与重绘" tabindex="-1">回流与重绘 <a class="header-anchor" href="#回流与重绘" aria-label="Permalink to "回流与重绘""></a></h2><p>下列关于回流和重绘的说法错误的是</p><ul><li><p>回流的性能开销大于重绘的性能开销</p></li><li><p>当页面结构、尺寸等改变时会发生回流</p></li><li><p>回流一定会引起重绘,重绘也一定会引起回流(x)</p></li><li><p>当页面结构不改变只是样式发生改变时会发生重绘,例如背景颜色改变时会发生重绘</p></li><li><p><code>display: none</code> 指的是元素完全不陈列出来,不占据空间,涉及到了DOM结构,故产生reflow与repaint</p></li><li><p><code>visibility: hidden</code> 指的是元素不可见但存在,保留空间,不影响结构,故只产生repaint,但不可触发绑定事件</p></li><li><p><code>opacity: 0</code> 指的是元素不可见但存在,保留空间,不影响结构,并且,如果该元素已经绑定一些事件,如click事件,那么点击该区域,也能触发点击事件的</p></li></ul><h2 id="css属性" tabindex="-1">CSS属性 <a class="header-anchor" href="#css属性" aria-label="Permalink to "CSS属性""></a></h2><p>下列选项中哪个描述对于visibility: hidden;与display: none;是正确的</p><ul><li>visibility属性不可继承</li><li>visibility: hidden; 不占据页面空间</li><li>display: none; 不占据页面空间(√)</li><li>都无法通过DOM交互</li></ul><h2 id="函数执行结果" tabindex="-1">函数执行结果 <a class="header-anchor" href="#函数执行结果" aria-label="Permalink to "函数执行结果""></a></h2><h3 id="题目1" tabindex="-1">题目1 <a class="header-anchor" href="#题目1" aria-label="Permalink to "题目1""></a></h3><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () {</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"【用友金融】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【用友金融】前端面试题总结.md","filePath":"article/【用友金融】前端面试题总结.md","lastUpdated":1713715656000}'),l={name:"article/【用友金融】前端面试题总结.md"},e=n(`<h1 id="【用友金融】前端面试题总结" tabindex="-1">【用友金融】前端面试题总结 <a class="header-anchor" href="#【用友金融】前端面试题总结" aria-label="Permalink to "【用友金融】前端面试题总结""></a></h1><h2 id="回流与重绘" tabindex="-1">回流与重绘 <a class="header-anchor" href="#回流与重绘" aria-label="Permalink to "回流与重绘""></a></h2><p>下列关于回流和重绘的说法错误的是</p><ul><li><p>回流的性能开销大于重绘的性能开销</p></li><li><p>当页面结构、尺寸等改变时会发生回流</p></li><li><p>回流一定会引起重绘,重绘也一定会引起回流(x)</p></li><li><p>当页面结构不改变只是样式发生改变时会发生重绘,例如背景颜色改变时会发生重绘</p></li><li><p><code>display: none</code> 指的是元素完全不陈列出来,不占据空间,涉及到了DOM结构,故产生reflow与repaint</p></li><li><p><code>visibility: hidden</code> 指的是元素不可见但存在,保留空间,不影响结构,故只产生repaint,但不可触发绑定事件</p></li><li><p><code>opacity: 0</code> 指的是元素不可见但存在,保留空间,不影响结构,并且,如果该元素已经绑定一些事件,如click事件,那么点击该区域,也能触发点击事件的</p></li></ul><h2 id="css属性" tabindex="-1">CSS属性 <a class="header-anchor" href="#css属性" aria-label="Permalink to "CSS属性""></a></h2><p>下列选项中哪个描述对于visibility: hidden;与display: none;是正确的</p><ul><li>visibility属性不可继承</li><li>visibility: hidden; 不占据页面空间</li><li>display: none; 不占据页面空间(√)</li><li>都无法通过DOM交互</li></ul><h2 id="函数执行结果" tabindex="-1">函数执行结果 <a class="header-anchor" href="#函数执行结果" aria-label="Permalink to "函数执行结果""></a></h2><h3 id="题目1" tabindex="-1">题目1 <a class="header-anchor" href="#题目1" aria-label="Permalink to "题目1""></a></h3><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> var</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> a </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (b </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})();</span></span>
|
||||
<span class="line"></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"【用友金融】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【用友金融】前端面试题总结.md","filePath":"article/【用友金融】前端面试题总结.md","lastUpdated":1712924096000}'),l={name:"article/【用友金融】前端面试题总结.md"},e=n("",71),p=[e];function h(t,r,k,d,c,o){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{g as __pageData,b as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"【用友金融】前端面试题总结","description":"","frontmatter":{},"headers":[],"relativePath":"article/【用友金融】前端面试题总结.md","filePath":"article/【用友金融】前端面试题总结.md","lastUpdated":1713715656000}'),l={name:"article/【用友金融】前端面试题总结.md"},e=n("",71),p=[e];function h(t,r,k,d,c,o){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{g as __pageData,b as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"一文读懂事件冒泡与事件捕获","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂事件冒泡与事件捕获.md","filePath":"article/一文读懂事件冒泡与事件捕获.md","lastUpdated":1712924096000}'),n={name:"article/一文读懂事件冒泡与事件捕获.md"},t=e(`<h1 id="一文读懂事件冒泡与事件捕获" tabindex="-1">一文读懂事件冒泡与事件捕获 <a class="header-anchor" href="#一文读懂事件冒泡与事件捕获" aria-label="Permalink to "一文读懂事件冒泡与事件捕获""></a></h1><h2 id="💡-从例子入手" tabindex="-1">💡 从例子入手 <a class="header-anchor" href="#💡-从例子入手" aria-label="Permalink to "💡 从例子入手""></a></h2><p>这是一个<a href="https://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box.html" target="_blank" rel="noreferrer">简单的 Demo</a>,点击的 <code>Display video</code> 按钮后,将视频展示出来。</p><p>其中的视频 <code><video></code> 标签被 <code><div></code> 包裹,<code><div></code> 与 <code><video></code> 上都绑定了自己的 <code>click</code> 事件。</p><p><a href="https://code.juejin.cn/pen/7092947625791455262" target="_blank" rel="noreferrer">代码片段</a></p><p>我们的预期是:点击 <code><video></code> 时播放视频,点击 <code><div></code> 时隐藏视频,然而实际上你会发现,点击视频后,不仅视频虽然正常播放,但同时也被隐藏了。</p><p>点击子元素,父元素的事件也被触发,导致这种现象的原因正是:<strong>浏览器的事件冒泡机制</strong>。</p><h2 id="🤔-什么是事件冒泡机制-事件捕获又是什么" tabindex="-1">🤔 什么是事件冒泡机制?事件捕获又是什么? <a class="header-anchor" href="#🤔-什么是事件冒泡机制-事件捕获又是什么" aria-label="Permalink to "🤔 什么是事件冒泡机制?事件捕获又是什么?""></a></h2><p>现代浏览器提供了两种事件处理阶段:<strong>捕获阶段与冒泡阶段</strong>,</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/712c504b08f946088fc51dd5f8959020~tplv-k3u1fbpfcp-zoom-1.image" alt="bubbling-capturing.png" loading="lazy"></p><blockquote><p>在捕获阶段:</p><ul><li>浏览器检查元素的最外层祖先 <code><html></code> ,是否在捕获阶段中注册了一个 <code>onclick</code> 事件处理程序,如果是,则运行它。</li><li>然后,它移动到 <code><html></code> 中单击元素的下一个祖先元素,执行相同的操作,然后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。</li></ul></blockquote><blockquote><p>在冒泡阶段,与上述顺序相反:</p><ul><li>浏览器检查实际点击的元素是否在冒泡阶段中注册了一个 <code>onclick</code> 事件处理程序,如果是,则运行它</li><li>然后它移动到下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达 <code><html></code> 元素。</li></ul></blockquote><p>当一个事件被触发时,浏览器<strong>先运行捕获阶段,后运行冒泡阶段</strong>,并且在默认情况下,<strong>所有事件处理程序都在冒泡阶段进行注册</strong>。</p><p>针对上面提到的问题,我们可以知道:当 <code><video></code> 点击事件触发后,虽然我们没有主动触发 <code><div></code> 上绑定的点击事件,但由于冒泡机制,点击事件冒泡到了 <code><div></code> 上,并触发了绑定在其上的监听回调函数,将 <code><video></code> 标签隐藏。</p><h3 id="📌-用例子验证结论" tabindex="-1">📌 用例子验证结论 <a class="header-anchor" href="#📌-用例子验证结论" aria-label="Permalink to "📌 用例子验证结论""></a></h3><p>下面是一个用于验证上述结论的Demo:</p><p>页面中包括由外向内的三个类名不同的div标签: <code>div1</code> <code>div2</code> <code>div3</code>,并为他们在捕获阶段/冒泡阶段分别绑定了不同的事件函数 <code>click</code> 和 <code>dblclick</code>。</p><p><a href="https://code.juejin.cn/pen/7092975347720781861" target="_blank" rel="noreferrer">代码片段</a></p><p>当点击最内部的 <code>div3</code> 后,浏览器控制台输出:</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>> 捕获 click div1</span></span>
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"一文读懂事件冒泡与事件捕获","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂事件冒泡与事件捕获.md","filePath":"article/一文读懂事件冒泡与事件捕获.md","lastUpdated":1713715656000}'),n={name:"article/一文读懂事件冒泡与事件捕获.md"},t=e(`<h1 id="一文读懂事件冒泡与事件捕获" tabindex="-1">一文读懂事件冒泡与事件捕获 <a class="header-anchor" href="#一文读懂事件冒泡与事件捕获" aria-label="Permalink to "一文读懂事件冒泡与事件捕获""></a></h1><h2 id="💡-从例子入手" tabindex="-1">💡 从例子入手 <a class="header-anchor" href="#💡-从例子入手" aria-label="Permalink to "💡 从例子入手""></a></h2><p>这是一个<a href="https://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box.html" target="_blank" rel="noreferrer">简单的 Demo</a>,点击的 <code>Display video</code> 按钮后,将视频展示出来。</p><p>其中的视频 <code><video></code> 标签被 <code><div></code> 包裹,<code><div></code> 与 <code><video></code> 上都绑定了自己的 <code>click</code> 事件。</p><p><a href="https://code.juejin.cn/pen/7092947625791455262" target="_blank" rel="noreferrer">代码片段</a></p><p>我们的预期是:点击 <code><video></code> 时播放视频,点击 <code><div></code> 时隐藏视频,然而实际上你会发现,点击视频后,不仅视频虽然正常播放,但同时也被隐藏了。</p><p>点击子元素,父元素的事件也被触发,导致这种现象的原因正是:<strong>浏览器的事件冒泡机制</strong>。</p><h2 id="🤔-什么是事件冒泡机制-事件捕获又是什么" tabindex="-1">🤔 什么是事件冒泡机制?事件捕获又是什么? <a class="header-anchor" href="#🤔-什么是事件冒泡机制-事件捕获又是什么" aria-label="Permalink to "🤔 什么是事件冒泡机制?事件捕获又是什么?""></a></h2><p>现代浏览器提供了两种事件处理阶段:<strong>捕获阶段与冒泡阶段</strong>,</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/712c504b08f946088fc51dd5f8959020~tplv-k3u1fbpfcp-zoom-1.image" alt="bubbling-capturing.png" loading="lazy"></p><blockquote><p>在捕获阶段:</p><ul><li>浏览器检查元素的最外层祖先 <code><html></code> ,是否在捕获阶段中注册了一个 <code>onclick</code> 事件处理程序,如果是,则运行它。</li><li>然后,它移动到 <code><html></code> 中单击元素的下一个祖先元素,执行相同的操作,然后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。</li></ul></blockquote><blockquote><p>在冒泡阶段,与上述顺序相反:</p><ul><li>浏览器检查实际点击的元素是否在冒泡阶段中注册了一个 <code>onclick</code> 事件处理程序,如果是,则运行它</li><li>然后它移动到下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达 <code><html></code> 元素。</li></ul></blockquote><p>当一个事件被触发时,浏览器<strong>先运行捕获阶段,后运行冒泡阶段</strong>,并且在默认情况下,<strong>所有事件处理程序都在冒泡阶段进行注册</strong>。</p><p>针对上面提到的问题,我们可以知道:当 <code><video></code> 点击事件触发后,虽然我们没有主动触发 <code><div></code> 上绑定的点击事件,但由于冒泡机制,点击事件冒泡到了 <code><div></code> 上,并触发了绑定在其上的监听回调函数,将 <code><video></code> 标签隐藏。</p><h3 id="📌-用例子验证结论" tabindex="-1">📌 用例子验证结论 <a class="header-anchor" href="#📌-用例子验证结论" aria-label="Permalink to "📌 用例子验证结论""></a></h3><p>下面是一个用于验证上述结论的Demo:</p><p>页面中包括由外向内的三个类名不同的div标签: <code>div1</code> <code>div2</code> <code>div3</code>,并为他们在捕获阶段/冒泡阶段分别绑定了不同的事件函数 <code>click</code> 和 <code>dblclick</code>。</p><p><a href="https://code.juejin.cn/pen/7092975347720781861" target="_blank" rel="noreferrer">代码片段</a></p><p>当点击最内部的 <code>div3</code> 后,浏览器控制台输出:</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>> 捕获 click div1</span></span>
|
||||
<span class="line"><span>> 捕获 click div2</span></span>
|
||||
<span class="line"><span>> 捕获 click div3</span></span>
|
||||
<span class="line"><span>> 冒泡 click div3</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"一文读懂事件冒泡与事件捕获","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂事件冒泡与事件捕获.md","filePath":"article/一文读懂事件冒泡与事件捕获.md","lastUpdated":1712924096000}'),n={name:"article/一文读懂事件冒泡与事件捕获.md"},t=e("",63),l=[t];function p(r,h,d,k,c,o){return a(),i("div",null,l)}const u=s(n,[["render",p]]);export{g as __pageData,u as default};
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"一文读懂事件冒泡与事件捕获","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂事件冒泡与事件捕获.md","filePath":"article/一文读懂事件冒泡与事件捕获.md","lastUpdated":1713715656000}'),n={name:"article/一文读懂事件冒泡与事件捕获.md"},t=e("",63),l=[t];function p(r,h,d,k,c,o){return a(),i("div",null,l)}const u=s(n,[["render",p]]);export{g as __pageData,u as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"一文读懂伪类与伪元素","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂伪类与伪元素.md","filePath":"article/一文读懂伪类与伪元素.md","lastUpdated":1712924096000}'),l={name:"article/一文读懂伪类与伪元素.md"},e=n(`<h1 id="一文读懂伪类与伪元素" tabindex="-1">一文读懂伪类与伪元素 <a class="header-anchor" href="#一文读懂伪类与伪元素" aria-label="Permalink to "一文读懂伪类与伪元素""></a></h1><h2 id="🔰-什么是伪类" tabindex="-1">🔰 什么是伪类? <a class="header-anchor" href="#🔰-什么是伪类" aria-label="Permalink to "🔰 什么是伪类?""></a></h2><p>伪类是添加到选择器的 <strong>关键字</strong> ,指定要选择的元素的特殊状态。</p><h3 id="典型的伪类关键字" tabindex="-1">典型的伪类关键字 <a class="header-anchor" href="#典型的伪类关键字" aria-label="Permalink to "典型的伪类关键字""></a></h3><p>在大多数情况下,<strong>伪类都与基础选择器搭配使用</strong>,下述是伪类在一些典型场景下的应用。</p><h4 id="hover" tabindex="-1"><code>:hover</code> <a class="header-anchor" href="#hover" aria-label="Permalink to "\`:hover\`""></a></h4><p>指针在 <code><button></code> 上悬停,但没有激活它时,按钮颜色变为蓝色</p><div class="language-css vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">button</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">:hover</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"一文读懂伪类与伪元素","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂伪类与伪元素.md","filePath":"article/一文读懂伪类与伪元素.md","lastUpdated":1713715656000}'),l={name:"article/一文读懂伪类与伪元素.md"},e=n(`<h1 id="一文读懂伪类与伪元素" tabindex="-1">一文读懂伪类与伪元素 <a class="header-anchor" href="#一文读懂伪类与伪元素" aria-label="Permalink to "一文读懂伪类与伪元素""></a></h1><h2 id="🔰-什么是伪类" tabindex="-1">🔰 什么是伪类? <a class="header-anchor" href="#🔰-什么是伪类" aria-label="Permalink to "🔰 什么是伪类?""></a></h2><p>伪类是添加到选择器的 <strong>关键字</strong> ,指定要选择的元素的特殊状态。</p><h3 id="典型的伪类关键字" tabindex="-1">典型的伪类关键字 <a class="header-anchor" href="#典型的伪类关键字" aria-label="Permalink to "典型的伪类关键字""></a></h3><p>在大多数情况下,<strong>伪类都与基础选择器搭配使用</strong>,下述是伪类在一些典型场景下的应用。</p><h4 id="hover" tabindex="-1"><code>:hover</code> <a class="header-anchor" href="#hover" aria-label="Permalink to "\`:hover\`""></a></h4><p>指针在 <code><button></code> 上悬停,但没有激活它时,按钮颜色变为蓝色</p><div class="language-css vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">button</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">:hover</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> color</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">blue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div><blockquote><p><strong>注意</strong>: 在触摸屏上 <code>:hover</code> 基本不可用。不同的浏览器上<code>:hover</code> 伪类表现不同。网页开发人员不要让任何内容只能通过悬停才能展示出来,不然这些内容对于触摸屏使用者来说是很难或者说不可能看到。</p></blockquote><h4 id="not" tabindex="-1"><code>:not</code> <a class="header-anchor" href="#not" aria-label="Permalink to "\`:not\`""></a></h4><p><strong><code>:not()</code></strong> 用来匹配不符合一组选择器的元素。由于它的作用是防止特定的元素被选中,它也被称为<em>反选伪类</em>(<em>negation pseudo-class</em>)。</p><p>将所有不是<code><p></code>的元素颜色改为蓝色:</p><div class="language-css vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">body</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">:not</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">p</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> color</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">blue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"一文读懂伪类与伪元素","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂伪类与伪元素.md","filePath":"article/一文读懂伪类与伪元素.md","lastUpdated":1712924096000}'),l={name:"article/一文读懂伪类与伪元素.md"},e=n("",56),p=[e];function h(t,k,r,d,c,E){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{g as __pageData,b as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"一文读懂伪类与伪元素","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂伪类与伪元素.md","filePath":"article/一文读懂伪类与伪元素.md","lastUpdated":1713715656000}'),l={name:"article/一文读懂伪类与伪元素.md"},e=n("",56),p=[e];function h(t,k,r,d,c,E){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{g as __pageData,b as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as n,o as a,ai as p}from"./chunks/framework.BFSS5Pox.js";const h=JSON.parse('{"title":"一文读懂函数中this指向问题","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂函数中this指向问题.md","filePath":"article/一文读懂函数中this指向问题.md","lastUpdated":1712924096000}'),e={name:"article/一文读懂函数中this指向问题.md"},l=p(`<h1 id="一文读懂函数中this指向问题" tabindex="-1">一文读懂函数中this指向问题 <a class="header-anchor" href="#一文读懂函数中this指向问题" aria-label="Permalink to "一文读懂函数中this指向问题""></a></h1><h2 id="函数中this指向" tabindex="-1">函数中this指向 <a class="header-anchor" href="#函数中this指向" aria-label="Permalink to "函数中this指向""></a></h2><p>函数在调用时, Javascript会默认为this绑定一个值</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>// 定义一个函数</span></span>
|
||||
import{_ as s,c as n,o as a,ai as p}from"./chunks/framework.DKE0jNKv.js";const h=JSON.parse('{"title":"一文读懂函数中this指向问题","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂函数中this指向问题.md","filePath":"article/一文读懂函数中this指向问题.md","lastUpdated":1713715656000}'),e={name:"article/一文读懂函数中this指向问题.md"},l=p(`<h1 id="一文读懂函数中this指向问题" tabindex="-1">一文读懂函数中this指向问题 <a class="header-anchor" href="#一文读懂函数中this指向问题" aria-label="Permalink to "一文读懂函数中this指向问题""></a></h1><h2 id="函数中this指向" tabindex="-1">函数中this指向 <a class="header-anchor" href="#函数中this指向" aria-label="Permalink to "函数中this指向""></a></h2><p>函数在调用时, Javascript会默认为this绑定一个值</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span>// 定义一个函数</span></span>
|
||||
<span class="line"><span>function foo() {</span></span>
|
||||
<span class="line"><span> console.log(this)</span></span>
|
||||
<span class="line"><span>}</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as n,o as a,ai as p}from"./chunks/framework.BFSS5Pox.js";const h=JSON.parse('{"title":"一文读懂函数中this指向问题","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂函数中this指向问题.md","filePath":"article/一文读懂函数中this指向问题.md","lastUpdated":1712924096000}'),e={name:"article/一文读懂函数中this指向问题.md"},l=p("",59),i=[l];function c(r,o,b,t,d,u){return a(),n("div",null,i)}const g=s(e,[["render",c]]);export{h as __pageData,g as default};
|
||||
import{_ as s,c as n,o as a,ai as p}from"./chunks/framework.DKE0jNKv.js";const h=JSON.parse('{"title":"一文读懂函数中this指向问题","description":"","frontmatter":{},"headers":[],"relativePath":"article/一文读懂函数中this指向问题.md","filePath":"article/一文读懂函数中this指向问题.md","lastUpdated":1713715656000}'),e={name:"article/一文读懂函数中this指向问题.md"},l=p("",59),i=[l];function c(r,o,b,t,d,u){return a(),n("div",null,i)}const g=s(e,[["render",c]]);export{h as __pageData,g as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const y=JSON.parse('{"title":"从0实现一个年度报告","description":"","frontmatter":{},"headers":[],"relativePath":"article/从0实现一个年度报告.md","filePath":"article/从0实现一个年度报告.md","lastUpdated":1712924096000}'),l={name:"article/从0实现一个年度报告.md"},h=n(`<h1 id="从0实现一个年度报告" tabindex="-1">从0实现一个年度报告 <a class="header-anchor" href="#从0实现一个年度报告" aria-label="Permalink to "从0实现一个年度报告""></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 "实现难点""></a></h2><h3 id="_1-数据模拟" tabindex="-1">1. 数据模拟 <a class="header-anchor" href="#_1-数据模拟" aria-label="Permalink to "1. 数据模拟""></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 "2. 屏幕适配""></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 "3. 动画效果""></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 "4. 音乐播放""></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 "用户数据""></a></h2><h3 id="用户数据内容" tabindex="-1">用户数据内容 <a class="header-anchor" href="#用户数据内容" aria-label="Permalink to "用户数据内容""></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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span>- 用户名</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const y=JSON.parse('{"title":"从0实现一个年度报告","description":"","frontmatter":{},"headers":[],"relativePath":"article/从0实现一个年度报告.md","filePath":"article/从0实现一个年度报告.md","lastUpdated":1713715656000}'),l={name:"article/从0实现一个年度报告.md"},h=n(`<h1 id="从0实现一个年度报告" tabindex="-1">从0实现一个年度报告 <a class="header-anchor" href="#从0实现一个年度报告" aria-label="Permalink to "从0实现一个年度报告""></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 "实现难点""></a></h2><h3 id="_1-数据模拟" tabindex="-1">1. 数据模拟 <a class="header-anchor" href="#_1-数据模拟" aria-label="Permalink to "1. 数据模拟""></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 "2. 屏幕适配""></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 "3. 动画效果""></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 "4. 音乐播放""></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 "用户数据""></a></h2><h3 id="用户数据内容" tabindex="-1">用户数据内容 <a class="header-anchor" href="#用户数据内容" aria-label="Permalink to "用户数据内容""></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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span>- 用户名</span></span>
|
||||
<span class="line"><span>- 注册时间 距今天数</span></span>
|
||||
<span class="line"><span>- 创作相关</span></span>
|
||||
<span class="line"><span> - 发布文章数</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const y=JSON.parse('{"title":"从0实现一个年度报告","description":"","frontmatter":{},"headers":[],"relativePath":"article/从0实现一个年度报告.md","filePath":"article/从0实现一个年度报告.md","lastUpdated":1712924096000}'),l={name:"article/从0实现一个年度报告.md"},h=n("",59),p=[h];function t(k,e,E,r,d,g){return a(),i("div",null,p)}const F=s(l,[["render",t]]);export{y as __pageData,F as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const y=JSON.parse('{"title":"从0实现一个年度报告","description":"","frontmatter":{},"headers":[],"relativePath":"article/从0实现一个年度报告.md","filePath":"article/从0实现一个年度报告.md","lastUpdated":1713715656000}'),l={name:"article/从0实现一个年度报告.md"},h=n("",59),p=[h];function t(k,e,E,r,d,g){return a(),i("div",null,p)}const F=s(l,[["render",t]]);export{y as __pageData,F as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const o=JSON.parse('{"title":"彻底搞懂对象的数据属性描述符、存储属性描述符","description":"","frontmatter":{},"headers":[],"relativePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","filePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","lastUpdated":1712924096000}'),l={name:"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md"},e=n(`<h1 id="彻底搞懂对象的数据属性描述符、存储属性描述符" tabindex="-1">彻底搞懂对象的数据属性描述符、存储属性描述符 <a class="header-anchor" href="#彻底搞懂对象的数据属性描述符、存储属性描述符" aria-label="Permalink to "彻底搞懂对象的数据属性描述符、存储属性描述符""></a></h1><h2 id="属性描述符" tabindex="-1">属性描述符 <a class="header-anchor" href="#属性描述符" aria-label="Permalink to "属性描述符""></a></h2><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> let</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> obj </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const o=JSON.parse('{"title":"彻底搞懂对象的数据属性描述符、存储属性描述符","description":"","frontmatter":{},"headers":[],"relativePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","filePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","lastUpdated":1713715656000}'),l={name:"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md"},e=n(`<h1 id="彻底搞懂对象的数据属性描述符、存储属性描述符" tabindex="-1">彻底搞懂对象的数据属性描述符、存储属性描述符 <a class="header-anchor" href="#彻底搞懂对象的数据属性描述符、存储属性描述符" aria-label="Permalink to "彻底搞懂对象的数据属性描述符、存储属性描述符""></a></h1><h2 id="属性描述符" tabindex="-1">属性描述符 <a class="header-anchor" href="#属性描述符" aria-label="Permalink to "属性描述符""></a></h2><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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> let</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> obj </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"ziu"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">18</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const o=JSON.parse('{"title":"彻底搞懂对象的数据属性描述符、存储属性描述符","description":"","frontmatter":{},"headers":[],"relativePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","filePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","lastUpdated":1712924096000}'),l={name:"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md"},e=n("",18),p=[e];function h(t,k,r,E,d,c){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{o as __pageData,b as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const o=JSON.parse('{"title":"彻底搞懂对象的数据属性描述符、存储属性描述符","description":"","frontmatter":{},"headers":[],"relativePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","filePath":"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md","lastUpdated":1713715656000}'),l={name:"article/彻底搞懂对象的数据属性描述符、存储属性描述符.md"},e=n("",18),p=[e];function h(t,k,r,E,d,c){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{o as __pageData,b as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"浅析defineProperty与Proxy实现的双向绑定","description":"","frontmatter":{},"headers":[],"relativePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","filePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","lastUpdated":1712924096000}'),n={name:"article/浅析defineProperty与Proxy实现的双向绑定.md"},t=e(`<h1 id="浅析defineproperty与proxy实现的双向绑定" tabindex="-1">浅析defineProperty与Proxy实现的双向绑定 <a class="header-anchor" href="#浅析defineproperty与proxy实现的双向绑定" aria-label="Permalink to "浅析defineProperty与Proxy实现的双向绑定""></a></h1><blockquote><p>文章内容总结自Vue官网 <a href="https://cn.vuejs.org/v2/guide/reactivity.html#%E5%A6%82%E4%BD%95%E8%BF%BD%E8%B8%AA%E5%8F%98%E5%8C%96" target="_blank" rel="noreferrer">深入响应式原理</a></p></blockquote><h2 id="🔰-vue2的响应式原理" tabindex="-1">🔰 Vue2的响应式原理 <a class="header-anchor" href="#🔰-vue2的响应式原理" aria-label="Permalink to "🔰 Vue2的响应式原理""></a></h2><p><img src="https://v2.cn.vuejs.org/images/data.png" alt="image.png" loading="lazy"></p><blockquote><p>当你把一个普通的 JavaScript 对象传入 Vue 实例作为 <code>data</code> 选项,Vue 将遍历此对象所有的 property,并使用 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty" target="_blank" rel="noreferrer"><code>Object.defineProperty</code></a> 把这些 property 全部转为 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects#%E5%AE%9A%E4%B9%89_getters_%E4%B8%8E_setters" target="_blank" rel="noreferrer">getter/setter</a>。</p><p>每个组件实例都对应一个 <strong>watcher</strong> 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。</p></blockquote><p>Vue2的响应式原理,利用的是 <code>Object.defineProperty()</code> 的 <code>setter</code> 属性:</p><p><code>defineProperty()</code> 方法用于<strong>精确</strong>定义一个对象的属性,能够指定属性的各种特征,其中的 <code>set</code> 属性能够为对象指定一个 <code>setter</code> 函数,每次该属性的值发生修改,就会调用此函数。</p><blockquote><p>更多可以配置的属性请参看:<a href="https://juejin.cn/post/7088335075061792782" target="_blank" rel="noreferrer">什么是对象的数据属性描述符?存储属性描述符?</a></p></blockquote><p>这也是Vue2实现响应式数据、数据双向绑定的原理。</p><p>可以使用此方法实现一个简单的数据双向绑定的Demo:</p><p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f241135dbeb04e829fe6897c2e418aa2~tplv-k3u1fbpfcp-watermark.image?" alt="image.png" loading="lazy"></p><ul><li>输入框内的内容改变,<code>.vBox</code> 展示的文本会随之改变。</li><li>点击按钮修改 <code>vm.text</code>,输入框内的值和 <code>.vBox</code> 的文本都会发生改变。</li></ul><div class="language-html vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"浅析defineProperty与Proxy实现的双向绑定","description":"","frontmatter":{},"headers":[],"relativePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","filePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","lastUpdated":1713715656000}'),n={name:"article/浅析defineProperty与Proxy实现的双向绑定.md"},t=e(`<h1 id="浅析defineproperty与proxy实现的双向绑定" tabindex="-1">浅析defineProperty与Proxy实现的双向绑定 <a class="header-anchor" href="#浅析defineproperty与proxy实现的双向绑定" aria-label="Permalink to "浅析defineProperty与Proxy实现的双向绑定""></a></h1><blockquote><p>文章内容总结自Vue官网 <a href="https://cn.vuejs.org/v2/guide/reactivity.html#%E5%A6%82%E4%BD%95%E8%BF%BD%E8%B8%AA%E5%8F%98%E5%8C%96" target="_blank" rel="noreferrer">深入响应式原理</a></p></blockquote><h2 id="🔰-vue2的响应式原理" tabindex="-1">🔰 Vue2的响应式原理 <a class="header-anchor" href="#🔰-vue2的响应式原理" aria-label="Permalink to "🔰 Vue2的响应式原理""></a></h2><p><img src="https://v2.cn.vuejs.org/images/data.png" alt="image.png" loading="lazy"></p><blockquote><p>当你把一个普通的 JavaScript 对象传入 Vue 实例作为 <code>data</code> 选项,Vue 将遍历此对象所有的 property,并使用 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty" target="_blank" rel="noreferrer"><code>Object.defineProperty</code></a> 把这些 property 全部转为 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects#%E5%AE%9A%E4%B9%89_getters_%E4%B8%8E_setters" target="_blank" rel="noreferrer">getter/setter</a>。</p><p>每个组件实例都对应一个 <strong>watcher</strong> 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。</p></blockquote><p>Vue2的响应式原理,利用的是 <code>Object.defineProperty()</code> 的 <code>setter</code> 属性:</p><p><code>defineProperty()</code> 方法用于<strong>精确</strong>定义一个对象的属性,能够指定属性的各种特征,其中的 <code>set</code> 属性能够为对象指定一个 <code>setter</code> 函数,每次该属性的值发生修改,就会调用此函数。</p><blockquote><p>更多可以配置的属性请参看:<a href="https://juejin.cn/post/7088335075061792782" target="_blank" rel="noreferrer">什么是对象的数据属性描述符?存储属性描述符?</a></p></blockquote><p>这也是Vue2实现响应式数据、数据双向绑定的原理。</p><p>可以使用此方法实现一个简单的数据双向绑定的Demo:</p><p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f241135dbeb04e829fe6897c2e418aa2~tplv-k3u1fbpfcp-watermark.image?" alt="image.png" loading="lazy"></p><ul><li>输入框内的内容改变,<code>.vBox</code> 展示的文本会随之改变。</li><li>点击按钮修改 <code>vm.text</code>,输入框内的值和 <code>.vBox</code> 的文本都会发生改变。</li></ul><div class="language-html vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">input</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"text"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"input"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">button</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onclick</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">vm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">text</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Hello, World.'"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">>Modify vm.text</</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">button</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> class</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"vBox"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.BFSS5Pox.js";const g=JSON.parse('{"title":"浅析defineProperty与Proxy实现的双向绑定","description":"","frontmatter":{},"headers":[],"relativePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","filePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","lastUpdated":1712924096000}'),n={name:"article/浅析defineProperty与Proxy实现的双向绑定.md"},t=e("",20),p=[t];function l(h,r,k,E,d,o){return a(),i("div",null,p)}const y=s(n,[["render",l]]);export{g as __pageData,y as default};
|
||||
import{_ as s,c as i,o as a,ai as e}from"./chunks/framework.DKE0jNKv.js";const g=JSON.parse('{"title":"浅析defineProperty与Proxy实现的双向绑定","description":"","frontmatter":{},"headers":[],"relativePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","filePath":"article/浅析defineProperty与Proxy实现的双向绑定.md","lastUpdated":1713715656000}'),n={name:"article/浅析defineProperty与Proxy实现的双向绑定.md"},t=e("",20),p=[t];function l(h,r,k,E,d,o){return a(),i("div",null,p)}const y=s(n,[["render",l]]);export{g as __pageData,y as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const t="/assets/Object.prototype.toString.CjFLIGI9.png",y=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入JavaScript数据类型.md","filePath":"article/深入JavaScript数据类型.md","lastUpdated":1712924096000}'),l={name:"article/深入JavaScript数据类型.md"},e=n(`<h2 id="深入javascript数据类型" tabindex="-1">深入JavaScript数据类型 <a class="header-anchor" href="#深入javascript数据类型" aria-label="Permalink to "深入JavaScript数据类型""></a></h2><p>JavaScript包含以下几种数据类型:</p><ul><li>Number 数字</li><li>String 字符串</li><li>Boolean 布尔值</li><li>Symbol 符号 (ES6新增)</li><li>Object 对象 <ul><li>Function 函数</li><li>Array 数组</li><li>Date 日期</li><li>RegExp 正则表达式</li><li>...</li></ul></li><li>null 空</li><li>undefined 未定义</li></ul><p>从语言底层值的可变与不可变,可以将JS中的数据分为两种:不可变值(原始类型)和可变值(引用类型)</p><p>除了Object及继承自Object的特殊对象,其他的类型都为<strong>原始类型</strong>。</p><h2 id="typeof运算符" tabindex="-1">typeof运算符 <a class="header-anchor" href="#typeof运算符" aria-label="Permalink to "typeof运算符""></a></h2><p>除了null,所有<strong>原始类型</strong>都可以通过<code>typeof</code>运算符得到不同的结果</p><p>而null与object通过<code>typeof</code>运算符得到的结果都为<code>'object'</code></p><div class="language-javascript vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 除了 null 其他原始类型的变量都可以通过 typeof 得到其类型</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const t="/assets/Object.prototype.toString.CjFLIGI9.png",y=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入JavaScript数据类型.md","filePath":"article/深入JavaScript数据类型.md","lastUpdated":1713715656000}'),l={name:"article/深入JavaScript数据类型.md"},e=n(`<h2 id="深入javascript数据类型" tabindex="-1">深入JavaScript数据类型 <a class="header-anchor" href="#深入javascript数据类型" aria-label="Permalink to "深入JavaScript数据类型""></a></h2><p>JavaScript包含以下几种数据类型:</p><ul><li>Number 数字</li><li>String 字符串</li><li>Boolean 布尔值</li><li>Symbol 符号 (ES6新增)</li><li>Object 对象 <ul><li>Function 函数</li><li>Array 数组</li><li>Date 日期</li><li>RegExp 正则表达式</li><li>...</li></ul></li><li>null 空</li><li>undefined 未定义</li></ul><p>从语言底层值的可变与不可变,可以将JS中的数据分为两种:不可变值(原始类型)和可变值(引用类型)</p><p>除了Object及继承自Object的特殊对象,其他的类型都为<strong>原始类型</strong>。</p><h2 id="typeof运算符" tabindex="-1">typeof运算符 <a class="header-anchor" href="#typeof运算符" aria-label="Permalink to "typeof运算符""></a></h2><p>除了null,所有<strong>原始类型</strong>都可以通过<code>typeof</code>运算符得到不同的结果</p><p>而null与object通过<code>typeof</code>运算符得到的结果都为<code>'object'</code></p><div class="language-javascript vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 除了 null 其他原始类型的变量都可以通过 typeof 得到其类型</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 而 null 与 object 通过 typeof 运算得到的都是 'object'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> targets</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">18</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Ziu'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Symbol</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">), {}, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">null</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">undefined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
|
||||
<span class="line"></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const t="/assets/Object.prototype.toString.CjFLIGI9.png",y=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入JavaScript数据类型.md","filePath":"article/深入JavaScript数据类型.md","lastUpdated":1712924096000}'),l={name:"article/深入JavaScript数据类型.md"},e=n("",46),p=[e];function h(k,r,o,d,c,E){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{y as __pageData,b as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const t="/assets/Object.prototype.toString.CjFLIGI9.png",y=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入JavaScript数据类型.md","filePath":"article/深入JavaScript数据类型.md","lastUpdated":1713715656000}'),l={name:"article/深入JavaScript数据类型.md"},e=n("",46),p=[e];function h(k,r,o,d,c,E){return a(),i("div",null,p)}const b=s(l,[["render",h]]);export{y as __pageData,b as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const u=JSON.parse('{"title":"深入Vue3源码,看看Vue.use后究竟发生了什么?","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","filePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","lastUpdated":1712924096000}'),p={name:"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md"},l=n(`<h1 id="深入vue3源码-看看vue-use后究竟发生了什么" tabindex="-1">深入Vue3源码,看看Vue.use后究竟发生了什么? <a class="header-anchor" href="#深入vue3源码-看看vue-use后究竟发生了什么" aria-label="Permalink to "深入Vue3源码,看看Vue.use后究竟发生了什么?""></a></h1><h2 id="从全局注册组件库入手" tabindex="-1">从全局注册组件库入手 <a class="header-anchor" href="#从全局注册组件库入手" aria-label="Permalink to "从全局注册组件库入手""></a></h2><p>如果我们自定义了几个自定义组件,当我们想在<code>.vue</code>文件中使用它们时,需要手动<code>import</code>导入组件并在<code>component</code>中注册:</p><div class="language-html vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const u=JSON.parse('{"title":"深入Vue3源码,看看Vue.use后究竟发生了什么?","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","filePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","lastUpdated":1713715656000}'),p={name:"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md"},l=n(`<h1 id="深入vue3源码-看看vue-use后究竟发生了什么" tabindex="-1">深入Vue3源码,看看Vue.use后究竟发生了什么? <a class="header-anchor" href="#深入vue3源码-看看vue-use后究竟发生了什么" aria-label="Permalink to "深入Vue3源码,看看Vue.use后究竟发生了什么?""></a></h1><h2 id="从全局注册组件库入手" tabindex="-1">从全局注册组件库入手 <a class="header-anchor" href="#从全局注册组件库入手" aria-label="Permalink to "从全局注册组件库入手""></a></h2><p>如果我们自定义了几个自定义组件,当我们想在<code>.vue</code>文件中使用它们时,需要手动<code>import</code>导入组件并在<code>component</code>中注册:</p><div class="language-html vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CustomInput </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@/component/CustomInput.vue'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const u=JSON.parse('{"title":"深入Vue3源码,看看Vue.use后究竟发生了什么?","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","filePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","lastUpdated":1712924096000}'),p={name:"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md"},l=n("",26),e=[l];function h(t,k,r,E,d,c){return a(),i("div",null,e)}const y=s(p,[["render",h]]);export{u as __pageData,y as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const u=JSON.parse('{"title":"深入Vue3源码,看看Vue.use后究竟发生了什么?","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","filePath":"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md","lastUpdated":1713715656000}'),p={name:"article/深入Vue3源码,看看Vue.use后究竟发生了什么?.md"},l=n("",26),e=[l];function h(t,k,r,E,d,c){return a(),i("div",null,e)}const y=s(p,[["render",h]]);export{u as __pageData,y as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const c=JSON.parse('{"title":"深入理解Proxy与Reflect","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解Proxy与Reflect.md","filePath":"article/深入理解Proxy与Reflect.md","lastUpdated":1712924096000}'),l={name:"article/深入理解Proxy与Reflect.md"},p=n(`<h1 id="深入理解proxy与reflect" tabindex="-1">深入理解Proxy与Reflect <a class="header-anchor" href="#深入理解proxy与reflect" aria-label="Permalink to "深入理解Proxy与Reflect""></a></h1><h3 id="监听对象的操作" tabindex="-1">监听对象的操作 <a class="header-anchor" href="#监听对象的操作" aria-label="Permalink to "监听对象的操作""></a></h3><p>可以使用Proxy对象将原对象包裹,此后的操作都对<code>proxy</code>进行,每次<code>get</code>与<code>set</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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> obj</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const c=JSON.parse('{"title":"深入理解Proxy与Reflect","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解Proxy与Reflect.md","filePath":"article/深入理解Proxy与Reflect.md","lastUpdated":1713715656000}'),l={name:"article/深入理解Proxy与Reflect.md"},p=n(`<h1 id="深入理解proxy与reflect" tabindex="-1">深入理解Proxy与Reflect <a class="header-anchor" href="#深入理解proxy与reflect" aria-label="Permalink to "深入理解Proxy与Reflect""></a></h1><h3 id="监听对象的操作" tabindex="-1">监听对象的操作 <a class="header-anchor" href="#监听对象的操作" aria-label="Permalink to "监听对象的操作""></a></h3><p>可以使用Proxy对象将原对象包裹,此后的操作都对<code>proxy</code>进行,每次<code>get</code>与<code>set</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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> obj</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'ziu'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">18</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> height: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1.88</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const c=JSON.parse('{"title":"深入理解Proxy与Reflect","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解Proxy与Reflect.md","filePath":"article/深入理解Proxy与Reflect.md","lastUpdated":1712924096000}'),l={name:"article/深入理解Proxy与Reflect.md"},p=n("",44),e=[p];function h(k,t,r,E,d,g){return a(),i("div",null,e)}const F=s(l,[["render",h]]);export{c as __pageData,F as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const c=JSON.parse('{"title":"深入理解Proxy与Reflect","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解Proxy与Reflect.md","filePath":"article/深入理解Proxy与Reflect.md","lastUpdated":1713715656000}'),l={name:"article/深入理解Proxy与Reflect.md"},p=n("",44),e=[p];function h(k,t,r,E,d,g){return a(),i("div",null,e)}const F=s(l,[["render",h]]);export{c as __pageData,F as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{_ as e,c as a,o as i,ai as s}from"./chunks/framework.BFSS5Pox.js";const u=JSON.parse('{"title":"深入理解浏览器缓存机制","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解浏览器缓存机制.md","filePath":"article/深入理解浏览器缓存机制.md","lastUpdated":1712924096000}'),l={name:"article/深入理解浏览器缓存机制.md"},t=s("",66),d=[t];function o(n,r,c,p,h,k){return i(),a("div",null,d)}const b=e(l,[["render",o]]);export{u as __pageData,b as default};
|
||||
import{_ as e,c as a,o as i,ai as s}from"./chunks/framework.DKE0jNKv.js";const u=JSON.parse('{"title":"深入理解浏览器缓存机制","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解浏览器缓存机制.md","filePath":"article/深入理解浏览器缓存机制.md","lastUpdated":1713715656000}'),l={name:"article/深入理解浏览器缓存机制.md"},t=s("",66),d=[t];function o(n,r,c,p,h,k){return i(),a("div",null,d)}const b=e(l,[["render",o]]);export{u as __pageData,b as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{_ as a,c as s,o as n,ai as e}from"./chunks/framework.BFSS5Pox.js";const m=JSON.parse('{"title":"深入理解浏览器运行原理","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解浏览器运行原理.md","filePath":"article/深入理解浏览器运行原理.md","lastUpdated":1712924096000}'),p={name:"article/深入理解浏览器运行原理.md"},l=e("",87),i=[l];function r(t,c,o,d,b,u){return n(),s("div",null,i)}const g=a(p,[["render",r]]);export{m as __pageData,g as default};
|
||||
import{_ as a,c as s,o as n,ai as e}from"./chunks/framework.DKE0jNKv.js";const m=JSON.parse('{"title":"深入理解浏览器运行原理","description":"","frontmatter":{},"headers":[],"relativePath":"article/深入理解浏览器运行原理.md","filePath":"article/深入理解浏览器运行原理.md","lastUpdated":1713715656000}'),p={name:"article/深入理解浏览器运行原理.md"},l=e("",87),i=[l];function r(t,c,o,d,b,u){return n(),s("div",null,i)}const g=a(p,[["render",r]]);export{m as __pageData,g as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
17
assets/chunks/framework.DKE0jNKv.js
Normal file
17
assets/chunks/framework.DKE0jNKv.js
Normal file
File diff suppressed because one or more lines are too long
120
assets/chunks/theme.CuFF5wLM.js
Normal file
120
assets/chunks/theme.CuFF5wLM.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{d as f,h as l,l as _,o as c,c as d,m as o,q as u,s as h,_ as g,J as y,a as v}from"./chunks/framework.BFSS5Pox.js";function x(e){window.addEventListener("message",async s=>{var i;const a=s.data,n=a.namespace,m=a.action,r=(i=t==null?void 0:t[n])==null?void 0:i[m];if(r){const p=await r(a.payload);e.postMessage({params:a,result:p},"*")}})}const t={user:{getUserToken:({userId:e})=>"token:"+e}},P=e=>(u("data-v-6e7a6b64"),e=e(),h(),e),b={class:"home"},k=P(()=>o("h2",null,"Home",-1)),w=f({__name:"Index",setup(e){const s=l(null);return _(()=>{s.value&&s.value.contentWindow&&x(s.value.contentWindow)}),(a,n)=>(c(),d("div",b,[k,o("iframe",{ref_key:"iframeRef",ref:s,src:"/demos/promiseify-post-message/inner",frameborder:"0"},null,512)]))}}),I=g(w,[["__scopeId","data-v-6e7a6b64"]]),M=o("h1",{id:"promiseify-postmessage",tabindex:"-1"},[v("Promiseify PostMessage "),o("a",{class:"header-anchor",href:"#promiseify-postmessage","aria-label":'Permalink to "Promiseify PostMessage"'},"")],-1),B=o("p",null,"将 postMessage 消息通信 Promise 化",-1),V=JSON.parse('{"title":"Promiseify PostMessage","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false},"headers":[],"relativePath":"demos/promiseify-post-message/index.md","filePath":"demos/promiseify-post-message/index.md","lastUpdated":1712924096000}'),N={name:"demos/promiseify-post-message/index.md"},$=Object.assign(N,{setup(e){return(s,a)=>(c(),d("div",null,[M,B,y(I)]))}});export{V as __pageData,$ as default};
|
||||
import{d as f,j as l,k as _,o as c,c as d,l as o,p as u,q as g,_ as h,I as y,a as v}from"./chunks/framework.DKE0jNKv.js";function x(e){window.addEventListener("message",async s=>{var i;const a=s.data,n=a.namespace,m=a.action,r=(i=t==null?void 0:t[n])==null?void 0:i[m];if(r){const p=await r(a.payload);e.postMessage({params:a,result:p},"*")}})}const t={user:{getUserToken:({userId:e})=>"token:"+e}},P=e=>(u("data-v-6e7a6b64"),e=e(),g(),e),b={class:"home"},k=P(()=>o("h2",null,"Home",-1)),w=f({__name:"Index",setup(e){const s=l(null);return _(()=>{s.value&&s.value.contentWindow&&x(s.value.contentWindow)}),(a,n)=>(c(),d("div",b,[k,o("iframe",{ref_key:"iframeRef",ref:s,src:"/demos/promiseify-post-message/inner",frameborder:"0"},null,512)]))}}),I=h(w,[["__scopeId","data-v-6e7a6b64"]]),M=o("h1",{id:"promiseify-postmessage",tabindex:"-1"},[v("Promiseify PostMessage "),o("a",{class:"header-anchor",href:"#promiseify-postmessage","aria-label":'Permalink to "Promiseify PostMessage"'},"")],-1),B=o("p",null,"将 postMessage 消息通信 Promise 化",-1),V=JSON.parse('{"title":"Promiseify PostMessage","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false},"headers":[],"relativePath":"demos/promiseify-post-message/index.md","filePath":"demos/promiseify-post-message/index.md","lastUpdated":1713715656000}'),N={name:"demos/promiseify-post-message/index.md"},$=Object.assign(N,{setup(e){return(s,a)=>(c(),d("div",null,[M,B,y(I)]))}});export{V as __pageData,$ as default};
|
||||
@@ -1 +1 @@
|
||||
import{d as f,h as l,l as _,o as c,c as d,m as o,q as u,s as h,_ as g,J as y,a as v}from"./chunks/framework.BFSS5Pox.js";function x(e){window.addEventListener("message",async s=>{var i;const a=s.data,n=a.namespace,m=a.action,r=(i=t==null?void 0:t[n])==null?void 0:i[m];if(r){const p=await r(a.payload);e.postMessage({params:a,result:p},"*")}})}const t={user:{getUserToken:({userId:e})=>"token:"+e}},P=e=>(u("data-v-6e7a6b64"),e=e(),h(),e),b={class:"home"},k=P(()=>o("h2",null,"Home",-1)),w=f({__name:"Index",setup(e){const s=l(null);return _(()=>{s.value&&s.value.contentWindow&&x(s.value.contentWindow)}),(a,n)=>(c(),d("div",b,[k,o("iframe",{ref_key:"iframeRef",ref:s,src:"/demos/promiseify-post-message/inner",frameborder:"0"},null,512)]))}}),I=g(w,[["__scopeId","data-v-6e7a6b64"]]),M=o("h1",{id:"promiseify-postmessage",tabindex:"-1"},[v("Promiseify PostMessage "),o("a",{class:"header-anchor",href:"#promiseify-postmessage","aria-label":'Permalink to "Promiseify PostMessage"'},"")],-1),B=o("p",null,"将 postMessage 消息通信 Promise 化",-1),V=JSON.parse('{"title":"Promiseify PostMessage","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false},"headers":[],"relativePath":"demos/promiseify-post-message/index.md","filePath":"demos/promiseify-post-message/index.md","lastUpdated":1712924096000}'),N={name:"demos/promiseify-post-message/index.md"},$=Object.assign(N,{setup(e){return(s,a)=>(c(),d("div",null,[M,B,y(I)]))}});export{V as __pageData,$ as default};
|
||||
import{d as f,j as l,k as _,o as c,c as d,l as o,p as u,q as g,_ as h,I as y,a as v}from"./chunks/framework.DKE0jNKv.js";function x(e){window.addEventListener("message",async s=>{var i;const a=s.data,n=a.namespace,m=a.action,r=(i=t==null?void 0:t[n])==null?void 0:i[m];if(r){const p=await r(a.payload);e.postMessage({params:a,result:p},"*")}})}const t={user:{getUserToken:({userId:e})=>"token:"+e}},P=e=>(u("data-v-6e7a6b64"),e=e(),g(),e),b={class:"home"},k=P(()=>o("h2",null,"Home",-1)),w=f({__name:"Index",setup(e){const s=l(null);return _(()=>{s.value&&s.value.contentWindow&&x(s.value.contentWindow)}),(a,n)=>(c(),d("div",b,[k,o("iframe",{ref_key:"iframeRef",ref:s,src:"/demos/promiseify-post-message/inner",frameborder:"0"},null,512)]))}}),I=h(w,[["__scopeId","data-v-6e7a6b64"]]),M=o("h1",{id:"promiseify-postmessage",tabindex:"-1"},[v("Promiseify PostMessage "),o("a",{class:"header-anchor",href:"#promiseify-postmessage","aria-label":'Permalink to "Promiseify PostMessage"'},"")],-1),B=o("p",null,"将 postMessage 消息通信 Promise 化",-1),V=JSON.parse('{"title":"Promiseify PostMessage","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false},"headers":[],"relativePath":"demos/promiseify-post-message/index.md","filePath":"demos/promiseify-post-message/index.md","lastUpdated":1713715656000}'),N={name:"demos/promiseify-post-message/index.md"},$=Object.assign(N,{setup(e){return(s,a)=>(c(),d("div",null,[M,B,y(I)]))}});export{V as __pageData,$ as default};
|
||||
@@ -1 +1 @@
|
||||
import{d,h as l,o as r,c,m as p,t as _,q as m,s as f,_ as u,J as g}from"./chunks/framework.BFSS5Pox.js";function k(){window.addEventListener("message",({data:e,type:a})=>{if(a==="message"){const{params:s,result:n}=e,t=`${s.namespace}.${s.action}_${s.id}`,o=i.get(t);o&&(o(n),i.delete(t))}})}const i=new Map;let v=0;function w(e){return new Promise(a=>{if(window.parent){const s=v++,n=`${e.namespace}.${String(e.action)}_${s}`;i.set(n,a),window.parent.postMessage({id:s,...e},"*")}})}const h=e=>(m("data-v-cafa80a5"),e=e(),f(),e),y={class:"inner"},$=h(()=>p("h2",null,"Inner",-1)),I=d({__name:"Inner",setup(e){k();const a=l("");async function s(n){const t=await w({namespace:"user",action:"getUserToken",payload:{userId:n}});t&&(a.value=t)}return(n,t)=>(r(),c("div",y,[$,p("button",{onClick:t[0]||(t[0]=o=>s("123456"))},"getUserToken: "+_(a.value),1)]))}}),S=u(I,[["__scopeId","data-v-cafa80a5"]]),x=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false,"outline":false},"headers":[],"relativePath":"demos/promiseify-post-message/inner.md","filePath":"demos/promiseify-post-message/inner.md","lastUpdated":1712924096000}'),b={name:"demos/promiseify-post-message/inner.md"},C=Object.assign(b,{setup(e){return(a,s)=>(r(),c("div",null,[g(S)]))}});export{x as __pageData,C as default};
|
||||
import{d,j as l,o as r,c,l as p,t as _,p as f,q as m,_ as u,I as g}from"./chunks/framework.DKE0jNKv.js";function k(){window.addEventListener("message",({data:e,type:a})=>{if(a==="message"){const{params:s,result:n}=e,t=`${s.namespace}.${s.action}_${s.id}`,o=i.get(t);o&&(o(n),i.delete(t))}})}const i=new Map;let v=0;function w(e){return new Promise(a=>{if(window.parent){const s=v++,n=`${e.namespace}.${String(e.action)}_${s}`;i.set(n,a),window.parent.postMessage({id:s,...e},"*")}})}const y=e=>(f("data-v-cafa80a5"),e=e(),m(),e),h={class:"inner"},I=y(()=>p("h2",null,"Inner",-1)),$=d({__name:"Inner",setup(e){k();const a=l("");async function s(n){const t=await w({namespace:"user",action:"getUserToken",payload:{userId:n}});t&&(a.value=t)}return(n,t)=>(r(),c("div",h,[I,p("button",{onClick:t[0]||(t[0]=o=>s("123456"))},"getUserToken: "+_(a.value),1)]))}}),S=u($,[["__scopeId","data-v-cafa80a5"]]),x=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false,"outline":false},"headers":[],"relativePath":"demos/promiseify-post-message/inner.md","filePath":"demos/promiseify-post-message/inner.md","lastUpdated":1713715656000}'),b={name:"demos/promiseify-post-message/inner.md"},C=Object.assign(b,{setup(e){return(a,s)=>(r(),c("div",null,[g(S)]))}});export{x as __pageData,C as default};
|
||||
@@ -1 +1 @@
|
||||
import{d,h as l,o as r,c,m as p,t as _,q as m,s as f,_ as u,J as g}from"./chunks/framework.BFSS5Pox.js";function k(){window.addEventListener("message",({data:e,type:a})=>{if(a==="message"){const{params:s,result:n}=e,t=`${s.namespace}.${s.action}_${s.id}`,o=i.get(t);o&&(o(n),i.delete(t))}})}const i=new Map;let v=0;function w(e){return new Promise(a=>{if(window.parent){const s=v++,n=`${e.namespace}.${String(e.action)}_${s}`;i.set(n,a),window.parent.postMessage({id:s,...e},"*")}})}const h=e=>(m("data-v-cafa80a5"),e=e(),f(),e),y={class:"inner"},$=h(()=>p("h2",null,"Inner",-1)),I=d({__name:"Inner",setup(e){k();const a=l("");async function s(n){const t=await w({namespace:"user",action:"getUserToken",payload:{userId:n}});t&&(a.value=t)}return(n,t)=>(r(),c("div",y,[$,p("button",{onClick:t[0]||(t[0]=o=>s("123456"))},"getUserToken: "+_(a.value),1)]))}}),S=u(I,[["__scopeId","data-v-cafa80a5"]]),x=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false,"outline":false},"headers":[],"relativePath":"demos/promiseify-post-message/inner.md","filePath":"demos/promiseify-post-message/inner.md","lastUpdated":1712924096000}'),b={name:"demos/promiseify-post-message/inner.md"},C=Object.assign(b,{setup(e){return(a,s)=>(r(),c("div",null,[g(S)]))}});export{x as __pageData,C as default};
|
||||
import{d,j as l,o as r,c,l as p,t as _,p as f,q as m,_ as u,I as g}from"./chunks/framework.DKE0jNKv.js";function k(){window.addEventListener("message",({data:e,type:a})=>{if(a==="message"){const{params:s,result:n}=e,t=`${s.namespace}.${s.action}_${s.id}`,o=i.get(t);o&&(o(n),i.delete(t))}})}const i=new Map;let v=0;function w(e){return new Promise(a=>{if(window.parent){const s=v++,n=`${e.namespace}.${String(e.action)}_${s}`;i.set(n,a),window.parent.postMessage({id:s,...e},"*")}})}const y=e=>(f("data-v-cafa80a5"),e=e(),m(),e),h={class:"inner"},I=y(()=>p("h2",null,"Inner",-1)),$=d({__name:"Inner",setup(e){k();const a=l("");async function s(n){const t=await w({namespace:"user",action:"getUserToken",payload:{userId:n}});t&&(a.value=t)}return(n,t)=>(r(),c("div",h,[I,p("button",{onClick:t[0]||(t[0]=o=>s("123456"))},"getUserToken: "+_(a.value),1)]))}}),S=u($,[["__scopeId","data-v-cafa80a5"]]),x=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"page","navbar":false,"sidebar":false,"aside":false,"footer":false,"outline":false},"headers":[],"relativePath":"demos/promiseify-post-message/inner.md","filePath":"demos/promiseify-post-message/inner.md","lastUpdated":1713715656000}'),b={name:"demos/promiseify-post-message/inner.md"},C=Object.assign(b,{setup(e){return(a,s)=>(r(),c("div",null,[g(S)]))}});export{x as __pageData,C as default};
|
||||
@@ -1 +1 @@
|
||||
import{_ as e,c as t,o as i}from"./chunks/framework.BFSS5Pox.js";const m=JSON.parse('{"title":"主页","description":"","frontmatter":{"layout":"home","title":"主页","hero":{"name":"ZiuChen","text":"无限进步.","tagline":"Infinite Progress...","actions":[{"theme":"brand","text":"Get Started","link":"/self/"},{"theme":"alt","text":"View on GitHub","link":"https://github.com/ZiuChen"}]},"features":[{"icon":"📋","title":"Clipboard Manager","details":"A Powerful clipboard management tool"},{"icon":"✍🏻","title":"Super Markdown","details":"Powerful Markdown editor"},{"icon":"🚗","title":"JS Runner","details":"Run JavaScript dynamicly in Browser/Node.js"},{"icon":"🔑","title":"Bytemd Plugin","details":"Bytemd Plugin Library"},{"icon":"🍬","title":"ASOUL Browser Pet","details":"Keep an A-SOUL member as a pet in your browser"},{"icon":"🔧","title":"Typein","details":"Typein text, quickly perform browser operations"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1712924096000}'),n={name:"index.md"};function a(r,o,l,s,d,c){return i(),t("div")}const u=e(n,[["render",a]]);export{m as __pageData,u as default};
|
||||
import{_ as e,c as t,o as i}from"./chunks/framework.DKE0jNKv.js";const m=JSON.parse('{"title":"主页","description":"","frontmatter":{"layout":"home","title":"主页","hero":{"name":"ZiuChen","text":"无限进步.","tagline":"Infinite Progress...","actions":[{"theme":"brand","text":"Get Started","link":"/self/"},{"theme":"alt","text":"View on GitHub","link":"https://github.com/ZiuChen"}]},"features":[{"icon":"📋","title":"Clipboard Manager","details":"A Powerful clipboard management tool"},{"icon":"✍🏻","title":"Super Markdown","details":"Powerful Markdown editor"},{"icon":"🚗","title":"JS Runner","details":"Run JavaScript dynamicly in Browser/Node.js"},{"icon":"🔑","title":"Bytemd Plugin","details":"Bytemd Plugin Library"},{"icon":"🍬","title":"ASOUL Browser Pet","details":"Keep an A-SOUL member as a pet in your browser"},{"icon":"🔧","title":"Typein","details":"Typein text, quickly perform browser operations"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1713715656000}'),n={name:"index.md"};function a(r,o,l,s,d,c){return i(),t("div")}const u=e(n,[["render",a]]);export{m as __pageData,u as default};
|
||||
@@ -1 +1 @@
|
||||
import{_ as e,c as t,o as i}from"./chunks/framework.BFSS5Pox.js";const m=JSON.parse('{"title":"主页","description":"","frontmatter":{"layout":"home","title":"主页","hero":{"name":"ZiuChen","text":"无限进步.","tagline":"Infinite Progress...","actions":[{"theme":"brand","text":"Get Started","link":"/self/"},{"theme":"alt","text":"View on GitHub","link":"https://github.com/ZiuChen"}]},"features":[{"icon":"📋","title":"Clipboard Manager","details":"A Powerful clipboard management tool"},{"icon":"✍🏻","title":"Super Markdown","details":"Powerful Markdown editor"},{"icon":"🚗","title":"JS Runner","details":"Run JavaScript dynamicly in Browser/Node.js"},{"icon":"🔑","title":"Bytemd Plugin","details":"Bytemd Plugin Library"},{"icon":"🍬","title":"ASOUL Browser Pet","details":"Keep an A-SOUL member as a pet in your browser"},{"icon":"🔧","title":"Typein","details":"Typein text, quickly perform browser operations"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1712924096000}'),n={name:"index.md"};function a(r,o,l,s,d,c){return i(),t("div")}const u=e(n,[["render",a]]);export{m as __pageData,u as default};
|
||||
import{_ as e,c as t,o as i}from"./chunks/framework.DKE0jNKv.js";const m=JSON.parse('{"title":"主页","description":"","frontmatter":{"layout":"home","title":"主页","hero":{"name":"ZiuChen","text":"无限进步.","tagline":"Infinite Progress...","actions":[{"theme":"brand","text":"Get Started","link":"/self/"},{"theme":"alt","text":"View on GitHub","link":"https://github.com/ZiuChen"}]},"features":[{"icon":"📋","title":"Clipboard Manager","details":"A Powerful clipboard management tool"},{"icon":"✍🏻","title":"Super Markdown","details":"Powerful Markdown editor"},{"icon":"🚗","title":"JS Runner","details":"Run JavaScript dynamicly in Browser/Node.js"},{"icon":"🔑","title":"Bytemd Plugin","details":"Bytemd Plugin Library"},{"icon":"🍬","title":"ASOUL Browser Pet","details":"Keep an A-SOUL member as a pet in your browser"},{"icon":"🔧","title":"Typein","details":"Typein text, quickly perform browser operations"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1713715656000}'),n={name:"index.md"};function a(r,o,l,s,d,c){return i(),t("div")}const u=e(n,[["render",a]]);export{m as __pageData,u as default};
|
||||
Binary file not shown.
BIN
assets/inter-italic-cyrillic-ext.r48I6akx.woff2
Normal file
BIN
assets/inter-italic-cyrillic-ext.r48I6akx.woff2
Normal file
Binary file not shown.
BIN
assets/inter-italic-cyrillic.By2_1cv3.woff2
Normal file
BIN
assets/inter-italic-cyrillic.By2_1cv3.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-italic-greek-ext.1u6EdAuj.woff2
Normal file
BIN
assets/inter-italic-greek-ext.1u6EdAuj.woff2
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/inter-italic-greek.DJ8dCoTZ.woff2
Normal file
BIN
assets/inter-italic-greek.DJ8dCoTZ.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-italic-latin-ext.CN1xVJS-.woff2
Normal file
BIN
assets/inter-italic-latin-ext.CN1xVJS-.woff2
Normal file
Binary file not shown.
BIN
assets/inter-italic-latin.C2AdPX0b.woff2
Normal file
BIN
assets/inter-italic-latin.C2AdPX0b.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-italic-vietnamese.BSbpV94h.woff2
Normal file
BIN
assets/inter-italic-vietnamese.BSbpV94h.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2
Normal file
BIN
assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-roman-cyrillic.C5lxZ8CY.woff2
Normal file
BIN
assets/inter-roman-cyrillic.C5lxZ8CY.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-roman-greek-ext.CqjqNYQ-.woff2
Normal file
BIN
assets/inter-roman-greek-ext.CqjqNYQ-.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-roman-greek.BBVDIX6e.woff2
Normal file
BIN
assets/inter-roman-greek.BBVDIX6e.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/inter-roman-latin-ext.4ZJIpNVo.woff2
Normal file
BIN
assets/inter-roman-latin-ext.4ZJIpNVo.woff2
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/inter-roman-latin.Di8DUHzh.woff2
Normal file
BIN
assets/inter-roman-latin.Di8DUHzh.woff2
Normal file
Binary file not shown.
BIN
assets/inter-roman-vietnamese.BjW4sHH5.woff2
Normal file
BIN
assets/inter-roman-vietnamese.BjW4sHH5.woff2
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
import{_ as l,c as a,m as s,a as e,ai as i,o as n}from"./chunks/framework.BFSS5Pox.js";const p="/assets/BFC-1.Bs9guDK8.jpg",t="/assets/BFC-2.exVcyt2Q.jpg",h="/assets/BFC-3.B5Ao7L7o.jpg",k="/assets/BFC-4.CuxslIO8.jpg",q=JSON.parse('{"title":"CSS基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/CSS.md","filePath":"note/CSS.md","lastUpdated":1712924096000}'),d={name:"note/CSS.md"},r=i(`<h1 id="css基础" tabindex="-1">CSS基础 <a class="header-anchor" href="#css基础" aria-label="Permalink to "CSS基础""></a></h1><h2 id="书写css代码的方式" tabindex="-1">书写CSS代码的方式 <a class="header-anchor" href="#书写css代码的方式" aria-label="Permalink to "书写CSS代码的方式""></a></h2><p>CSS提供了三种方法,可以将CSS样式应用到元素上:</p><ul><li>内联样式 <ul><li>直接将样式写到元素的<code>style</code>属性上</li></ul></li><li>内部样式表 <ul><li>将样式通过<code><style></code>标签写在<code><head></code>标签中,通过选择器应用到元素上</li></ul></li><li>外部样式表 <ul><li>将样式写在外部文件如<code>style.css</code>中,再通过<code><link></code>标签引入</li></ul></li></ul><h2 id="文本样式-text" tabindex="-1">文本样式(text) <a class="header-anchor" href="#文本样式-text" aria-label="Permalink to "文本样式(text)""></a></h2><ul><li>text-decoration 框线样式 <ul><li>line-through 删除线</li><li>overline 上划线</li><li>underline 下划线</li><li>none 不设置装饰线</li></ul></li><li>text-transform <ul><li><code>text-transform</code> 属性指定如何将元素的文本大写。</li><li>它可以用于使文本显示为全大写或全小写,也可单独对每一个单词进行操作。</li></ul></li><li>text-indent <ul><li><code>text-indent</code> 属性能定义一个块元素首行文本内容之前的缩进量。</li></ul></li><li>text-align</li><li>word/letter-spacing</li></ul><h3 id="text-align-重要" tabindex="-1">text-align(重要) <a class="header-anchor" href="#text-align-重要" aria-label="Permalink to "text-align(重要)""></a></h3><p>行内内容(例如文字)如何相对它的块父元素对齐,<code>left</code>靠左 <code>center</code>居中 <code>right</code>靠右 <code>justify</code>两端对齐</p><p>默认值为<code>left</code></p><p>需要注意的是,当子元素是<code>div</code>时,对父元素设置<code>text-align</code>是不生效的:</p><div class="language-css vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">.box</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
import{_ as l,c as a,l as s,a as e,ai as i,o as n}from"./chunks/framework.DKE0jNKv.js";const p="/assets/BFC-1.Bs9guDK8.jpg",t="/assets/BFC-2.exVcyt2Q.jpg",h="/assets/BFC-3.B5Ao7L7o.jpg",k="/assets/BFC-4.CuxslIO8.jpg",q=JSON.parse('{"title":"CSS基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/CSS.md","filePath":"note/CSS.md","lastUpdated":1713715656000}'),d={name:"note/CSS.md"},r=i(`<h1 id="css基础" tabindex="-1">CSS基础 <a class="header-anchor" href="#css基础" aria-label="Permalink to "CSS基础""></a></h1><h2 id="书写css代码的方式" tabindex="-1">书写CSS代码的方式 <a class="header-anchor" href="#书写css代码的方式" aria-label="Permalink to "书写CSS代码的方式""></a></h2><p>CSS提供了三种方法,可以将CSS样式应用到元素上:</p><ul><li>内联样式 <ul><li>直接将样式写到元素的<code>style</code>属性上</li></ul></li><li>内部样式表 <ul><li>将样式通过<code><style></code>标签写在<code><head></code>标签中,通过选择器应用到元素上</li></ul></li><li>外部样式表 <ul><li>将样式写在外部文件如<code>style.css</code>中,再通过<code><link></code>标签引入</li></ul></li></ul><h2 id="文本样式-text" tabindex="-1">文本样式(text) <a class="header-anchor" href="#文本样式-text" aria-label="Permalink to "文本样式(text)""></a></h2><ul><li>text-decoration 框线样式 <ul><li>line-through 删除线</li><li>overline 上划线</li><li>underline 下划线</li><li>none 不设置装饰线</li></ul></li><li>text-transform <ul><li><code>text-transform</code> 属性指定如何将元素的文本大写。</li><li>它可以用于使文本显示为全大写或全小写,也可单独对每一个单词进行操作。</li></ul></li><li>text-indent <ul><li><code>text-indent</code> 属性能定义一个块元素首行文本内容之前的缩进量。</li></ul></li><li>text-align</li><li>word/letter-spacing</li></ul><h3 id="text-align-重要" tabindex="-1">text-align(重要) <a class="header-anchor" href="#text-align-重要" aria-label="Permalink to "text-align(重要)""></a></h3><p>行内内容(例如文字)如何相对它的块父元素对齐,<code>left</code>靠左 <code>center</code>居中 <code>right</code>靠右 <code>justify</code>两端对齐</p><p>默认值为<code>left</code></p><p>需要注意的是,当子元素是<code>div</code>时,对父元素设置<code>text-align</code>是不生效的:</p><div class="language-css vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">.box</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> height</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">500</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">px</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> text-align</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">center</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> background-color</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">red</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as l,c as a,m as s,a as e,ai as i,o as n}from"./chunks/framework.BFSS5Pox.js";const p="/assets/BFC-1.Bs9guDK8.jpg",t="/assets/BFC-2.exVcyt2Q.jpg",h="/assets/BFC-3.B5Ao7L7o.jpg",k="/assets/BFC-4.CuxslIO8.jpg",q=JSON.parse('{"title":"CSS基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/CSS.md","filePath":"note/CSS.md","lastUpdated":1712924096000}'),d={name:"note/CSS.md"},r=i("",210),o={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},c={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.186ex"},xmlns:"http://www.w3.org/2000/svg",width:"6.267ex",height:"2.071ex",role:"img",focusable:"false",viewBox:"0 -833.2 2770.1 915.2","aria-hidden":"true"},E=i("",1),g=[E],u=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("msup",null,[s("mn",null,"2"),s("mn",null,"3")]),s("mo",null,"="),s("mn",null,"8")])],-1),y=i("",325);function b(m,F,C,v,B,x){return n(),a("div",null,[r,s("p",null,[e("这样最终的样式就成为了:"),s("mjx-container",o,[(n(),a("svg",c,g)),u])]),y])}const A=l(d,[["render",b]]);export{q as __pageData,A as default};
|
||||
import{_ as l,c as a,l as s,a as e,ai as i,o as n}from"./chunks/framework.DKE0jNKv.js";const p="/assets/BFC-1.Bs9guDK8.jpg",t="/assets/BFC-2.exVcyt2Q.jpg",h="/assets/BFC-3.B5Ao7L7o.jpg",k="/assets/BFC-4.CuxslIO8.jpg",q=JSON.parse('{"title":"CSS基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/CSS.md","filePath":"note/CSS.md","lastUpdated":1713715656000}'),d={name:"note/CSS.md"},r=i("",210),o={class:"MathJax",jax:"SVG",style:{direction:"ltr",position:"relative"}},c={style:{overflow:"visible","min-height":"1px","min-width":"1px","vertical-align":"-0.186ex"},xmlns:"http://www.w3.org/2000/svg",width:"6.267ex",height:"2.071ex",role:"img",focusable:"false",viewBox:"0 -833.2 2770.1 915.2","aria-hidden":"true"},E=i("",1),g=[E],u=s("mjx-assistive-mml",{unselectable:"on",display:"inline",style:{top:"0px",left:"0px",clip:"rect(1px, 1px, 1px, 1px)","-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none",position:"absolute",padding:"1px 0px 0px 0px",border:"0px",display:"block",width:"auto",overflow:"hidden"}},[s("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[s("msup",null,[s("mn",null,"2"),s("mn",null,"3")]),s("mo",null,"="),s("mn",null,"8")])],-1),y=i("",325);function b(m,F,C,v,B,x){return n(),a("div",null,[r,s("p",null,[e("这样最终的样式就成为了:"),s("mjx-container",o,[(n(),a("svg",c,g)),u])]),y])}const A=l(d,[["render",b]]);export{q as __pageData,A as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const e="/assets/the-node.js-system.gCyqLCsp.jpeg",l="/assets/esmodule-phases.BezvbeaV.png",p="/assets/hard-link-and-soft-link.InHxy2mg.jpg",t="/assets/how-pnpm-works.dAKs5qkE.jpg",y=JSON.parse('{"title":"前端工程化","description":"","frontmatter":{},"headers":[],"relativePath":"note/Front-end Engineering.md","filePath":"note/Front-end Engineering.md","lastUpdated":1712924096000}'),h={name:"note/Front-end Engineering.md"},d=n("",254),k=[d];function o(r,c,E,g,u,b){return a(),i("div",null,k)}const F=s(h,[["render",o]]);export{y as __pageData,F as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const e="/assets/the-node.js-system.gCyqLCsp.jpeg",l="/assets/esmodule-phases.BezvbeaV.png",p="/assets/hard-link-and-soft-link.InHxy2mg.jpg",t="/assets/how-pnpm-works.dAKs5qkE.jpg",y=JSON.parse('{"title":"前端工程化","description":"","frontmatter":{},"headers":[],"relativePath":"note/Front-end Engineering.md","filePath":"note/Front-end Engineering.md","lastUpdated":1713715656000}'),h={name:"note/Front-end Engineering.md"},d=n("",254),k=[d];function o(r,c,E,g,u,b){return a(),i("div",null,k)}const F=s(h,[["render",o]]);export{y as __pageData,F as default};
|
||||
@@ -1 +1 @@
|
||||
import{_ as t,c as e,o as r,m as a,a as c}from"./chunks/framework.BFSS5Pox.js";const S=JSON.parse('{"title":"JavaScript 基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScript.md","filePath":"note/JavaScript.md","lastUpdated":1712924096000}'),i={name:"note/JavaScript.md"},s=a("h1",{id:"javascript-基础",tabindex:"-1"},[c("JavaScript 基础 "),a("a",{class:"header-anchor",href:"#javascript-基础","aria-label":'Permalink to "JavaScript 基础"'},"")],-1),n=a("p",null,"JavaScript 组成",-1),o=a("ul",null,[a("li",null,"ECMAScript 定义语言规范"),a("li",null,"DOM 用于操作文档的API"),a("li",null,"BOM 用于操作浏览器的API")],-1),l=[s,n,o];function p(d,_,h,v,m,u){return r(),e("div",null,l)}const J=t(i,[["render",p]]);export{S as __pageData,J as default};
|
||||
import{_ as t,c as e,o as r,l as a,a as c}from"./chunks/framework.DKE0jNKv.js";const S=JSON.parse('{"title":"JavaScript 基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScript.md","filePath":"note/JavaScript.md","lastUpdated":1713715656000}'),i={name:"note/JavaScript.md"},s=a("h1",{id:"javascript-基础",tabindex:"-1"},[c("JavaScript 基础 "),a("a",{class:"header-anchor",href:"#javascript-基础","aria-label":'Permalink to "JavaScript 基础"'},"")],-1),n=a("p",null,"JavaScript 组成",-1),o=a("ul",null,[a("li",null,"ECMAScript 定义语言规范"),a("li",null,"DOM 用于操作文档的API"),a("li",null,"BOM 用于操作浏览器的API")],-1),l=[s,n,o];function p(d,_,h,v,u,f){return r(),e("div",null,l)}const J=t(i,[["render",p]]);export{S as __pageData,J as default};
|
||||
@@ -1 +1 @@
|
||||
import{_ as t,c as e,o as r,m as a,a as c}from"./chunks/framework.BFSS5Pox.js";const S=JSON.parse('{"title":"JavaScript 基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScript.md","filePath":"note/JavaScript.md","lastUpdated":1712924096000}'),i={name:"note/JavaScript.md"},s=a("h1",{id:"javascript-基础",tabindex:"-1"},[c("JavaScript 基础 "),a("a",{class:"header-anchor",href:"#javascript-基础","aria-label":'Permalink to "JavaScript 基础"'},"")],-1),n=a("p",null,"JavaScript 组成",-1),o=a("ul",null,[a("li",null,"ECMAScript 定义语言规范"),a("li",null,"DOM 用于操作文档的API"),a("li",null,"BOM 用于操作浏览器的API")],-1),l=[s,n,o];function p(d,_,h,v,m,u){return r(),e("div",null,l)}const J=t(i,[["render",p]]);export{S as __pageData,J as default};
|
||||
import{_ as t,c as e,o as r,l as a,a as c}from"./chunks/framework.DKE0jNKv.js";const S=JSON.parse('{"title":"JavaScript 基础","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScript.md","filePath":"note/JavaScript.md","lastUpdated":1713715656000}'),i={name:"note/JavaScript.md"},s=a("h1",{id:"javascript-基础",tabindex:"-1"},[c("JavaScript 基础 "),a("a",{class:"header-anchor",href:"#javascript-基础","aria-label":'Permalink to "JavaScript 基础"'},"")],-1),n=a("p",null,"JavaScript 组成",-1),o=a("ul",null,[a("li",null,"ECMAScript 定义语言规范"),a("li",null,"DOM 用于操作文档的API"),a("li",null,"BOM 用于操作浏览器的API")],-1),l=[s,n,o];function p(d,_,h,v,u,f){return r(),e("div",null,l)}const J=t(i,[["render",p]]);export{S as __pageData,J as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l="/assets/image-20221118222207332-16687813334481.voHhuUQb.png",p="/assets/image-20221118222311200-16687813941873.BNUI2Qna.png",h="/assets/image-20221122103111654.-tsvcGvv.png",e="/assets/image-20221122103256116.BasjQ_pg.png",k="/assets/image-20221122103715428.DMMNV3OF.png",t="/assets/image-20221125090752249.BnpI9zXc.png",r="/assets/image-20221125094148365.ZryUkl5L.png",B=JSON.parse('{"title":"JavaScript 高级教程","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScriptEnhanced.md","filePath":"note/JavaScriptEnhanced.md","lastUpdated":1712924096000}'),E={name:"note/JavaScriptEnhanced.md"},d=n(`<h1 id="javascript-高级教程" tabindex="-1">JavaScript 高级教程 <a class="header-anchor" href="#javascript-高级教程" aria-label="Permalink to "JavaScript 高级教程""></a></h1><h2 id="函数中this指向" tabindex="-1">函数中this指向 <a class="header-anchor" href="#函数中this指向" aria-label="Permalink to "函数中this指向""></a></h2><p>函数在调用时, Javascript会默认为this绑定一个值</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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 定义一个函数</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const l="/assets/image-20221118222207332-16687813334481.voHhuUQb.png",p="/assets/image-20221118222311200-16687813941873.BNUI2Qna.png",h="/assets/image-20221122103111654.-tsvcGvv.png",e="/assets/image-20221122103256116.BasjQ_pg.png",k="/assets/image-20221122103715428.DMMNV3OF.png",t="/assets/image-20221125090752249.BnpI9zXc.png",r="/assets/image-20221125094148365.ZryUkl5L.png",B=JSON.parse('{"title":"JavaScript 高级教程","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScriptEnhanced.md","filePath":"note/JavaScriptEnhanced.md","lastUpdated":1713715656000}'),E={name:"note/JavaScriptEnhanced.md"},d=n(`<h1 id="javascript-高级教程" tabindex="-1">JavaScript 高级教程 <a class="header-anchor" href="#javascript-高级教程" aria-label="Permalink to "JavaScript 高级教程""></a></h1><h2 id="函数中this指向" tabindex="-1">函数中this指向 <a class="header-anchor" href="#函数中this指向" aria-label="Permalink to "函数中this指向""></a></h2><p>函数在调用时, Javascript会默认为this绑定一个值</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 shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 定义一个函数</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> foo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">this</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l="/assets/image-20221118222207332-16687813334481.voHhuUQb.png",p="/assets/image-20221118222311200-16687813941873.BNUI2Qna.png",h="/assets/image-20221122103111654.-tsvcGvv.png",e="/assets/image-20221122103256116.BasjQ_pg.png",k="/assets/image-20221122103715428.DMMNV3OF.png",t="/assets/image-20221125090752249.BnpI9zXc.png",r="/assets/image-20221125094148365.ZryUkl5L.png",B=JSON.parse('{"title":"JavaScript 高级教程","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScriptEnhanced.md","filePath":"note/JavaScriptEnhanced.md","lastUpdated":1712924096000}'),E={name:"note/JavaScriptEnhanced.md"},d=n("",668),g=[d];function c(y,o,F,b,u,m){return a(),i("div",null,g)}const A=s(E,[["render",c]]);export{B as __pageData,A as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const l="/assets/image-20221118222207332-16687813334481.voHhuUQb.png",p="/assets/image-20221118222311200-16687813941873.BNUI2Qna.png",h="/assets/image-20221122103111654.-tsvcGvv.png",e="/assets/image-20221122103256116.BasjQ_pg.png",k="/assets/image-20221122103715428.DMMNV3OF.png",t="/assets/image-20221125090752249.BnpI9zXc.png",r="/assets/image-20221125094148365.ZryUkl5L.png",B=JSON.parse('{"title":"JavaScript 高级教程","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"note/JavaScriptEnhanced.md","filePath":"note/JavaScriptEnhanced.md","lastUpdated":1713715656000}'),E={name:"note/JavaScriptEnhanced.md"},d=n("",668),g=[d];function c(y,o,F,b,u,m){return a(),i("div",null,g)}const A=s(E,[["render",c]]);export{B as __pageData,A as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as t}from"./chunks/framework.BFSS5Pox.js";const c=JSON.parse('{"title":"MySQL","description":"","frontmatter":{},"headers":[],"relativePath":"note/MySQL.md","filePath":"note/MySQL.md","lastUpdated":1712924096000}'),l={name:"note/MySQL.md"},n=t("",71),e=[n];function h(p,k,d,r,g,E){return a(),i("div",null,e)}const o=s(l,[["render",h]]);export{c as __pageData,o as default};
|
||||
import{_ as s,c as i,o as a,ai as t}from"./chunks/framework.DKE0jNKv.js";const c=JSON.parse('{"title":"MySQL","description":"","frontmatter":{},"headers":[],"relativePath":"note/MySQL.md","filePath":"note/MySQL.md","lastUpdated":1713715656000}'),l={name:"note/MySQL.md"},n=t("",71),e=[n];function h(p,k,d,r,g,E){return a(),i("div",null,e)}const o=s(l,[["render",h]]);export{c as __pageData,o as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l="/assets/useLayoutEffect.B_End6k1.svg",p="/assets/SSR.Ja5pYx3h.svg",F=JSON.parse('{"title":"React Hooks","description":"","frontmatter":{},"headers":[],"relativePath":"note/React Hooks.md","filePath":"note/React Hooks.md","lastUpdated":1712924096000}'),h={name:"note/React Hooks.md"},k=n(`<h1 id="react-hooks" tabindex="-1">React Hooks <a class="header-anchor" href="#react-hooks" aria-label="Permalink to "React Hooks""></a></h1><ul><li>认识和体验Hooks</li><li>State/Effect</li><li>Context/Reducer</li><li>Callback/Memo</li><li>Ref/LayoutEffect</li><li>自定义Hooks使用</li></ul><h2 id="认识react-hooks" tabindex="-1">认识React Hooks <a class="header-anchor" href="#认识react-hooks" aria-label="Permalink to "认识React Hooks""></a></h2><p>Hooks 是 React16.8 推出的新特性</p><p>在没有Hooks时,类组件能够完成的大部分工作,函数式组件都无法胜任:</p><ul><li>类组件可以定义并保存组件内部状态,并在状态发生改变时触发视图重新渲染 <ul><li>函数式组件不行,每次调用函数其中的变量都会被重新初始化,重新渲染时整个函数都重新执行</li></ul></li><li>类组件可以在其内部的生命周期回调中添加副作用 <ul><li>例如<code>componentDidMount</code>在类组件生命周期只会执行一次</li><li>函数式组件没有生命周期,如果在函数体内发起网络请求,那每次重新渲染都会发起请求</li></ul></li></ul><p>类组件存在的问题:</p><ul><li>复杂组件变得难以理解 <ul><li>业务代码相互耦合,类组件变得复杂</li><li>逻辑强耦合在一起难以拆分,强行拆分会导致过度设计,进一步增加代码复杂度</li></ul></li><li>class关键字的理解 <ul><li>初学React时class关键字理解存在困难</li><li>处理<code>this</code>的指向问题需要花费额外的心智负担</li></ul></li><li>组件状态复用 <ul><li>要复用组件需要借助高阶组件</li><li><code>redux</code> 中的 <code>connect</code> 或者 <code>react-router</code> 中的 <code>withRouter</code>,高阶组件的目的就是为了状态复</li><li>或通过Provider、Consumer来共享状态,但是Comsumer嵌套问题较严重</li></ul></li></ul><p>Hooks带来的优势:</p><ul><li>在不编写class的情况下使用state和其他React特性(如生命周期)</li><li>Hooks 允许我们在函数式组件中使用状态,并在状态发生改变时让视图重新渲染</li><li>同时,我们还可以在函数式组件中使用生命周期回调</li><li>更多的优点 ...</li></ul><h2 id="计数器案例对比" tabindex="-1">计数器案例对比 <a class="header-anchor" href="#计数器案例对比" aria-label="Permalink to "计数器案例对比""></a></h2><p>分别使用Hooks和类组件编写一个计数器:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-iSSDo" id="tab-0R4hnNt" checked="checked"><label for="tab-0R4hnNt">CounterClass.jsx</label><input type="radio" name="group-iSSDo" id="tab-QMpPyM9"><label for="tab-QMpPyM9">CounterFunctional.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// CounterClass.jsx</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const l="/assets/useLayoutEffect.B_End6k1.svg",p="/assets/SSR.Ja5pYx3h.svg",F=JSON.parse('{"title":"React Hooks","description":"","frontmatter":{},"headers":[],"relativePath":"note/React Hooks.md","filePath":"note/React Hooks.md","lastUpdated":1713715656000}'),h={name:"note/React Hooks.md"},k=n(`<h1 id="react-hooks" tabindex="-1">React Hooks <a class="header-anchor" href="#react-hooks" aria-label="Permalink to "React Hooks""></a></h1><ul><li>认识和体验Hooks</li><li>State/Effect</li><li>Context/Reducer</li><li>Callback/Memo</li><li>Ref/LayoutEffect</li><li>自定义Hooks使用</li></ul><h2 id="认识react-hooks" tabindex="-1">认识React Hooks <a class="header-anchor" href="#认识react-hooks" aria-label="Permalink to "认识React Hooks""></a></h2><p>Hooks 是 React16.8 推出的新特性</p><p>在没有Hooks时,类组件能够完成的大部分工作,函数式组件都无法胜任:</p><ul><li>类组件可以定义并保存组件内部状态,并在状态发生改变时触发视图重新渲染 <ul><li>函数式组件不行,每次调用函数其中的变量都会被重新初始化,重新渲染时整个函数都重新执行</li></ul></li><li>类组件可以在其内部的生命周期回调中添加副作用 <ul><li>例如<code>componentDidMount</code>在类组件生命周期只会执行一次</li><li>函数式组件没有生命周期,如果在函数体内发起网络请求,那每次重新渲染都会发起请求</li></ul></li></ul><p>类组件存在的问题:</p><ul><li>复杂组件变得难以理解 <ul><li>业务代码相互耦合,类组件变得复杂</li><li>逻辑强耦合在一起难以拆分,强行拆分会导致过度设计,进一步增加代码复杂度</li></ul></li><li>class关键字的理解 <ul><li>初学React时class关键字理解存在困难</li><li>处理<code>this</code>的指向问题需要花费额外的心智负担</li></ul></li><li>组件状态复用 <ul><li>要复用组件需要借助高阶组件</li><li><code>redux</code> 中的 <code>connect</code> 或者 <code>react-router</code> 中的 <code>withRouter</code>,高阶组件的目的就是为了状态复</li><li>或通过Provider、Consumer来共享状态,但是Comsumer嵌套问题较严重</li></ul></li></ul><p>Hooks带来的优势:</p><ul><li>在不编写class的情况下使用state和其他React特性(如生命周期)</li><li>Hooks 允许我们在函数式组件中使用状态,并在状态发生改变时让视图重新渲染</li><li>同时,我们还可以在函数式组件中使用生命周期回调</li><li>更多的优点 ...</li></ul><h2 id="计数器案例对比" tabindex="-1">计数器案例对比 <a class="header-anchor" href="#计数器案例对比" aria-label="Permalink to "计数器案例对比""></a></h2><p>分别使用Hooks和类组件编写一个计数器:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-kFhha" id="tab-hXR-r-0" checked="checked"><label for="tab-hXR-r-0">CounterClass.jsx</label><input type="radio" name="group-kFhha" id="tab-sm-Mjih"><label for="tab-sm-Mjih">CounterFunctional.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// CounterClass.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> React, { PureComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> CounterClass</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> extends</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> PureComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
@@ -95,7 +95,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Effect Cleaned Up'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line highlighted"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }, [])</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</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></div></div><h2 id="usecontext" tabindex="-1">useContext <a class="header-anchor" href="#usecontext" aria-label="Permalink to "useContext""></a></h2><p>在之前的开发中,要在组件中使用共享的Context有两种方式</p><ul><li>类组件可以通过<code>ClassName.contextType = SomeContext</code>绑定上下文</li><li>在类的函数中通过<code>this.context.xxx</code>获取上下文中共享的状态</li><li>同时有多个Context时/函数式组件中,通过<code>SomeContext.Consumer</code>的方式共享上下文状态</li></ul><p>其中最大的问题就是:多个Context在同时使用时会引入大量的嵌套,而<code>useContext</code>可以帮我们解决这个问题</p><p>通过<code>useContext</code>可以直接获取到某个上下文中共享的状态变量</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-qq5NL" id="tab-sXc6Ipd" checked="checked"><label for="tab-sXc6Ipd">Profile.jsx</label><input type="radio" name="group-qq5NL" id="tab-lm-lRC7"><label for="tab-lm-lRC7">index.js</label><input type="radio" name="group-qq5NL" id="tab-3QFJpzP"><label for="tab-3QFJpzP">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Profile.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</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></div></div><h2 id="usecontext" tabindex="-1">useContext <a class="header-anchor" href="#usecontext" aria-label="Permalink to "useContext""></a></h2><p>在之前的开发中,要在组件中使用共享的Context有两种方式</p><ul><li>类组件可以通过<code>ClassName.contextType = SomeContext</code>绑定上下文</li><li>在类的函数中通过<code>this.context.xxx</code>获取上下文中共享的状态</li><li>同时有多个Context时/函数式组件中,通过<code>SomeContext.Consumer</code>的方式共享上下文状态</li></ul><p>其中最大的问题就是:多个Context在同时使用时会引入大量的嵌套,而<code>useContext</code>可以帮我们解决这个问题</p><p>通过<code>useContext</code>可以直接获取到某个上下文中共享的状态变量</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-LjGs2" id="tab-x0YyD3f" checked="checked"><label for="tab-x0YyD3f">Profile.jsx</label><input type="radio" name="group-LjGs2" id="tab-bnWmeCw"><label for="tab-bnWmeCw">index.js</label><input type="radio" name="group-LjGs2" id="tab-5iA2bye"><label for="tab-5iA2bye">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Profile.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> React, { useContext } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { UserContext, ThemeContext } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '../context'</span></span>
|
||||
<span class="line"></span>
|
||||
@@ -135,7 +135,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">UserContext.Provider</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div></div></div><p>当组件上层最近的<code>SomeContext.Provider</code>提供的值发生更新时,<code>useContext</code>会使用上下文中最新的数据触发组件的重新渲染</p><h2 id="usereducer" tabindex="-1">useReducer <a class="header-anchor" href="#usereducer" aria-label="Permalink to "useReducer""></a></h2><p><code>useReducer</code>并不是Redux的替代品</p><ul><li><code>useReducer</code>是<code>useState</code>在某些场景下的替代方案</li><li>如果state需要处理的<strong>数据较为复杂</strong>,我们可以通过<code>useReducer</code>对其进行拆分</li><li>或者需要修改的state需要依赖之前的state时,也可以使用<code>useReducer</code></li></ul><p>下面举一个例子:用户信息包含多个复杂的字段,当用户执行操作后需要同时对多个字段进行修改</p><p>我们分别用<code>useState</code>和<code>useReducer</code>来实现:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-Hylvh" id="tab-gs8pFnb" checked="checked"><label for="tab-gs8pFnb">UserInfoWithReducer.jsx</label><input type="radio" name="group-Hylvh" id="tab-GCHmYxW"><label for="tab-GCHmYxW">UserInfo.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// UserInfoWithReducer.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div></div></div><p>当组件上层最近的<code>SomeContext.Provider</code>提供的值发生更新时,<code>useContext</code>会使用上下文中最新的数据触发组件的重新渲染</p><h2 id="usereducer" tabindex="-1">useReducer <a class="header-anchor" href="#usereducer" aria-label="Permalink to "useReducer""></a></h2><p><code>useReducer</code>并不是Redux的替代品</p><ul><li><code>useReducer</code>是<code>useState</code>在某些场景下的替代方案</li><li>如果state需要处理的<strong>数据较为复杂</strong>,我们可以通过<code>useReducer</code>对其进行拆分</li><li>或者需要修改的state需要依赖之前的state时,也可以使用<code>useReducer</code></li></ul><p>下面举一个例子:用户信息包含多个复杂的字段,当用户执行操作后需要同时对多个字段进行修改</p><p>我们分别用<code>useState</code>和<code>useReducer</code>来实现:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group--OkJ7" id="tab-MznlC-K" checked="checked"><label for="tab-MznlC-K">UserInfoWithReducer.jsx</label><input type="radio" name="group--OkJ7" id="tab-yHnx6FC"><label for="tab-yHnx6FC">UserInfo.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// UserInfoWithReducer.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> React, { useReducer } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> reducer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">state</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">action</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
||||
@@ -278,7 +278,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> bar1</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> foo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">bar1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 1</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">bar1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 1</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></div></div><p>不论调用了多少次<code>bar1</code>,其内部取到的值都始终是最初的那个<code>count</code>,自然值也不会发生变化</p><p>所以,我们需要显式地为<code>useCallback</code>指定依赖state,这样才能准确地使用最新的状态定义新的函数</p><h3 id="真实的usecallback使用场景" tabindex="-1">真实的useCallback使用场景 <a class="header-anchor" href="#真实的usecallback使用场景" aria-label="Permalink to "真实的useCallback使用场景""></a></h3><p>经过之前的说明,目前<code>useCallback</code>看起来并没有实际的用途,它没有减少函数的定义次数,甚至在不合理使用时还会出现闭包陷阱,而带来的唯一好处就是:<strong>当状态没有发生改变时,保证函数指向确定且唯一</strong></p><p>下面我们举一个实际场景来说明<code>useCallback</code>的用途:</p><p>一个嵌套计数器的例子,外部计数器可以展示/改变计数器的值,子组件也可以通过调用props传递来的函数来改变计数器的值,同时外部计数器还包含了其他的状态在动态被修改</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-axZCX" id="tab-soNx4-L" checked="checked"><label for="tab-soNx4-L">InnerCounter.jsx</label><input type="radio" name="group-axZCX" id="tab-mjELzeA"><label for="tab-mjELzeA">Counter.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// InnerCounter.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">bar1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 1</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></div></div><p>不论调用了多少次<code>bar1</code>,其内部取到的值都始终是最初的那个<code>count</code>,自然值也不会发生变化</p><p>所以,我们需要显式地为<code>useCallback</code>指定依赖state,这样才能准确地使用最新的状态定义新的函数</p><h3 id="真实的usecallback使用场景" tabindex="-1">真实的useCallback使用场景 <a class="header-anchor" href="#真实的usecallback使用场景" aria-label="Permalink to "真实的useCallback使用场景""></a></h3><p>经过之前的说明,目前<code>useCallback</code>看起来并没有实际的用途,它没有减少函数的定义次数,甚至在不合理使用时还会出现闭包陷阱,而带来的唯一好处就是:<strong>当状态没有发生改变时,保证函数指向确定且唯一</strong></p><p>下面我们举一个实际场景来说明<code>useCallback</code>的用途:</p><p>一个嵌套计数器的例子,外部计数器可以展示/改变计数器的值,子组件也可以通过调用props传递来的函数来改变计数器的值,同时外部计数器还包含了其他的状态在动态被修改</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-950ZC" id="tab-y_kEbzd" checked="checked"><label for="tab-y_kEbzd">InnerCounter.jsx</label><input type="radio" name="group-950ZC" id="tab-n45T49x"><label for="tab-n45T49x">Counter.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// InnerCounter.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> React, { memo } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> memo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> InnerCounter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">props</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
||||
@@ -526,7 +526,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> theme</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useContext</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(ThemeContext)</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(user.name, theme.primaryColor) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// ...</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</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>我们可以使用自定义Hook来简化这一操作,将所有的Context统一导入并转化为对象,直接在组件中使用</p><p>对之前的Profile组件使用Hook进行增强:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-QRxIG" id="tab-_JOo44H" checked="checked"><label for="tab-_JOo44H">useSharedContext.js</label><input type="radio" name="group-QRxIG" id="tab-2idRMMx"><label for="tab-2idRMMx">Profile.js</label></div><div class="blocks"><div class="language-ts vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// useSharedContext.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</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>我们可以使用自定义Hook来简化这一操作,将所有的Context统一导入并转化为对象,直接在组件中使用</p><p>对之前的Profile组件使用Hook进行增强:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-gJy7b" id="tab-2FY1e6J" checked="checked"><label for="tab-2FY1e6J">useSharedContext.js</label><input type="radio" name="group-gJy7b" id="tab-xpfNRQQ"><label for="tab-xpfNRQQ">Profile.js</label></div><div class="blocks"><div class="language-ts vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// useSharedContext.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { useContext } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { UserContext, ThemeContext } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '../context'</span></span>
|
||||
<span class="line"></span>
|
||||
@@ -550,7 +550,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">theme</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">theme</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">theme</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> </</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">div</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div></div></div><h3 id="案例二-获取滚动位置" tabindex="-1">案例二:获取滚动位置 <a class="header-anchor" href="#案例二-获取滚动位置" aria-label="Permalink to "案例二:获取滚动位置""></a></h3><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-4UPpR" id="tab-vs4t_0Q" checked="checked"><label for="tab-vs4t_0Q">useScrollPosition.js</label><input type="radio" name="group-4UPpR" id="tab-qWK3uI2"><label for="tab-qWK3uI2">GiantList.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// useScrollPosition.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div></div></div><h3 id="案例二-获取滚动位置" tabindex="-1">案例二:获取滚动位置 <a class="header-anchor" href="#案例二-获取滚动位置" aria-label="Permalink to "案例二:获取滚动位置""></a></h3><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-dcSJ2" id="tab-gFhUldf" checked="checked"><label for="tab-gFhUldf">useScrollPosition.js</label><input type="radio" name="group-dcSJ2" id="tab-Cply0MZ"><label for="tab-Cply0MZ">GiantList.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// useScrollPosition.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { useState, useEffect } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useScrollPosition</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">options</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {}) {</span></span>
|
||||
@@ -587,7 +587,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> GiantList</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></div></div></div></div><h3 id="案例三-封装localstorage" tabindex="-1">案例三:封装localStorage <a class="header-anchor" href="#案例三-封装localstorage" aria-label="Permalink to "案例三:封装localStorage""></a></h3><p>在使用状态变量的时候,为状态变量值的更新添加副作用,将变量名作为key,值更新到localStorage中</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-i1fQJ" id="tab-gCPdaOX" checked="checked"><label for="tab-gCPdaOX">useLocalStorage.js</label><input type="radio" name="group-i1fQJ" id="tab-T7anx0y"><label for="tab-T7anx0y">UserInfoStorage.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// useLocalStorage.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> GiantList</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></div></div></div></div><h3 id="案例三-封装localstorage" tabindex="-1">案例三:封装localStorage <a class="header-anchor" href="#案例三-封装localstorage" aria-label="Permalink to "案例三:封装localStorage""></a></h3><p>在使用状态变量的时候,为状态变量值的更新添加副作用,将变量名作为key,值更新到localStorage中</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-i5sKZ" id="tab-y4zYrBe" checked="checked"><label for="tab-y4zYrBe">useLocalStorage.js</label><input type="radio" name="group-i5sKZ" id="tab-g3FeDrF"><label for="tab-g3FeDrF">UserInfoStorage.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// useLocalStorage.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { useState, useEffect } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useLocalStorage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">key</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
||||
@@ -622,7 +622,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> UserInfoStorage</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></div></div></div></div><p>这里的<code>useState</code>还展示了一个额外的用法,向<code>useState</code>传递一个函数,函数的返回值会作为状态变量的初始值</p><h2 id="redux-hooks" tabindex="-1">Redux Hooks <a class="header-anchor" href="#redux-hooks" aria-label="Permalink to "Redux Hooks""></a></h2><p>之前的Redux开发中,为了让组件和Redux建立联系,我们使用了react-redux中的connect</p><ul><li>必须与高阶函数结合,必须使用返回的高阶组件</li><li>必须编写<code>mapStateToProps</code> <code>mapDispatchToProps</code>,将上下文状态映射到props中</li></ul><p>从Redux7.1开始,支持Hook写法,不再需要编写connect以及映射函数了</p><h3 id="useselector" tabindex="-1">useSelector <a class="header-anchor" href="#useselector" aria-label="Permalink to "useSelector""></a></h3><p>将state映射到组件中</p><ul><li>参数一:将state映射到需要的数据中</li><li>参数二:可以进行比较,来决定组件是否重新渲染</li></ul><p>默认情况下<code>useSelector</code>监听整个state的变化,只要state中有状态变量发生变化,无论当前组件是否使用到了这个状态变量,都会触发组件的重新渲染。这就需要我们显式地为其指定重新渲染的判断条件</p><blockquote><p><code>useSelector</code>会比较我们返回的两个对象是否相等:</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> refEquality</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">a</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">b</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (a </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> b);</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>只有两个对象全等时,才可以不触发重新渲染</p></blockquote><h3 id="usedispatch" tabindex="-1">useDispatch <a class="header-anchor" href="#usedispatch" aria-label="Permalink to "useDispatch""></a></h3><p>直接获取<code>dispatch</code>函数,之后在组件中直接调用即可</p><p>另外,我们还可以通过<code>useStore</code>来获取当前的store对象</p><p>拿之前Redux的计数器举例,使用<code>useSelector</code>与<code>useDispatch</code>进行重构:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-Ux1jP" id="tab-1WTCW0r" checked="checked"><label for="tab-1WTCW0r">[Now] Counter.jsx</label><input type="radio" name="group-Ux1jP" id="tab-Fy--SQN"><label for="tab-Fy--SQN">[Prev] Counter.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// [Now] Counter.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> UserInfoStorage</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></div></div></div></div><p>这里的<code>useState</code>还展示了一个额外的用法,向<code>useState</code>传递一个函数,函数的返回值会作为状态变量的初始值</p><h2 id="redux-hooks" tabindex="-1">Redux Hooks <a class="header-anchor" href="#redux-hooks" aria-label="Permalink to "Redux Hooks""></a></h2><p>之前的Redux开发中,为了让组件和Redux建立联系,我们使用了react-redux中的connect</p><ul><li>必须与高阶函数结合,必须使用返回的高阶组件</li><li>必须编写<code>mapStateToProps</code> <code>mapDispatchToProps</code>,将上下文状态映射到props中</li></ul><p>从Redux7.1开始,支持Hook写法,不再需要编写connect以及映射函数了</p><h3 id="useselector" tabindex="-1">useSelector <a class="header-anchor" href="#useselector" aria-label="Permalink to "useSelector""></a></h3><p>将state映射到组件中</p><ul><li>参数一:将state映射到需要的数据中</li><li>参数二:可以进行比较,来决定组件是否重新渲染</li></ul><p>默认情况下<code>useSelector</code>监听整个state的变化,只要state中有状态变量发生变化,无论当前组件是否使用到了这个状态变量,都会触发组件的重新渲染。这就需要我们显式地为其指定重新渲染的判断条件</p><blockquote><p><code>useSelector</code>会比较我们返回的两个对象是否相等:</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> refEquality</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">a</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">b</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (a </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> b);</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>只有两个对象全等时,才可以不触发重新渲染</p></blockquote><h3 id="usedispatch" tabindex="-1">useDispatch <a class="header-anchor" href="#usedispatch" aria-label="Permalink to "useDispatch""></a></h3><p>直接获取<code>dispatch</code>函数,之后在组件中直接调用即可</p><p>另外,我们还可以通过<code>useStore</code>来获取当前的store对象</p><p>拿之前Redux的计数器举例,使用<code>useSelector</code>与<code>useDispatch</code>进行重构:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-yP61_" id="tab-aubCPnx" checked="checked"><label for="tab-aubCPnx">[Now] Counter.jsx</label><input type="radio" name="group-yP61_" id="tab-ua0QufB"><label for="tab-ua0QufB">[Prev] Counter.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// [Now] Counter.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { memo } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { useSelector, useDispatch, shallowEqual } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react-redux'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { addCount, subCount } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '../store/features/counter'</span></span>
|
||||
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const l="/assets/useLayoutEffect.B_End6k1.svg",p="/assets/SSR.Ja5pYx3h.svg",F=JSON.parse('{"title":"React Hooks","description":"","frontmatter":{},"headers":[],"relativePath":"note/React Hooks.md","filePath":"note/React Hooks.md","lastUpdated":1712924096000}'),h={name:"note/React Hooks.md"},k=n("",207),t=[k];function e(r,E,d,g,y,c){return a(),i("div",null,t)}const b=s(h,[["render",e]]);export{F as __pageData,b as default};
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const l="/assets/useLayoutEffect.B_End6k1.svg",p="/assets/SSR.Ja5pYx3h.svg",F=JSON.parse('{"title":"React Hooks","description":"","frontmatter":{},"headers":[],"relativePath":"note/React Hooks.md","filePath":"note/React Hooks.md","lastUpdated":1713715656000}'),h={name:"note/React Hooks.md"},k=n("",207),t=[k];function e(r,E,d,g,y,c){return a(),i("div",null,t)}const b=s(h,[["render",e]]);export{F as __pageData,b as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const y=JSON.parse('{"title":"React Router","description":"","frontmatter":{},"headers":[],"relativePath":"note/React Router.md","filePath":"note/React Router.md","lastUpdated":1712924096000}'),l={name:"note/React Router.md"},p=n(`<h1 id="react-router" tabindex="-1">React Router <a class="header-anchor" href="#react-router" aria-label="Permalink to "React Router""></a></h1><h2 id="了解reactrouter" tabindex="-1">了解ReactRouter <a class="header-anchor" href="#了解reactrouter" aria-label="Permalink to "了解ReactRouter""></a></h2><p>三大框架都有各自的路由实现</p><ul><li>Angular ngRouter</li><li>React ReactRouter</li><li>Vue VueRouter</li></ul><p>React Router在最近两年的版本更新较快,并且在最新的React Router6发生了较大的变化</p><ul><li>Web开发只需要安装<code>react-router-dom</code></li><li><code>react-router</code>包含一些ReactNative的内容</li></ul><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> i</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> react-router-dom</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>从<code>react-router-dom</code>中导出<code>BrowserRouter</code> 或 <code>HashRouter</code>,二者分别对应history模式与哈希模式</p><p>将App用二者之一包裹,即可启用路由:</p><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// index.js</span></span>
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const y=JSON.parse('{"title":"React Router","description":"","frontmatter":{},"headers":[],"relativePath":"note/React Router.md","filePath":"note/React Router.md","lastUpdated":1713715656000}'),l={name:"note/React Router.md"},p=n(`<h1 id="react-router" tabindex="-1">React Router <a class="header-anchor" href="#react-router" aria-label="Permalink to "React Router""></a></h1><h2 id="了解reactrouter" tabindex="-1">了解ReactRouter <a class="header-anchor" href="#了解reactrouter" aria-label="Permalink to "了解ReactRouter""></a></h2><p>三大框架都有各自的路由实现</p><ul><li>Angular ngRouter</li><li>React ReactRouter</li><li>Vue VueRouter</li></ul><p>React Router在最近两年的版本更新较快,并且在最新的React Router6发生了较大的变化</p><ul><li>Web开发只需要安装<code>react-router-dom</code></li><li><code>react-router</code>包含一些ReactNative的内容</li></ul><div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> i</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> react-router-dom</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>从<code>react-router-dom</code>中导出<code>BrowserRouter</code> 或 <code>HashRouter</code>,二者分别对应history模式与哈希模式</p><p>将App用二者之一包裹,即可启用路由:</p><div class="language-tsx vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// index.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> React, { StrictMode } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ReactDOM </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react-dom/client'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> App </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> './App'</span></span>
|
||||
@@ -38,7 +38,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const y
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div><p>另外,这里还有一个小技巧,在最末一个路由指定一个path为<code>*</code>的路由匹配规则,可以为路由匹配添加fallback策略,当未匹配到其之前的任何域名时,会展示NotFound页面</p><h2 id="嵌套路由" tabindex="-1">嵌套路由 <a class="header-anchor" href="#嵌套路由" aria-label="Permalink to "嵌套路由""></a></h2><p>嵌套路由可以通过在<code>Route</code>组件内部嵌套新的<code>Route</code>组件来实现</p><p>再通过<code>Outlet</code>组件来指定嵌套路由的占位元素(类似于VueRouter中的router-view)</p><p>我们在之前的例子的基础上,为Home页面添加两个子页面HomeRanking和HomeRecommand</p><p>同时,我们也应该为Home组件添加默认跳转,就像根路径默认重定向到Home组件那样,进入到Home组件后也应该默认重定向一个子页面中,这里我们仍然使用到了Navigate组件</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group--vkzm" id="tab-8MoePdA" checked="checked"><label for="tab-8MoePdA">App.jsx </label><input type="radio" name="group--vkzm" id="tab-vEUIsNG"><label for="tab-vEUIsNG">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// App.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div><p>另外,这里还有一个小技巧,在最末一个路由指定一个path为<code>*</code>的路由匹配规则,可以为路由匹配添加fallback策略,当未匹配到其之前的任何域名时,会展示NotFound页面</p><h2 id="嵌套路由" tabindex="-1">嵌套路由 <a class="header-anchor" href="#嵌套路由" aria-label="Permalink to "嵌套路由""></a></h2><p>嵌套路由可以通过在<code>Route</code>组件内部嵌套新的<code>Route</code>组件来实现</p><p>再通过<code>Outlet</code>组件来指定嵌套路由的占位元素(类似于VueRouter中的router-view)</p><p>我们在之前的例子的基础上,为Home页面添加两个子页面HomeRanking和HomeRecommand</p><p>同时,我们也应该为Home组件添加默认跳转,就像根路径默认重定向到Home组件那样,进入到Home组件后也应该默认重定向一个子页面中,这里我们仍然使用到了Navigate组件</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-xwhrH" id="tab-F-sk0gA" checked="checked"><label for="tab-F-sk0gA">App.jsx </label><input type="radio" name="group-xwhrH" id="tab-UzYzPbH"><label for="tab-UzYzPbH">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// App.jsx</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> React, { PureComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { Routes, Route, Navigate, NavLink } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react-router-dom'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Home </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> './views/Home'</span></span>
|
||||
@@ -73,7 +73,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const y
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div></div></div><h2 id="编程式导航-高阶组件" tabindex="-1">编程式导航(高阶组件) <a class="header-anchor" href="#编程式导航-高阶组件" aria-label="Permalink to "编程式导航(高阶组件)""></a></h2><p>之前使用的ReactRouter提供的路由跳转的组件,无论是<code>Link</code>还是<code>NavLink</code>可定制化能力都比较差,无法实现“点击按钮后跳转路由”这样的需求,那么我们就需要通过编程式导航,使用JS来完成路由的跳转</p><p>ReactRouter提供了编程式导航的API:<code>useNavigate</code></p><p>自ReactRouter6起,编程式导航的API不再支持ClassComponent,全面拥抱Hooks。</p><p>我们将在后续的学习中开启Hooks的写法,那么目前如何在类组件中也能使用Hooks呢?答案是高阶组件</p><p>封装一个高阶组件<code>withRouter</code>,经过高阶组件处理的类组件的props将会携带router对象,上面包含一些我们需要的属性和方法:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-vmd81" id="tab-75k2Fao" checked="checked"><label for="tab-75k2Fao">withRouter.js</label><input type="radio" name="group-vmd81" id="tab-TCe-SqS"><label for="tab-TCe-SqS">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div></div></div><h2 id="编程式导航-高阶组件" tabindex="-1">编程式导航(高阶组件) <a class="header-anchor" href="#编程式导航-高阶组件" aria-label="Permalink to "编程式导航(高阶组件)""></a></h2><p>之前使用的ReactRouter提供的路由跳转的组件,无论是<code>Link</code>还是<code>NavLink</code>可定制化能力都比较差,无法实现“点击按钮后跳转路由”这样的需求,那么我们就需要通过编程式导航,使用JS来完成路由的跳转</p><p>ReactRouter提供了编程式导航的API:<code>useNavigate</code></p><p>自ReactRouter6起,编程式导航的API不再支持ClassComponent,全面拥抱Hooks。</p><p>我们将在后续的学习中开启Hooks的写法,那么目前如何在类组件中也能使用Hooks呢?答案是高阶组件</p><p>封装一个高阶组件<code>withRouter</code>,经过高阶组件处理的类组件的props将会携带router对象,上面包含一些我们需要的属性和方法:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-CY7JV" id="tab--rX64tm" checked="checked"><label for="tab--rX64tm">withRouter.js</label><input type="radio" name="group-CY7JV" id="tab-Z3DOB3M"><label for="tab-Z3DOB3M">Home.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { useNavigate } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react-router-dom'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> withRouter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">WrapperComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
||||
@@ -100,7 +100,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const y
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</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></div></div></div></div><p>我们使用<code>withRouter</code>高阶组件对Home组件进行了增强,可以通过编程式导航来实现二级路由跳转</p><p>这里只是展示了编程式导航的用法和高阶组件的能力,目前还是尽可能使用Hooks写法编写新项目</p><h2 id="动态路由-路由传参" tabindex="-1">动态路由(路由传参) <a class="header-anchor" href="#动态路由-路由传参" aria-label="Permalink to "动态路由(路由传参)""></a></h2><p>传递参数由两种方式:</p><ul><li>动态路由的方式</li><li>查询字符串传递参数</li></ul><p>动态路由是指:路由中的<strong>路径</strong>信息并不会固定</p><ul><li>比如匹配规则为<code>/detail/:id</code>时,<code>/detail/123</code> <code>detail/888</code>都会被匹配上,并将<code>123/888</code>作为id参数传递</li><li>其中<code>/detail/:id</code>这个匹配规则被称为动态路由</li></ul><p>动态路由常见于嵌套路由跳转,比如:从歌曲列表页面点击后跳转到歌曲详情页,可以通过路由传递歌曲的ID,访问到不同歌曲的详情页</p><p>我们在之前的HomeRanking榜单中加入列表和点击跳转功能,并编写一个新的组件Detail来接收来自路由的参数</p><p>同样地,<code>react-router-dom</code>为我们提供了从路由获取参数的API:<code>useParams</code>,它是一个Hooks,我们将它应用到之前编写的高级组件<code>withRouter</code>中</p><ul><li>在使用了<code>withRouter</code>的组件中,就可以通过<code>this.props.router.params.xxx</code>获取到当前路由中传递的参数</li><li>使用动态匹配路由时,传递给Route组件的<code>path</code>属性为<code>:xxx</code>,这里是<code>/detail/:id</code></li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-SXxsE" id="tab-Zq-M3Jl" checked="checked"><label for="tab-Zq-M3Jl">withRouter.js</label><input type="radio" name="group-SXxsE" id="tab-DOtnJ-E"><label for="tab-DOtnJ-E">HomeRanking.jsx</label><input type="radio" name="group-SXxsE" id="tab-BLmaxuR"><label for="tab-BLmaxuR">Detail.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</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></div></div></div></div><p>我们使用<code>withRouter</code>高阶组件对Home组件进行了增强,可以通过编程式导航来实现二级路由跳转</p><p>这里只是展示了编程式导航的用法和高阶组件的能力,目前还是尽可能使用Hooks写法编写新项目</p><h2 id="动态路由-路由传参" tabindex="-1">动态路由(路由传参) <a class="header-anchor" href="#动态路由-路由传参" aria-label="Permalink to "动态路由(路由传参)""></a></h2><p>传递参数由两种方式:</p><ul><li>动态路由的方式</li><li>查询字符串传递参数</li></ul><p>动态路由是指:路由中的<strong>路径</strong>信息并不会固定</p><ul><li>比如匹配规则为<code>/detail/:id</code>时,<code>/detail/123</code> <code>detail/888</code>都会被匹配上,并将<code>123/888</code>作为id参数传递</li><li>其中<code>/detail/:id</code>这个匹配规则被称为动态路由</li></ul><p>动态路由常见于嵌套路由跳转,比如:从歌曲列表页面点击后跳转到歌曲详情页,可以通过路由传递歌曲的ID,访问到不同歌曲的详情页</p><p>我们在之前的HomeRanking榜单中加入列表和点击跳转功能,并编写一个新的组件Detail来接收来自路由的参数</p><p>同样地,<code>react-router-dom</code>为我们提供了从路由获取参数的API:<code>useParams</code>,它是一个Hooks,我们将它应用到之前编写的高级组件<code>withRouter</code>中</p><ul><li>在使用了<code>withRouter</code>的组件中,就可以通过<code>this.props.router.params.xxx</code>获取到当前路由中传递的参数</li><li>使用动态匹配路由时,传递给Route组件的<code>path</code>属性为<code>:xxx</code>,这里是<code>/detail/:id</code></li></ul><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-a15H_" id="tab-Hwc_0Pe" checked="checked"><label for="tab-Hwc_0Pe">withRouter.js</label><input type="radio" name="group-a15H_" id="tab--eFETBH"><label for="tab--eFETBH">HomeRanking.jsx</label><input type="radio" name="group-a15H_" id="tab-UDLWj4B"><label for="tab-UDLWj4B">Detail.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// withRouter.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { useNavigate, useParams } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react-router-dom'</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> withRouter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">WrapperComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
||||
@@ -165,7 +165,7 @@ import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.BFSS5Pox.js";const y
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> router</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { navigate, params, query }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">WrapperComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">props} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">router</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{router} /></span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>需要注意的是,这里的<code>useSearchParams</code>是一个Hooks的常见形态</p><p>它返回一个数组,数组的首位为值,数组的次位为改变值的方法</p><p>与对象解构不同的是,数组结构是对位解构:保证位置一致则值一致,命名随意</p><p>而对象解构恰恰相反,不必保证位置,而需要保证命名一致</p></div><h2 id="路由的配置方式" tabindex="-1">路由的配置方式 <a class="header-anchor" href="#路由的配置方式" aria-label="Permalink to "路由的配置方式""></a></h2><p>至此为止,路由的配置是耦合在<code>App.jsx</code>中的,我们可以将Routes这部分代码抽离出单独的组件,也可以通过配置的方式来完成路由映射关系的编写</p><ul><li>在ReactRouter5版本中,我们可以将路由的映射规则写为JS对象,需要引入第三方库<code>react-router-config</code></li><li>在ReactRouter6版本中,允许我们将其写为配置文件,不需要安装其他内容</li></ul><p>6版本为我们提供了一个API:<code>useRoutes</code>,将我们编写的配置文件传入此函数,可以将其转化为之前编写的组件结构,本质上也是一种语法糖</p><p>需要注意的是,Hooks只能在函数式组件中使用,这里我们将App组件改用FunctionComponent书写了</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-nLlvJ" id="tab-OWj1Rbf" checked="checked"><label for="tab-OWj1Rbf">index.js</label><input type="radio" name="group-nLlvJ" id="tab-o1C-ydU"><label for="tab-o1C-ydU">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// router/index.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</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></div></div><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>需要注意的是,这里的<code>useSearchParams</code>是一个Hooks的常见形态</p><p>它返回一个数组,数组的首位为值,数组的次位为改变值的方法</p><p>与对象解构不同的是,数组结构是对位解构:保证位置一致则值一致,命名随意</p><p>而对象解构恰恰相反,不必保证位置,而需要保证命名一致</p></div><h2 id="路由的配置方式" tabindex="-1">路由的配置方式 <a class="header-anchor" href="#路由的配置方式" aria-label="Permalink to "路由的配置方式""></a></h2><p>至此为止,路由的配置是耦合在<code>App.jsx</code>中的,我们可以将Routes这部分代码抽离出单独的组件,也可以通过配置的方式来完成路由映射关系的编写</p><ul><li>在ReactRouter5版本中,我们可以将路由的映射规则写为JS对象,需要引入第三方库<code>react-router-config</code></li><li>在ReactRouter6版本中,允许我们将其写为配置文件,不需要安装其他内容</li></ul><p>6版本为我们提供了一个API:<code>useRoutes</code>,将我们编写的配置文件传入此函数,可以将其转化为之前编写的组件结构,本质上也是一种语法糖</p><p>需要注意的是,Hooks只能在函数式组件中使用,这里我们将App组件改用FunctionComponent书写了</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-640fi" id="tab-jo9OFfX" checked="checked"><label for="tab-jo9OFfX">index.js</label><input type="radio" name="group-640fi" id="tab-9d-DrrA"><label for="tab-9d-DrrA">App.jsx</label></div><div class="blocks"><div class="language-tsx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// router/index.js</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { Navigate } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'react-router-dom'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Home </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '../views/Home'</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> HomeRanking </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '../views/HomeRanking'</span></span>
|
||||
1
assets/note_React Router.md.CKY65iIZ.lean.js
Normal file
1
assets/note_React Router.md.CKY65iIZ.lean.js
Normal file
@@ -0,0 +1 @@
|
||||
import{_ as s,c as i,o as a,ai as n}from"./chunks/framework.DKE0jNKv.js";const y=JSON.parse('{"title":"React Router","description":"","frontmatter":{},"headers":[],"relativePath":"note/React Router.md","filePath":"note/React Router.md","lastUpdated":1713715656000}'),l={name:"note/React Router.md"},p=n("",71),h=[p];function t(k,e,r,E,d,g){return a(),i("div",null,h)}const o=s(l,[["render",t]]);export{y as __pageData,o as default};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user