TypeScript在React项目中的使用总结
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">序言</span></h2><p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">本文会侧重于TypeScript(以下简称TS)在项目中与React的结合使用情况,而非TS的基本概念。关于TS的类型查看可以使用在线TS工具👉TypeScript游乐场</p>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">React元素相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">React元素相关的类型主要包括<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactNode</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">JSX.Element</code>。</p>
<ul style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: disc" data-tool="mdnice编辑器">
<li><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactNode</code>。表示任意类型的React节点,这是个联合类型,包含情况众多;</li>
<li><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactElement</code>/<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">JSX</code>。从使用表现上来看,可以认为这两者是一致的,属于<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactNode</code>的子集,表示“<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">原生的DOM组件</strong>”或“<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">自定义组件的执行结果</strong>”。</li>
</ul>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">使用示例如下:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> MyComp: React.FC<{ <span class="hljs-attr" style="line-height: 26px">title</span>: string; }> = <span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">{title}</span>) =></span> <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">h2</span>></span>{title}<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"></<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">h2</span>></span></span>;<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// ReactNode</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> a: React.ReactNode =<br> <span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span> ||<br> <span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">undefined</span> || <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>></span>hello<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"></<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>></span></span> || <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">MyComp</span> <span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">title</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"world"</span> /></span></span> ||<br> <span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"abc"</span> ||<br> <span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">123</span> ||<br> <span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">true</span>;<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// ReactElement和JSX.Element</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> b: React.ReactElement = <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>></span>hello world<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"></<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>></span></span> || <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">MyComp</span> <span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">title</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"good"</span> /></span></span>;<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> c: JSX.Element = <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">MyComp</span> <span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">title</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"good"</span> /></span></span> || <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>></span>hello world<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"></<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>></span></span>;<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">原生DOM相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">原生的 DOM 相关的类型,主要有以下这么几个:<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Element</code>、 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLxxxElment</code>。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">简单来说: <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Element = HTMLElement + SVGElement</code>。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器"><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">SVGElement</code>一般开发比较少用到,而<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLElement</code>却非常常见,它的子类型包括<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLDivElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLInputElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLSpanElement</code>等等。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">因此我们可以得知,其关系为:<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Element</code> > <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLElement</code> > <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLxxxElement</code>,原则上是尽量写详细。</p>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">React合成事件相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">在 React 中,原生事件被处理成了<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">React 事件</strong>,其内部是通过事件委托来优化内存,减少DOM事件绑定的。言归正传,React 事件的通用格式为<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Event</code>,常见的有<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">MouseEvent</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ChangeEvent</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">TouchEvent</code>,是一个泛型类型,泛型变量为触发该事件的 DOM 元素类型。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">示例如下:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// input输入框输入文字</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> handleInputChange = <span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">evt: React.ChangeEvent<HTMLInputElement></span>) =></span> {<br> <span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(evt);<br>};<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// button按钮点击</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> handleButtonClick = <span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">evt: React.MouseEvent<HTMLButtonElement></span>) =></span> {<br> <span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(evt);<br>};<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 移动端触摸div</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> handleDivTouch = <span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">evt: React.TouchEvent<HTMLDivElement></span>) =></span> {<br> <span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(evt);<br>};<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">与hooks的结合</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">在hooks中,并非全部钩子都与TS有强关联,比如<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">useEffect</code>就不依赖TS做类型定义,我们挑选比较常见的几个和TS强关联的钩子来看看。</p>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">useState</span></h3>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" data-tool="mdnice编辑器">
<li>如果初始值能说明类型,就不用给 useState 指明泛型变量;</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// ❌这样写是不必要的,因为初始值0已经能说明count类型</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> = useState<number>(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// ✅这样写好点</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> = useState(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br></code></pre>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" start="2" data-tool="mdnice编辑器">
<li>如果初始值是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">null</code> 或 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">undefined</code>,那就要通过泛型手动传入你期望的类型,并在访问属性的时候通过可选链来规避语法错误。</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px">interface IUser {<br> <span class="hljs-attr" style="line-height: 26px">name</span>: string;<br> age: number;<br>}<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> = React.useState<IUser | <span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span>>(<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span>);<br><br><span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(user?.name);<br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">useRef</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">这个 hook 比较特别,它通常有两种用途:</p>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" data-tool="mdnice编辑器">
<li>用来连接 DOM,以获取到 DOM 元素;</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 连接DOM,初始值赋值为null,不能是undefined,如要指明泛型变量需要具体到HTMLxxxElement</span><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 如果我们确定inputRef.current在调用时一定是有值的,可以使用非空断言,在null后添加!</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> inputRef = useRef<HTMLInputElement>(<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span>!);<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> handleClick = <span class="hljs-function" style="line-height: 26px"><span class="hljs-params" style="line-height: 26px">()</span> =></span> {<br> inputRef.current.focus(); <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 当然不用非空断言,用inputEl.current?.focus()可选链也是可以的</span><br>}<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span> (<br> <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">input</span> <span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">ref</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">{inputRef}</span> /></span></span><br> <span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"><<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">button</span> <span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">onClick</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">{handleClick}</span>></span>点击<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px"></<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">button</span>></span></span><br>)<br></code></pre>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" start="2" data-tool="mdnice编辑器">
<li>用来存储变量,由于是存储在函数式组件的外部,比起 useState,它不会存在异步更新的问题,也不会存在由<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">capture-value</code>特性引发的过时变量的问题,但是要注意赋值后由于ref引用没变,不会引起重渲染。</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 通过初始值来自动指明泛型变量类型</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> sum = useRef(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 通过.current直接赋值</span><br>sum.current = <span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">3</span>;<br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 不存在异步更新问题</span><br><span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(sum.current); <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 3</span><br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">useSelector</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">useSelector用于获取store中的状态,其第一个固定参数为函数,函数的入参即为store,而store的类型<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">RootState</code>需要在store中提前定义好,一种常见的定义如下:</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">在store.ts中:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> store = createStore(rootReducer);<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span> type RootState = ReturnType<<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">typeof</span> rootReducer>;<br></code></pre>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">使用时:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> { var1, var2 } = useSelector(<span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">store: RootState</span>) =></span> store.xxx);<br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">自定义 hook</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">如果我们需要仿照 useState 的形式,返回一个数组出去,则需要在返回值的末尾使用<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">as const</code>,标记这个返回值是个常量,否则返回的值将被推断成联合类型。</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> useInfo = <span class="hljs-function" style="line-height: 26px"><span class="hljs-params" style="line-height: 26px">()</span> =></span> {<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> = useState(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br><br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">as</span> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>; <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 类型为一个元组,</span><br>};<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">redux相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">对于<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">action</code>的定义,我们可以使用官方暴露的<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">AnyAction</code>,放宽对于<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">action</code>内部键值对的限制,如下:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">import</span> { AnyAction } <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">from</span> <span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"redux"</span>;<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> DEF_STATE = {<br> <span class="hljs-attr" style="line-height: 26px">count</span>: <span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>,<br> <span class="hljs-attr" style="line-height: 26px">type</span>: <span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'integer'</span><br>};<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 使用redux的AnyAction放宽限制</span><br><span class="hljs-function" style="line-height: 26px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">function</span> <span class="hljs-title" style="color: rgba(153, 0, 0, 1); font-weight: bold; line-height: 26px">countReducer</span>(<span class="hljs-params" style="line-height: 26px">state = DEF_STATE, action: AnyAction</span>) </span>{<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">switch</span> (action.type) {<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">case</span> <span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"INCREASE_COUNT"</span>:<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span> {<br> ...state,<br> <span class="hljs-attr" style="line-height: 26px">count</span>: state.count + <span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">1</span>,<br> };<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">case</span> <span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"DECREASE_COUNT"</span>:<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span> {<br> ...state,<br> <span class="hljs-attr" style="line-height: 26px">count</span>: state.count - <span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">1</span>,<br> };<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">default</span>:<br> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span> state;<br> }<br>}<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span> <span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">default</span> countReducer;<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">规约</span></h2>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" data-tool="mdnice编辑器">
<li>子组件的入参命名为<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">[组件名]Props</code>,如:</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 比如当前组件名为InfoCard</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span> interface InfoCardProps {<br> <span class="hljs-attr" style="line-height: 26px">name</span>: string;<br> age: number;<br>}<br></code></pre>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" start="2" data-tool="mdnice编辑器">
<li>interface接口类型以大写开头;</li>
<li>为后端接口的出入参书写interface,同时使用利于编辑器提示的jsdoc风格做注释,如:</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span> interface GetUserInfoReqParams {<br> <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">/** 名字 */</span><br> <span class="hljs-attr" style="line-height: 26px">name</span>: string;<br> <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">/** 年龄 */</span><br> age: number;<br> <span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">/** 性别 */</span><br> gender: string;<br>}<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">其他</span></h2>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">键名或键值不确定如何处理?</span></h3>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 表示键名不确定,键值限制为number类型</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span> interface NotSureAboutKey {<br> : number;<br>}<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 当键名键值都不确定时,以下接口对任何对象都是适用的</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span> interface AllNotSure {<br> : any;<br>}<br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">如何在接口中使用泛型变量?</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">所谓泛型,就是预定义类型。它的目的是:<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">达到类型定义的局部灵活,提高复用性</strong>。我们通常会在接口中使用泛型,如:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 通常,我们会为接口的泛型变量指定一个默认类型</span><br>interface IHuman<T = unknown> {<br> <span class="hljs-attr" style="line-height: 26px">name</span>: string;<br> age: number;<br> gender: T;<br>}<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">// 其他地方使用时</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span> youngMan: IHuman<string> = {<br> <span class="hljs-attr" style="line-height: 26px">name</span>: <span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'zhangsan'</span>,<br> <span class="hljs-attr" style="line-height: 26px">age</span>: <span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">18</span>,<br> <span class="hljs-attr" style="line-height: 26px">gender</span>: <span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'male'</span><br>}<br></code></pre><br><br>
来源:https://www.cnblogs.com/zhangnan35/p/14685651.html
頁:
[1]