<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 19.使用模板字面值和標簽模板 > 原文: [http://exploringjs.com/impatient-js/ch_template-literals.html](http://exploringjs.com/impatient-js/ch_template-literals.html) > > 貢獻者:[飛龍](https://github.com/wizardforcel) 在我們深入研究兩個特性*模板字面值*和*標簽模板*之前,讓我們首先檢查術語*模板*的多重含義。 ### 19.1。消歧:“模板” 盡管所有名稱中都有*模板*并且所有這些模板看起來都相似,但以下三件事情有很大不同: * *網頁模板*是從數據到文本的函數。它經常用于 Web 開發,通常通過文本文件定義。例如,以下文本定義了庫 [Handlebars](https://handlebarsjs.com) 的模板: ```html <div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div> ``` * *模板字面值*是具有更多功能的字符串字面值,例如插值。它由反引號分隔: ```js const num = 5; assert.equal(`Count: ${num}!`, 'Count: 5!'); ``` * *標簽模板*是一個函數,后跟一個模板字面值。它導致調用該函數,并將模板字面值的內容作為參數提供給它。 ```js const getArgs = (...args) => args; assert.deepEqual( getArgs`Count: ${5}!`, [['Count: ', '!'], 5] ); ``` 請注意,`getArgs()`接收字面值的文本和通過`${}`插入的數據。 ### 19.2。模板字面值 與普通字符串字面值相比,模板字面值有兩個主要好處。 首先,它們支持*字符串插值*:如果將表達式放在`${`和`}`中,則可以插入表達式: ```js const MAX = 100; function doSomeWork(x) { if (x > MAX) { throw new Error(`At most ${MAX} allowed: ${x}!`); } // ··· } assert.throws( () => doSomeWork(101), {message: 'At most 100 allowed: 101!'}); ``` 其次,模板字面值可以跨越多行: ```js const str = `this is a text with multiple lines`; ``` 模板字面值總是產生字符串。 ### 19.3。標簽模板 行 A 中的表達式是*標簽模板*: ```js const first = 'Lisa'; const last = 'Simpson'; const result = tagFunction`Hello ${first} ${last}!`; // A ``` 最后一行相當于: ```js const result = tagFunction(['Hello ', ' ', '!'], first, last); ``` `tagFunction`的參數是: * 模板字符串(第一個參數):一個包含插值(`${...}`)周圍文本片段的數組。 * 在示例中:`['Hello ', ' ', '!']` * 替換值(剩余參數):插值。 * 在示例中:`'Lisa'`和`'Simpson'` 字面值的靜態(固定)部分(模板字符串)與動態部分(替換)分開。 `tagFunction`可以返回任意值,并接受模板字符串的兩個視圖作為輸入(只有熟視圖顯示在上一個示例中): * *熟視圖*,其中: * `\t`變為制表符 * `\\`變為一個反斜杠 * *原始視圖*,其中: * `\t`變為斜線后跟`t` * `\\`變為兩個反斜杠 原始視圖通過`String.raw`(稍后描述)和類似的應用提供原始字符串字面值。 標簽模板非常適合支持小型嵌入式語言(所謂的*領域特定語言*)。我們將繼續舉幾個例子。 #### 19.3.1。標簽函數庫:lit-html [lit-html](https://github.com/Polymer/lit-html) 是一個基于標簽模板的模板庫,由[前端框架 Polymer ](https://www.polymer-project.org/)使用: ```js import {html, render} from 'lit-html'; const template = (items) => html` <ul> ${ repeat(items, (item) => item.id, (item, index) => html`<li>${index}. ${item.name}</li>` ) } </ul> `; ``` `repeat()`是用于循環的自定義函數。它的第二個參數為第 3 個參數返回的值生成唯一鍵。請注意該參數使用的嵌套標簽模板。 #### 19.3.2。標簽函數庫:re-template-tag re-template-tag 是一個用于編寫正則表達式的簡單庫。帶有`re`標簽的模板會生成正則表達式。主要的好處是你可以通過`${}`插入正則表達式和純文本(參見`RE_DATE`): ```js import {re} from 're-template-tag'; const RE_YEAR = re`(?<year>[0-9]{4})`; const RE_MONTH = re`(?<month>[0-9]{2})`; const RE_DAY = re`(?<day>[0-9]{2})`; const RE_DATE = re`/${RE_YEAR}-${RE_MONTH}-${RE_DAY}/u`; const match = RE_DATE.exec('2017-01-27'); assert.equal(match.groups.year, '2017'); ``` #### 19.3.3。標簽函數庫:graphql-tag [graphql-tag 庫](https://github.com/apollographql/graphql-tag) 允許您通過標簽模板創建 GraphQL 查詢: ```js import gql from 'graphql-tag'; const query = gql` { user(id: 5) { firstName lastName } } `; ``` 此外,還有用于在 Babel,TypeScript 等中預編譯此類查詢的插件。 ### 19.4。原始字符串字面值 原始字符串字面值通過標簽函數`String.raw`實現。它們是一個字符串字面值,其中反斜杠不做任何特殊操作(例如轉義字符等): ```js assert.equal(String.raw`\back`, '\\back'); ``` 一個有幫助的例子是帶有正則表達式的字符串: ```js const regex1 = /^\./; const regex2 = new RegExp('^\\.'); const regex3 = new RegExp(String.raw`^\.`); ``` 所有三個正則表達式都是等價的,您可以看到使用字符串字面值,您必須編寫兩次反斜杠才能為該字面值轉義它。使用原始字符串字面值,您不必這樣做。 原始字符串字面值有用的另一個示例是 Windows 路徑: ```js const WIN_PATH = String.raw`C:\foo\bar`; assert.equal(WIN_PATH, 'C:\\foo\\bar'); ``` ### 19.5。 (高級) 所有剩余部分都是高級的 ### 19.6。多行模板字面值和縮進 如果將多行文本放在模板字面值中,則會出現兩個目標沖突:一方面,文本應縮進來適合源代碼。另一方面,它的行應該從最左邊的列開始。 例如: ```js function div(text) { return ` <div> ${text} </div> `; } console.log('Output:'); console.log(div('Hello!') // Replace spaces with mid-dots: .replace(/ /g, '·') // Replace \n with #\n: .replace(/\n/g, '#\n')); ``` 由于縮進,模板字面值很適合源代碼。但輸出也是縮進的。而且我們不希望開頭的回車,以及末尾的回車加上兩個空格。 ``` Output: # ····<div># ······Hello!# ····</div># ·· ``` 有兩種方法可以解決這個問題:通過標簽模板或修剪模板字面值的結果。 #### 19.6.1。修復:用于去縮進的模板標簽 第一個修復是使用自定義模板標簽來刪除不需要的空格。它使用初始換行符后面的第一行來確定文本從哪一列開始,并去掉各處的縮進。它還刪除了最開始的換行符和最后的縮進。這樣的模板標簽之一是 Desmond Brand 的[`dedent`](https://github.com/dmnd/dedent): ```js import dedent from 'dedent'; function divDedented(text) { return dedent` <div> ${text} </div> `; } console.log('Output:'); console.log(divDedented('Hello!')); ``` 這次,輸出沒有縮進: ``` Output: <div> Hello! </div> ``` #### 19.6.2。修復:`.trim()` 第二個修復更快,但也更臟: ```js function divDedented(text) { return ` <div> ${text} </div> `.trim(); } console.log('Output:'); console.log(divDedented('Hello!')); ``` 字符串方法`.trim()`在開頭和結尾刪除多余的空格,但內容本身必須從最左邊的列開始。此解決方案的優點是不需要自定義標簽函數。缺點是它看起來很難看。 輸出看起來與`dedent`一樣(但是,最后沒有換行符): ``` Output: <div> Hello! </div> ``` ### 19.7。通過模板字面值進行簡單的模板化 雖然模板字面值看起來像 Web 模板,但是如何將它們用于(web)模板并不是很明顯:Web 模板從對象獲取其數據,而模板字面值從變量獲取其數據。解決方案是在函數體中使用模板字面值,其參數接收模板數據。例如: ```js const tmpl = (data) => `Hello ${data.name}!`; assert.equal(tmpl({name: 'Jane'}), 'Hello Jane!'); ``` #### 19.7.1。一個更復雜的例子 作為一個更復雜的例子,我們想要一個地址數組并生成一個 HTML 表。這是數組: ```js const addresses = [ { first: '<Jane>', last: 'Bond' }, { first: 'Lars', last: '<Croft>' }, ]; ``` 生成 HTML 表的函數`tmpl()`如下所示。 ```js const tmpl = (addrs) => ` <table> ${addrs.map( (addr) => ` <tr> <td>${escapeHtml(addr.first)}</td> <td>${escapeHtml(addr.last)}</td> </tr> `.trim() ).join('')} </table> `.trim(); ``` `tmpl()`采取以下步驟: * `<table>`內的文本是通過單個地址(第 4 行)的嵌套模板函數生成的。注意它最后如何使用字符串方法`.trim()`來刪除不必要的空格。 * 嵌套模板函數通過數組方法`.map()`(第 3 行)應用于 Array `addrs`的每個元素。 * 生成的(字符串)數組通過數組方法`.join()`(第 10 行)轉換為字符串。 * 輔助函數`escapeHtml()`用于轉義特殊 HTML 字符(第 6 行和第 7 行)。其實現將在下一節中介紹。 這是如何使用地址調用`tmpl()`并記錄結果: ```js console.log(tmpl(addresses)); ``` 輸出是: ```html <table> <tr> <td>&lt;Jane&gt;</td> <td>Bond</td> </tr><tr> <td>Lars</td> <td>&lt;Croft&gt;</td> </tr> </table> ``` #### 19.7.2。簡單的 HTML 轉義 ```js function escapeHtml(str) { return str .replace(/&/g, '&amp;') // first! .replace(/>/g, '&gt;') .replace(/</g, '&lt;') .replace(/"/g, '&quot;') .replace(/'/g, '&#39;') .replace(/`/g, '&#96;') ; } ``` ![](https://img.kancloud.cn/3e/d5/3ed5755d562179ae6c199264f5e21157.svg) **練習:HTML 模板** 有獎練習挑戰:`exercises/template-literals/templating_test.js` ### 19.8。進一步閱讀 * [“探索 ES6”](http://exploringjs.com/es6/ch_template-literals.html)中描述了如何實現自己的標簽函數。 ![](https://img.kancloud.cn/ff/a8/ffa8e16628cad59b09c786b836722faa.svg) **測驗** 參見[測驗應用程序](ch_quizzes-exercises.html#quizzes)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看