日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ElementUI 组件库 md-loader 的解析和优化

發布時間:2023/12/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ElementUI 组件库 md-loader 的解析和优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信?ruochuan12?參與,已進行三個月了,大家一起交流學習,共同進步。


背景

相信很多同學在學習 webpack 的時候,對 loader 的概念應該有所了解,它用于模塊源碼的轉換,描述了 webpack 如何處理非 JavaScript 模塊,常見的有 css-loader、babel-loader、url-loader、vue-loader 等。

大部分 loader 已經滿足我們的日常開發需求,不過有些時候我們仍然需要自定義 loader。為了讓你了解如何開發一個 webpack loader,我決定從 ElementUI 組件庫的 md-loader 入手,帶你去了解其中的實現原理,以及在它的基礎上,如何做進一步的優化。

文檔的設計

對于一個組件的文檔,首先我們要考慮的是如何更好地展現組件的功能,其次要考慮的是如何更方便地做文檔維護。

想要編寫好一個組件的文檔,需要做好以下幾點:

1.功能描述

對組件功能、使用場景做詳細的描述。

2.demo 演示

直觀地讓用戶感受到組件的功能,并且能展示 demo 對應的代碼。

3.接口說明

寫清楚組件支持的屬性、方法、事件等。

那么,如何方便地維護文檔呢?

ElementUI 組件庫的文檔也是一個 Vue 項目,組件的文檔頁面是單獨的路由視圖,而文檔是用 markdown 文件來描述的,在文檔內部,不僅包含了對組件的功能以及接口的描述,還可以通過編寫 vue 組件的方式直接編寫組件的 demo,這種方式對于組件文檔的維護還是比較方便的。

以 ElementUI 組件庫 Alter 組件為例:

##?Alert?警告用于頁面中展示重要的提示信息。###?基本用法頁面中的非浮層元素,不會自動消失。:::demo?Alert?組件提供四種主題,由`type`屬性指定,默認值為`info`。```html <template><el-alerttitle="成功提示的文案"type="success"></el-alert><el-alerttitle="消息提示的文案"type="info"></el-alert><el-alerttitle="警告提示的文案"type="warning"></el-alert><el-alerttitle="錯誤提示的文案"type="error"></el-alert> </template> ``` :::

最終它在頁面上的展示效果如下:

可以看到,組件的路由視圖對應的是一個 markdown 文件,而在我們通常的認知中,Vue 的路由視圖應該對應的是一個 Vue 組件。

在 ElementUI 內部,是通過 require.ensure 的方式去加載一個 .md 文件,它的返回值會作為路由視圖對應的異步組件。

const?LOAD_DOCS_MAP?=?{'zh-CN':?path?=>?{return?r?=>?require.ensure([],?()?=>r(require(`./docs/zh-CN${path}.md`)),'zh-CN');},//?... }

因此內部就必須要把 markdown 文件轉換一個 Vue 組件,我們可以借助 webpack loader 來實現這一需求。

自定義 md-loader

首先,在 webpack 的配置規則中,需要指定 .md 文件應用的 loader:

{test:?/\.md$/,use:?[{loader:?'vue-loader',options:?{compilerOptions:?{preserveWhitespace:?false}}},{loader:?path.resolve(__dirname,?'./md-loader/index.js')}] }

接下來,我們就來分析 md-loader 的源碼實現:

const?{stripScript,stripTemplate,genInlineComponentText }?=?require('./util'); const?md?=?require('./config');module.exports?=?function(source)?{const?content?=?md.render(source);const?startTag?=?'<!--element-demo:';const?startTagLen?=?startTag.length;const?endTag?=?':element-demo-->';const?endTagLen?=?endTag.length;let?componenetsString?=?'';let?id?=?0;?//?demo?的?idlet?output?=?[];?//?輸出的內容let?start?=?0;?//?字符串開始位置let?commentStart?=?content.indexOf(startTag);let?commentEnd?=?content.indexOf(endTag,?commentStart?+?startTagLen);while?(commentStart?!==?-1?&&?commentEnd?!==?-1)?{output.push(content.slice(start,?commentStart));const?commentContent?=?content.slice(commentStart?+?startTagLen,?commentEnd);const?html?=?stripTemplate(commentContent);const?script?=?stripScript(commentContent);let?demoComponentContent?=?genInlineComponentText(html,?script);const?demoComponentName?=?`element-demo${id}`;output.push(`<template?slot="source"><${demoComponentName}?/></template>`);componenetsString?+=?`${JSON.stringify(demoComponentName)}:?${demoComponentContent},`;//?重新計算下一次的位置id++;start?=?commentEnd?+?endTagLen;commentStart?=?content.indexOf(startTag,?start);commentEnd?=?content.indexOf(endTag,?commentStart?+?startTagLen);}//?僅允許在?demo?不存在時,才可以在?Markdown?中寫?script?標簽let?pageScript?=?'';if?(componenetsString)?{pageScript?=?`<script>export?default?{name:?'component-doc',components:?{${componenetsString}}}</script>`;}?else?if?(content.indexOf('<script>')?===?0)?{start?=?content.indexOf('</script>')?+?'</script>'.length;pageScript?=?content.slice(0,?start);}output.push(content.slice(start));return?`<template><section?class="content?element-doc">${output.join('')}</section></template>${pageScript}`; };

md-loader 要做的事情,就是把 markdown 語法的字符串,轉成 Vue 組件字符串。轉換的過程可以拆成三個步驟:markdown 渲染,demo 子組件的處理,構造完整的組件。接下來我們就來依次分析這三個步驟。

markdown 渲染

markdown 文件內容會渲染生成對應的 HTML,它是通過下面這段代碼完成的:

const?md?=?require('./config'); module.exports?=?function(source)?{const?content?=?md.render(source); }

而 md 對象的來源如下:

const?Config?=?require('markdown-it-chain'); const?anchorPlugin?=?require('markdown-it-anchor'); const?slugify?=?require('transliteration').slugify; const?containers?=?require('./containers'); const?overWriteFenceRule?=?require('./fence');const?config?=?new?Config();config.options.html(true).end().plugin('anchor').use(anchorPlugin,?[{level:?2,slugify:?slugify,permalink:?true,permalinkBefore:?true}]).end().plugin('containers').use(containers).end();const?md?=?config.toMd(); overWriteFenceRule(md);module.exports?=?md;

首先實例化了 config 對象,它依賴于 markdown-it-chain,通過 webpack chain 的鏈式 API,配置了 markdown-it 的插件。而 md 對象指向的就是 markdown-it 的實例。

markdown-it 的實例提供了很多 API,具體可以參考它的官網文檔。其中 md.render 就是把 markdown 字符串渲染生成 HTML。

不過我們注意到,組件文檔使用了一些非標準的 markdown 語法,比如:

:::demo :::

它實際上是一個 markdown 的自定義容器,借助于 markdown-it-container 插件,就可以解析這個自定義容器:

const?mdContainer?=?require('markdown-it-container');module.exports?=?md?=>?{md.use(mdContainer,?'demo',?{validate(params)?{return?params.trim().match(/^demo\s*(.*)$/);},render(tokens,?idx)?{const?m?=?tokens[idx].info.trim().match(/^demo\s*(.*)$/);if?(tokens[idx].nesting?===?1)?{const?description?=?m?&&?m.length?>?1???m[1]?:?'';const?content?=?tokens[idx?+?1].type?===?'fence'???tokens[idx?+?1].content?:?'';return?`<demo-block>${description???`<div>${md.render(description)}</div>`?:?''}<!--element-demo:?${content}:element-demo-->`;}return?'</demo-block>';}});md.use(mdContainer,?'tip');md.use(mdContainer,?'warning'); };

可以看到,對于 demo 這個自定義容器,它會解析 demo 后面緊接著的描述字符串以及 code fence,并生成新的 HTML 字符串。

此外,code fence 也定義了新的渲染策略:

//?覆蓋默認的?fence?渲染策略 module.exports?=?md?=>?{const?defaultRender?=?md.renderer.rules.fence;md.renderer.rules.fence?=?(tokens,?idx,?options,?env,?self)?=>?{const?token?=?tokens[idx];//?判斷該?fence?是否在?:::demo?內const?prevToken?=?tokens[idx?-?1];const?isInDemoContainer?=?prevToken?&&?prevToken.nesting?===?1?&&?prevToken.info.trim().match(/^demo\s*(.*)$/);if?(token.info?===?'html'?&&?isInDemoContainer)?{return?`<template?slot="highlight"><pre?v-pre><code?class="html">${md.utils.escapeHtml(token.content)}</code></pre></template>`;}return?defaultRender(tokens,?idx,?options,?env,?self);}; };

對于在 demo 容器內且帶有 html 標記的 code fence,會做一層特殊處理。

對于我們前面的示例:

:::demo?Alert?組件提供四種主題,由`type`屬性指定,默認值為`info`。```html <template><el-alerttitle="成功提示的文案"type="success"></el-alert><el-alerttitle="消息提示的文案"type="info"></el-alert><el-alerttitle="警告提示的文案"type="warning"></el-alert><el-alerttitle="錯誤提示的文案"type="error"></el-alert> </template> ``` :::

經過解析后,生成的 HTML 大致如下:

<demo-block><div><p>Alert?組件提供四種主題,由<code>type</code>屬性指定,默認值為<code>info</code>。</p></div><!--element-demo:?<template><el-alerttitle="成功提示的文案"type="success"></el-alert><el-alerttitle="消息提示的文案"type="info"></el-alert><el-alerttitle="警告提示的文案"type="warning"></el-alert><el-alerttitle="錯誤提示的文案"type="error"></el-alert></template>:element-demo--><template?slot="highlight"><pre?v-pre><code?class="html">&lt;template&gt;&lt;el-alerttitle=&quot;成功提示的文案&quot;type=&quot;success&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;消息提示的文案&quot;type=&quot;info&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;警告提示的文案&quot;type=&quot;warning&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;錯誤提示的文案&quot;type=&quot;error&quot;&gt;&lt;/el-alert&gt;&lt;/template&gt;</code></pre></template> </demo-block>

demo 子組件的處理

目前我們了解到,每一個 demo 容器對應一個示例,它會解析生成對應的 HTML,最終會通過 demo-block 組件渲染,這個組件是預先定義好的 Vue 組件:

<template><divclass="demo-block":class="[blockClass,?{?'hover':?hovering?}]"@mouseenter="hovering?=?true"@mouseleave="hovering?=?false"><div?class="source"><slot?name="source"></slot></div><div?class="meta"?ref="meta"><div?class="description"?v-if="$slots.default"><slot></slot></div><div?class="highlight"><slot?name="highlight"></slot></div></div><divclass="demo-block-control"ref="control":class="{?'is-fixed':?fixedControl?}"@click="isExpanded?=?!isExpanded"><transition?name="arrow-slide"><i?:class="[iconClass,?{?'hovering':?hovering?}]"></i></transition><transition?name="text-slide"><span?v-show="hovering">{{?controlText?}}</span></transition><el-tooltip?effect="dark"?:content="langConfig['tooltip-text']"?placement="right"><transition?name="text-slide"><el-buttonv-show="hovering?||?isExpanded"size="small"type="text"class="control-button"@click.stop="goCodepen">{{?langConfig['button-text']?}}</el-button></transition></el-tooltip></div></div> </template>

demo-block 支持了多個插槽,其中默認插槽對應了組件的描述部分;highlight 插槽對應組件高亮的代碼部分;source 插槽對應 demo 實現的部分。

因此,目前我們生成的 HTML 字符串還不能夠直接被 demo-block 組件使用,需要進一步的處理:

module.exports?=?function(source)?{const?content?=?md.render(source);const?startTag?=?'<!--element-demo:';const?startTagLen?=?startTag.length;const?endTag?=?':element-demo-->';const?endTagLen?=?endTag.length;let?componenetsString?=?'';let?id?=?0;?//?demo?的?idlet?output?=?[];?//?輸出的內容let?start?=?0;?//?字符串開始位置let?commentStart?=?content.indexOf(startTag);let?commentEnd?=?content.indexOf(endTag,?commentStart?+?startTagLen);while?(commentStart?!==?-1?&&?commentEnd?!==?-1)?{output.push(content.slice(start,?commentStart));const?commentContent?=?content.slice(commentStart?+?startTagLen,?commentEnd);const?html?=?stripTemplate(commentContent);const?script?=?stripScript(commentContent);let?demoComponentContent?=?genInlineComponentText(html,?script);const?demoComponentName?=?`element-demo${id}`;output.push(`<template?slot="source"><${demoComponentName}?/></template>`);componenetsString?+=?`${JSON.stringify(demoComponentName)}:?${demoComponentContent},`;//?重新計算下一次的位置id++;start?=?commentEnd?+?endTagLen;commentStart?=?content.indexOf(startTag,?start);commentEnd?=?content.indexOf(endTag,?commentStart?+?startTagLen);}//?處理?script//?...output.push(content.slice(start)) };

其中 output 表示要輸出的模板內容,componenetsString 表示要輸出的腳本內容。這段代碼要做的事情就是填充 demo-block 組件內部的 source 插槽,并且插槽的內容是一個 demo 子組件。

由于前面生成的 HTML 中包含了 <!--element-demo: ?和 :element-demo--> 注釋字符串,因此就可以找到注釋字符串的位置,通過字符串截取的方式來獲取注釋內外的內容。

對于注釋內的內容,會提取其中的模板部分和 JS 部分,然后構造出一個內聯的組件字符串。

前面的示例經過處理,output 對應的內容如下:

[`<demo-block><div><p>Alert 組件提供四種主題,由<code>type</code>屬性指定,默認值為<code>info</code>。</p></div>`,`<template?slot="source"><element-demo0?/></template>`,?`<template?slot="highlight"><pre?v-pre><code?class="html">&lt;template&gt;&lt;el-alerttitle=&quot;成功提示的文案&quot;type=&quot;success&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;消息提示的文案&quot;type=&quot;info&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;警告提示的文案&quot;type=&quot;warning&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;錯誤提示的文案&quot;type=&quot;error&quot;&gt;&lt;/el-alert&gt;&lt;/template&gt;</code></pre></template><demo-block>` ]

處理后的 demo-block 就變成一個標準的 Vue 組件的應用了。

componenetsString 對應的內容如下:

`"element-demo0":?(function()?{var?render?=?function()?{var?_vm?=?thisvar?_h?=?_vm.$createElementvar?_c?=?_vm._self._c?||?_hreturn?_c("div",[[_c("el-alert",?{?attrs:?{?title:?"成功提示的文案",?type:?"success"?}?}),_vm._v("?"),_c("el-alert",?{?attrs:?{?title:?"消息提示的文案",?type:?"info"?}?}),_vm._v("?"),_c("el-alert",?{?attrs:?{?title:?"警告提示的文案",?type:?"warning"?}?}),_vm._v("?"),_c("el-alert",?{?attrs:?{?title:?"錯誤提示的文案",?type:?"error"?}?})]],2)??}??var?staticRenderFns?=?[]render._withStripped?=?trueconst?democomponentExport?=?{}return?{render,staticRenderFns,...democomponentExport} })(),`

通過內聯的方式定義了 element-demo0 子組件的實現。

示例只是處理了單個 demo 子組件,如果有多個 demo 容器,就可以通過循環查找注釋字符串 element-demo:,處理所有的 demo-block。

構造完整的組件

module.exports?=?function(source)?{const?content?=?md.render(source);let?componenetsString?=?'';let?output?=?[];let?start?=?0;//?循環處理?demo?子組件//?...let?pageScript?=?'';if?(componenetsString)?{pageScript?=?`<script>export?default?{name:?'component-doc',components:?{${componenetsString}}}</script>`;}?else?if?(content.indexOf('<script>')?===?0)?{start?=?content.indexOf('</script>')?+?'</script>'.length;pageScript?=?content.slice(0,?start);}output.push(content.slice(start));return?`<template><section?class="content?element-doc">${output.join('')}</section></template>${pageScript}`; };

可以看到,output 負責組件的模板定義,pageScript 負責組件的腳本定義,最終會通過字符串拼接的方式,返回完整的組件定義。

對于最開始完整的示例而言,經過 md-loader 處理的結果如下:

<template><section?class="content?element-doc"><h2?id="alert-jing-gao"><a?class="header-anchor"?href="#alert-jing-gao"?aria-hidden="true">?</a>?Alert?警告</h2><p>用于頁面中展示重要的提示信息。</p><h3?id="ji-ben-yong-fa"><a?class="header-anchor"?href="#ji-ben-yong-fa"?aria-hidden="true">?</a>?基本用法</h3><p>頁面中的非浮層元素,不會自動消失。</p><demo-block><div><p>Alert?組件提供四種主題,由<code>type</code>屬性指定,默認值為<code>info</code>。</p></div><template?slot="source"><element-demo0/></template><template?slot="highlight"><pre?v-pre><code?class="html">&lt;template&gt;&lt;el-alerttitle=&quot;成功提示的文案&quot;type=&quot;success&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;消息提示的文案&quot;type=&quot;info&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;警告提示的文案&quot;type=&quot;warning&quot;&gt;&lt;/el-alert&gt;&lt;el-alerttitle=&quot;錯誤提示的文案&quot;type=&quot;error&quot;&gt;&lt;/el-alert&gt;&lt;/template&gt;</code></pre></template></demo-block></section> </template> <script>export?default?{name:?'component-doc',components:?{"element-demo0":?(function()?{var?render?=?function()?{var?_vm?=?thisvar?_h?=?_vm.$createElementvar?_c?=?_vm._self._c?||?_hreturn?_c("div",[[_c("el-alert",?{?attrs:?{?title:?"成功提示的文案",?type:?"success"?}?}),_vm._v("?"),_c("el-alert",?{?attrs:?{?title:?"消息提示的文案",?type:?"info"?}?}),_vm._v("?"),_c("el-alert",?{?attrs:?{?title:?"警告提示的文案",?type:?"warning"?}?}),_vm._v("?"),_c("el-alert",?{?attrs:?{?title:?"錯誤提示的文案",?type:?"error"?}?})]],2)}var?staticRenderFns?=?[]render._withStripped?=?trueconst?democomponentExport?=?{}return?{render,staticRenderFns,...democomponentExport}})(),}} </script>

顯然,經過 md-loader 處理后原來 markdown 語法的字符串變成了一個 Vue 組件定義的字符串,就可以交給 vue-loader 繼續處理了。

文檔的優化

ElementUI 文檔的設計確實巧妙,由于我們研發的 ZoomUI 是 fork 自 ElementUI 的,很長一段時間,我們也沿用了 ElementUI 文檔的編寫方式。

但是隨著我們自研的組件越來越多,組件使用的場景也越來越豐富,我們對于文檔編寫和維護的需求也越來越多。

我發現在現有模式下寫文檔有幾個不爽的點:

1.在 .md 中寫 Vue 組件不方便,沒法格式化代碼,IDE 的智能提示不夠友好。

2.在 demo 中寫 style 是無效的,需要在外部的 css 文件另外定義樣式。

3.中英文文檔需要分別寫 demo,修改一處沒法自動同步到另一處。

我認為理想中編寫一個組件的文檔的方式是這樣的:

##?Select?選擇器當選項過多時,使用下拉菜單展示并選擇內容。###?基礎用法適用廣泛的基礎單選。:::demo?`v-model`?的值為當前被選中的?`zm-option`?的?`value`?屬性值。```html <basic/> ``` :::###?有禁用選項:::demo?在?`zm-option`?中,設定?`disabled`?值為?`true`,即可禁用該選項。 ```html <disabled/> ``` :::

所有組件的 demo 拆成一個個 Vue 組件,然后在 markdown 文檔中引入這些同名的組件。通過這種方式,前面提到的三個痛點就解決了。

那么,想達到這種效果,我們需要對 md-loader 做哪些修改呢?

來看一下修改后的 md-loader 的實現:

const?md?=?require('./config');module.exports?=?function(source)?{const?content?=?md.render(source,?{resourcePath:?this.resourcePath});const?startTag?=?'<!--element-demo:';const?startTagLen?=?startTag.length;const?endTag?=?':element-demo-->';const?endTagLen?=?endTag.length;const?tagReg?=?/\s*<([\w-_]+)\s*\/>\s*/;let?componenetsString?=?'';let?output?=?[];?//?輸出的內容let?start?=?0;?//?字符串開始位置let?commentStart?=?content.indexOf(startTag);let?commentEnd?=?content.indexOf(endTag,?commentStart?+?startTagLen);while?(commentStart?!==?-1?&&?commentEnd?!==?-1)?{output.push(content.slice(start,?commentStart));const?commentContent?=?content.slice(commentStart?+?startTagLen,?commentEnd);const?matches?=?commentContent.match(tagReg);if?(matches)?{const?demoComponentName?=?matches[1];output.push(`<template?slot="source"><${demoComponentName}?/></template>`);const?imports?=?`()=>import('../demos/${demoComponentName}.vue')`;componenetsString?+=?`${JSON.stringify(demoComponentName)}:?${imports},`;}start?=?commentEnd?+?endTagLen;commentStart?=?content.indexOf(startTag,?start);commentEnd?=?content.indexOf(endTag,?commentStart?+?startTagLen);}let?pageScript?=?'';if?(componenetsString)?{pageScript?=?`<script>export?default?{name:?'component-doc',components:?{${componenetsString}}}</script>`;}?else?if?(content.indexOf('<script>')?===?0)?{start?=?content.indexOf('</script>')?+?'</script>'.length;pageScript?=?content.slice(0,?start);}output.push(content.slice(start));return?`<template><section?class="content?element-doc">${output.join('')}</section></template>${pageScript}`; };

思路很簡單,解析出每個 demo 容器中的組件名稱,通過動態 import 的方式加載組件,然后在 source 插槽中直接用這個組件。

這樣就把組件的 markdown 文檔和 demo 直接關聯起來。但這樣還不夠,我們還需要解決組件 demo 下面的代碼展示問題,需要對 code fence 渲染策略做一定的修改:

const?path?=?require('path'); const?fs?=?require('fs');const?tagReg?=?/\s*<([\w-_]+)\s*\/>\s*/;//?覆蓋默認的?fence?渲染策略 module.exports?=?md?=>?{const?defaultRender?=?md.renderer.rules.fence;md.renderer.rules.fence?=?(tokens,?idx,?options,?env,?self)?=>?{const?token?=?tokens[idx];//?判斷該?fence?是否在?:::demo?內const?prevToken?=?tokens[idx?-?1];const?isInDemoContainer?=?prevToken?&&?prevToken.nesting?===?1?&&?prevToken.info.trim().match(/^demo\s*(.*)$/);if?(token.info?===?'html'?&&?isInDemoContainer)?{const?matches?=?token.content.match(tagReg);if?(matches)?{const?componentName?=?matches[1];const?componentPath?=?path.resolve(env.resourcePath,?`../../demos/${componentName}.vue`);const?content?=?fs.readFileSync(componentPath,?'utf-8');return?`<template?slot="highlight"><pre?v-pre><code?class="html">${md.utils.escapeHtml(content)}</code></pre></template>`;}return?'';}return?defaultRender(tokens,?idx,?options,?env,?self);}; };

由于組件 demo 的代碼已經不在 markdown 文檔中維護了,因此只能從組件文件中讀取了。

但是我們如何知道應該從哪個路徑讀取對應的 demo 組件呢?

在 webpack loader 中,我們可以通過 this.resourcePath 獲取到當前處理文件的路徑,那么在執行 markdown 渲染的過程中就可以把路徑當做環境變量傳入:

const?content?=?md.render(source,?{resourcePath:?this.resourcePath })

這樣在 markdown 處理器的內部我們就可以通過 env.resourcePath 拿到處理的 markdown 文件路徑,從而通過相對路徑計算出要讀取組件的路徑,然后讀取它們的內容:

const?componentPath?=?path.resolve(env.resourcePath,?`../../demos/${componentName}.vue`); const?content?=?fs.readFileSync(componentPath,?'utf-8');

有了組件文檔的重構方案,接下來的工作就是依次重構組件的文檔。當然在這個階段,新老文檔編寫的方式都需要支持。

因此需要對 webpack 的配置做一些修改:

{test:?/examples(\/|\\)docs(\/|\\).*\.md$/,use:?[{loader:?'vue-loader',options:?{compilerOptions:?{preserveWhitespace:?false}}},{loader:?path.resolve(__dirname,?'./md-loader/index.js')}] },?{test:?/(examples(\/|\\)docs-next(\/|\\).*|changelog\.[\w-_]+)\.md$/i,use:?[{loader:?'vue-loader',options:?{compilerOptions:?{preserveWhitespace:?false}}},{loader:?path.resolve(__dirname,?'./md-loader-next/index.js')}] }

對于重構的文檔,使用新的 markdown loader。當然加載組件視圖的邏輯也需要做一定的修改,對于重構的文檔,指向新的文檔地址。

總結

ElementUI 通過 markdown 編寫組件文檔的思路還是非常棒的,主要利用了自定義 md-loader 對 markdown 文件內容做了一層處理,解析成 Vue 組件字符串,再交給 vue-loader 處理。

在寫這篇文章之前,我就在粉絲群里分享了重構文檔的方案。有同學告訴我,Element-plus 已經用 vitepress 重寫,看了一下文檔的組織方式,和我重構的方式非常類似,這就是傳說中的英雄所見略同嗎?

我在之前的文章中強調過,要善于發現工作中的痛點,并通過技術的方式解決,這是優秀的工程師重要的能力之一,希望這篇文章能夠帶給你這方面的一些思考。

參考資料

[1] markdown-it-chain:??https://github.com/ulivz/markdown-it-chain
[2] markdown-it:?https://markdown-it.github.io/markdown-it/


最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。

推薦閱讀

1個月,200+人,一起讀了4周源碼
我歷時3年才寫了10余篇源碼文章,但收獲了100w+閱讀

老姚淺談:怎么學JavaScript?

我在阿里招前端,該怎么幫你(可進面試群)

·················?若川簡介?·················

你好,我是若川,畢業于江西高?!,F在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》10余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助1000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

識別方二維碼加我微信、拉你進源碼共讀

今日話題

略。歡迎分享、收藏、點贊、在看我的公眾號文章~

總結

以上是生活随笔為你收集整理的ElementUI 组件库 md-loader 的解析和优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

亚洲电影一区二区 | 天天激情天天干 | 日韩在线视频国产 | 久久久久久免费毛片精品 | japanesexxxhd奶水 国产一区二区在线免费观看 | 欧美老少交| 91视视频在线直接观看在线看网页在线看 | 97在线观视频免费观看 | 国产字幕在线看 | 国产美女免费观看 | 九九精品视频在线看 | 国产区精品在线观看 | 国产日韩欧美在线免费观看 | 一区二区三区四区五区在线视频 | 国产精品你懂的在线观看 | 国产精品1区2区3区在线观看 | 国产精品久久久久aaaa | 在线视频久 | 西西人体www444 | 毛片视频电影 | 91中文字幕| 日韩欧美极品 | 国产精品第一视频 | 亚洲国产精品va在线看 | 欧美日本不卡 | 正在播放五月婷婷狠狠干 | 97成人在线观看 | 国产成人61精品免费看片 | 国产一级性生活 | 日韩久久视频 | 国产黄免费看 | 青春草免费视频 | 亚洲国内在线 | av在线免费在线观看 | 西西人体www444 | 国产一级二级三级视频 | 免费国产一区二区视频 | 午夜久操 | 黄色av电影免费观看 | 欧美日韩亚洲第一页 | 一本一道久久a久久精品蜜桃 | 成人黄色毛片视频 | 日日干干 | 国产精品免费观看视频 | 天天激情站 | 国产亚洲婷婷免费 | 亚洲天天在线日亚洲洲精 | 日韩av不卡播放 | 最近中文字幕免费视频 | 人人视频网站 | 西西44人体做爰大胆视频 | 六月丁香伊人 | 成人在线播放视频 | 亚洲永久av | 免费成人短视频 | 这里只有精彩视频 | 黄色小说18| 日韩在线观看你懂得 | 国产日产高清dvd碟片 | 国产乱对白刺激视频在线观看女王 | 亚洲国产日韩欧美在线 | 亚洲丁香久久久 | 黄色国产高清 | 5月丁香婷婷综合 | av中文字幕不卡 | 精品资源在线 | 亚洲精品国产精品乱码不99热 | 正在播放 久久 | 国产视频色 | 欧美视频日韩视频 | 国内精品视频一区二区三区八戒 | 成人黄色国产 | 亚洲欧美日韩精品久久久 | 在线视频一区观看 | 午夜久久久久久久久 | 粉嫩av一区二区三区四区在线观看 | 一区二区三区高清在线 | 在线成人欧美 | 亚洲精品久久久久www | 欧美日韩1区2区 | 国产精品久久久久久久午夜 | 久久久精品综合 | 亚洲精品久久久久中文字幕m男 | 免费碰碰| 亚洲国产一区在线观看 | 黄色99视频 | 国产精品久久久久婷婷二区次 | 日韩精品中文字幕有码 | 91桃色免费视频 | 在线免费高清视频 | 五月天久久精品 | 亚洲精品在线一区二区三区 | 五月天久久婷婷 | 天天草av| 日韩av网站在线播放 | 久久99网 | 久草视频免费观 | 99久久婷婷国产一区二区三区 | 成人免费观看av | 亚洲精品伦理在线 | 久久九九精品 | 在线观看黄污 | 日韩高清av | 久草在线免费在线观看 | 黄色在线网站噜噜噜 | 国产亚洲精品久久久久久久久久 | 婷婷在线网 | 日韩成人在线一区二区 | 在线看日韩av | 久久调教视频 | 久久理论视频 | 欧美日韩不卡一区 | 在线看小早川怜子av | 人人玩人人添人人 | 久久高清 | 麻豆精品视频在线观看免费 | 在线日韩精品视频 | 色无五月 | 欧美尹人 | 国内精品在线观看视频 | 二区三区毛片 | 五月天中文在线 | 亚洲欧美在线视频免费 | 91精品国产网站 | 国产拍揄自揄精品视频麻豆 | 在线视频一二三 | 91网在线看 | 91亚洲精品乱码久久久久久蜜桃 | 久久av网址 | 午夜精品视频在线 | 成年人黄色免费看 | 成年人黄色免费视频 | 久久精品视频观看 | 欧洲精品久久久久毛片完整版 | 成人免费视频网站在线观看 | 久久综合偷偷噜噜噜色 | 久久一及片 | 欧美一级片 | 91福利区一区二区三区 | 日韩欧美一区二区在线观看 | 91大神在线观看视频 | 成人午夜黄色影院 | 久草在线这里只有精品 | 久久国产精品色av免费看 | 狠狠干狠狠艹 | 黄色的视频网站 | av永久网址 | 九九在线视频免费观看 | 免费观看全黄做爰大片国产 | 久久五月婷婷丁香社区 | 欧美日韩aaaa | 狠狠操狠狠干2017 | 99精品国产在热久久下载 | 一区二区不卡视频在线观看 | 天天干天天操天天拍 | 国产精品免费视频久久久 | 欧美日韩一区二区在线 | 久久精品一区八戒影视 | 国产一区视频免费在线观看 | 国产+日韩欧美 | 夜夜操夜夜干 | 午夜久久福利视频 | 欧美日韩一区二区三区在线免费观看 | 天天在线操 | 国产一区av在线 | 欧美成人xxxx | 日韩城人在线 | 在线免费观看的av | 久久九九影院 | 一本一本久久a久久精品牛牛影视 | av天天在线观看 | 国产资源网 | 天天色成人网 | 日韩免费电影在线观看 | 亚洲视频第一页 | 精品国产乱码久久久久 | 麻豆国产网站入口 | 91久久人澡人人添人人爽欧美 | 亚洲视频高清 | 欧美午夜性 | 欧美成人黄| 婷婷色亚洲 | 日韩视频免费播放 | 四虎影视成人永久免费观看视频 | 黄色av高清 | 亚洲欧美国产精品va在线观看 | 人人看人人做人人澡 | 中文字幕丝袜一区二区 | 亚洲国产午夜精品 | 国产成人精品日本亚洲999 | 成人久久18免费网站麻豆 | 青青草在久久免费久久免费 | 国产高清不卡在线 | 欧美做受高潮1 | 成人午夜影院在线观看 | 亚洲天堂网在线播放 | 最新av在线网站 | 久久久国产一区 | 亚洲视频在线观看网站 | 五月激情六月丁香 | 国产成人精品久久亚洲高清不卡 | 国产在线97 | 伊人天天综合 | 中日韩免费视频 | 在线看一区| 99久久超碰中文字幕伊人 | 国产一线天在线观看 | 国产原创91 | 国产成人久久av免费高清密臂 | 久久人人看 | 国产美女无遮挡永久免费 | 免费网址在线播放 | www在线观看视频 | 久久综合九色99 | 天天天色| 夜夜骑天天操 | 久久久国产毛片 | 99久久99久国产黄毛片 | 日韩av在线资源 | 六月天综合网 | 国产最新福利 | 欧美日韩国产免费视频 | 亚洲国产精品99久久久久久久久 | 国产日韩高清在线 | 国产v视频 | 91麻豆免费视频 | 中文字幕色在线 | 四虎永久视频 | 国内精品久久久久久久久久久久 | 国产成人免费观看久久久 | www免费黄色 | 成人 国产 在线 | 免费看在线看www777 | 日韩二区在线 | 夜夜夜夜操 | 久久久国产精品久久久 | 国产欧美日韩精品一区二区免费 | 婷婷网在线 | 天天插天天爱 | 亚洲最大av | 久久九九久久九九 | 91久久人澡人人添人人爽欧美 | 91在线永久 | 玖玖在线看 | 久久久久夜色 | 97视频免费播放 | 日韩一区二区三区免费电影 | 国产999精品久久久久久 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 中文字幕国语官网在线视频 | 日韩字幕在线观看 | 黄色在线成人 | 久久免费一级片 | 九九免费在线观看视频 | 国产裸体无遮挡 | 91精品国产乱码久久桃 | 亚洲午夜不卡 | 国产精品久久久久久久久搜平片 | 日韩激情片在线观看 | 天天摸天天操天天舔 | 粉嫩av一区二区三区四区 | 久久亚洲综合色 | 成人欧美一区二区三区在线观看 | 欧美色图p | 91综合色 | 热re99久久精品国产66热 | 欧美久久久久久久久久久久久 | 国产成人一区二 | 国产免费人成xvideos视频 | 在线观看成人 | 美女一二三区 | 欧美日韩一二三四区 | 2023亚洲精品国偷拍自产在线 | 精品影院| 草久在线观看视频 | 日本三级在线观看中文字 | 欧美日韩成人 | 日日干天天| 欧美日韩一区二区三区在线免费观看 | 一区二区视频在线看 | 欧美久久久久久久久久久久 | 国产91精品看黄网站在线观看动漫 | 国产视频一区二区在线观看 | 婷婷色网视频在线播放 | 久草在线这里只有精品 | 91视视频在线直接观看在线看网页在线看 | www.在线观看av | 欧美精品在线免费 | 国产青青青 | 国产亚洲欧美精品久久久久久 | 国产一级电影在线 | 欧美日韩18| 亚洲男男gaygay无套同网址 | 国产精品9999久久久久仙踪林 | 中文字幕 国产 一区 | 色播六月天 | www.成人久久 | 懂色av一区二区三区蜜臀 | 日韩av网址在线 | 亚洲精品免费观看视频 | 91探花在线 | 日日骑| 国产在线观看免费观看 | 国产免费专区 | 96久久| 五月婷婷在线观看 | 91爱爱网址 | 91传媒91久久久 | 日韩a级免费视频 | 免费在线观看午夜视频 | 久久久久久国产精品亚洲78 | 日韩在线播放av | 欧美性生交大片免网 | 精品影院一区二区久久久 | 国产成人精品一区二区三区福利 | 在线观看精品一区 | 国产xxxx性hd极品 | 天天射日| 亚洲精品久久久蜜桃直播 | 91在线观 | 97成人资源站 | 国产无吗一区二区三区在线欢 | 高清av免费一区中文字幕 | 国产精品乱码高清在线看 | 国产一级免费视频 | 国产1区在线观看 | 91专区在线观看 | 久久久久久久久久久久久久电影 | 国产一级片免费视频 | 亚洲视频精品在线 | 久草在线视频资源 | 国产精品一区二区久久精品爱微奶 | 日韩在线小视频 | 婷婷综合国产 | 久草在线最新视频 | 久久精品4 | 日韩av三区 | 91.精品高清在线观看 | 日韩视频二区 | 91精品国自产在线偷拍蜜桃 | 99 视频 高清 | 国产精品va最新国产精品视频 | 成年人在线观看网站 | 亚洲影音先锋 | 亚洲美女免费视频 | 国产伦精品一区二区三区… | 欧美a在线免费观看 | www.久久久精品 | 96国产精品 | 成人免费91 | 久久爽久久爽久久av东京爽 | 国产高清在线免费 | 黄色一级大片免费看 | 天天色婷婷 | 99r在线 | 一区二区三区高清不卡 | 色婷婷综合久久久久 | 欧美-第1页-屁屁影院 | 丁香婷五月 | 国产在线观看免费 | 欧美日高清视频 | 91大神精品视频在线观看 | 天天夜夜狠狠操 | 精品久久久久国产免费第一页 | 国产精品永久免费视频 | 国产中文视频 | 欧美日韩91| 超碰在线9 | 精品视频免费播放 | 国产精品久久久久久久久久久久午夜片 | 午夜精品久久久 | 免费看片日韩 | 日本精品一区二区在线观看 | 九热精品 | 欧美一级xxxx | 中文字幕高清视频 | 日本女人的性生活视频 | 在线观看中文字幕av | 天天综合网在线观看 | 探花国产在线 | 免费激情网 | 99久久视频| 久久久电影 | 狠狠色狠狠色 | 91精品老司机久久一区啪 | 99国产免费网址 | 天天爽天天摸 | 亚洲欧美日韩不卡 | 91丨九色丨91啦蝌蚪老版 | 欧美日韩国产伦理 | 黄污在线看 | 国产一二三精品 | 日日草天天干 | 国产精品一区二区免费 | 天天干天天操天天拍 | 国产黄网站在线观看 | 黄网站色成年免费观看 | 国产成人一区二区三区电影 | 亚洲年轻女教师毛茸茸 | 伊人资源视频在线 | 黄色大片免费播放 | 国产精品理论在线观看 | av大片网址 | 久久久精品视频网站 | 精品在线免费视频 | av网站播放| 色综合人人 | 亚洲综合视频在线 | 国产破处精品 | 欧美日韩在线视频一区 | 91麻豆精品国产91久久久久久 | 久久手机看片 | 精品91久久久久 | 久久99国产精品视频 | 91片网| 国产精品白浆视频 | a视频在线| 久久久午夜剧场 | 一区二区三区精品在线视频 | 欧美一级片在线观看视频 | 日韩中文字幕免费视频 | 激情丁香综合五月 | 欧美性天天 | 亚洲精品国产精品久久99热 | 91在线区 | a级国产乱理伦片在线观看 亚洲3级 | 国产伦精品一区二区三区免费 | 欧美成人xxxx| 成人毛片一区 | 黄色软件大全网站 | 亚洲精品777| 99热99| 狠狠干夜夜操天天爽 | 久久久影院一区二区三区 | 在线观看中文字幕视频 | 国产色秀视频 | 四虎影视成人永久免费观看亚洲欧美 | 99国产一区 | 丰满少妇久久久 | 久久人人爽人人人人片 | 精品自拍sae8—视频 | 国产玖玖精品视频 | 视频一区久久 | 国产91区 | 精品欧美在线视频 | 一区二区三区动漫 | 99国产精品一区 | 亚洲精品久久久久中文字幕m男 | 国产91免费在线 | 久久精品一区二 | 国产精品6999成人免费视频 | 狠狠干五月天 | www.色爱 | 亚洲特级毛片 | 久久久高清 | 日韩毛片在线免费观看 | 精品国产一区二区三区蜜臀 | 日韩欧美电影在线 | 精品日韩在线一区 | 日韩欧美在线免费观看 | 五月天久久狠狠 | 国产视频在线播放 | 三级黄色大片在线观看 | 黄色成年片 | 韩国一区二区三区在线观看 | 日韩久久精品一区二区 | 精品国内自产拍在线观看视频 | 久久成熟 | 91在线免费视频观看 | 亚洲2019精品 | 国产无限资源在线观看 | 亚洲成人国产精品 | 国产精品人成电影在线观看 | 99久久精品无码一区二区毛片 | 深夜免费福利视频 | av资源免费看 | 亚洲极色| 97色狠狠| 操久久免费视频 | 国产一区二区在线免费观看 | 午夜国产一区 | 91精品国产99久久久久久红楼 | 人人爽人人看 | 日韩最新在线 | 久草在线资源免费 | 国产成人免费在线观看 | 久久午夜精品 | 色综合久久天天 | 成人一区二区在线观看 | 狠狠操电影网 | 欧美一区,二区 | 日日操网站 | 日韩欧美一区二区三区视频 | 狠狠躁夜夜躁人人爽超碰91 | 久草视频在线播放 | 久久在线视频精品 | 超碰人在线 | 国产黄a三级三级三级三级三级 | 婷婷成人综合 | 激情小说 五月 | 亚洲欧美激情精品一区二区 | 六月激情网| 在线欧美小视频 | 久久久久日本精品一区二区三区 | 中文字幕在线观看的网站 | 国产亚洲综合在线 | 成人小视频免费在线观看 | 久久久久久美女 | а天堂中文最新一区二区三区 | 久久人人爽人人人人片 | 成人资源在线播放 | 亚洲丁香久久久 | 九七在线视频 | 麻豆视频在线免费 | 97在线视频免费 | 国产精品中文字幕在线 | 成年人三级网站 | 免费亚洲成人 | 91网站免费观看 | 欧美三级免费 | 99超碰在线观看 | 人人舔人人干 | 婷婷在线色 | 91精品啪在线观看国产 | 国产精品免费视频网站 | 黄色www免费| 欧美激情另类 | 草莓视频在线观看免费观看 | 免费av高清| 午夜.dj高清免费观看视频 | 国产成人专区 | 四虎成人精品在永久免费 | 欧美日韩国产三级 | 欧美日韩p片 | 色综合婷婷 | 成人久久久久久久久久 | 97精品一区二区三区 | 婷婷激情网站 | 欧美日韩在线精品一区二区 | 国产 欧美 日本 | av大全在线看| 在线视频欧美亚洲 | 国产一区二区三区视频在线 | 国产亚洲免费观看 | 亚洲一区二区精品视频 | 精品国产乱码久久久久久1区2匹 | 日韩在线视频精品 | 麻豆国产精品一区二区三区 | 亚洲狠狠婷婷 | 中文字幕在线网址 | 99热国内精品 | 99久久精品免费看国产免费软件 | 色婷婷久久久综合中文字幕 | 一本色道久久综合亚洲二区三区 | 91人人干 | 国产成人性色生活片 | 婷婷www | 国产精品久久久久久模特 | 伊人开心激情 | 亚洲成av人影院 | 高清精品视频 | 456成人精品影院 | 成人永久视频 | 亚州精品视频 | 中文字幕中文字幕 | 日韩特黄一级欧美毛片特黄 | 天天碰天天操视频 | 久久国内精品 | 少妇高潮流白浆在线观看 | 狠狠干.com| 免费成人黄色片 | 亚洲伊人成综合网 | 中文字幕专区高清在线观看 | 91精品久久久久久粉嫩 | 精品久久久免费 | 精品九九久久 | 狠狠干美女 | 97在线免费 | 免费国产ww | 香蕉视频日本 | 午夜久久精品 | 国产偷国产偷亚洲清高 | 黄色软件视频网站 | 丁香视频全集免费观看 | 精品女同一区二区三区在线观看 | 日韩精品综合在线 | 欧美国产三区 | 久草视频在线免费 | 久久久久久久久久影院 | 国产系列在线观看 | 国产午夜精品一区二区三区四区 | 精品久久一二三区 | 色香蕉在线 | 欧美日韩不卡在线视频 | 成人羞羞免费 | 亚洲综合在线五月天 | 亚洲三级av | 中文字幕一区二区三区乱码不卡 | 国产精品一区二区三区久久 | 国产精品免费观看视频 | 免费在线观看av网站 | 一区二区三区日韩精品 | 亚洲综合丁香 | 91亚洲精品久久久蜜桃借种 | 黄色一级免费 | 久久理论片| 天天干干 | 国产中文字幕av | 91精品国产91久久久久久三级 | 美女视频a美女大全免费下载蜜臀 | 国产原创av在线 | 丝袜美腿亚洲综合 | 久久精品高清视频 | 在线观看91网站 | 国产不卡高清 | 色偷偷网站视频 | 免费观看www小视频的软件 | 天天干.com | 久久国产亚洲精品 | 亚洲国产免费看 | 日韩天堂在线观看 | 97色婷婷 | 久久a国产 | 欧美日韩国产二区 | 奇米777777 | 在线观看视频一区二区 | 四虎国产精品成人免费4hu | 色播五月激情五月 | 亚洲精品免费在线播放 | 日日爽天天操 | 亚洲黄色免费电影 | 日韩在线免费电影 | 亚洲国产精品小视频 | 丝袜美腿av | 久草视频观看 | 在线视频1卡二卡三卡 | 在线看欧美 | 国产小视频免费在线观看 | 国产夫妻自拍av | 免费在线观看的av网站 | 国产精品原创视频 | 97精品久久人人爽人人爽 | 国产一区在线观看免费 | 日韩美视频 | 粉嫩高清一区二区三区 | 天堂网一区二区 | 日韩激情片在线观看 | 日韩中文在线视频 | 超碰免费观看 | 午夜精品久久久99热福利 | 97综合在线 | 精品一二区 | 日本中文字幕系列 | 精品综合久久久 | 中文字幕人成不卡一区 | 久久国产电影 | 三日本三级少妇三级99 | 日韩欧美v | 永久免费精品视频网站 | 在线 影视 一区 | 欧美日韩伦理一区 | 精品一区二区三区久久久 | 韩日av一区二区 | 欧美精品一区在线 | 一本到视频在线观看 | 中文字幕一区二区三区久久 | 婷香五月 | 日日麻批40分钟视频免费观看 | 亚洲激精日韩激精欧美精品 | 丁香六月五月婷婷 | 久久视频在线观看免费 | 国产一区免费视频 | 91精品一区在线观看 | 97在线免费视频 | 久久黄色精品视频 | 香蕉精品在线观看 | 很黄很黄的网站免费的 | 色小说av | 中文字幕亚洲综合久久五月天色无吗'' | 午夜男人影院 | 91天堂影院| www.亚洲| 91porny九色91啦中文 | 久久久久亚洲精品中文字幕 | 国产精品久久久av | 国产成人一区在线 | 日本精品一区二区三区在线观看 | 91精品国产自产在线观看永久 | 91亚洲精品国偷拍 | 亚洲精品乱码久久久久久蜜桃91 | 国产精品久久久久久999 | 亚洲91精品| 福利视频 | 狠狠干成人 | 日本在线观看一区 | 狠狠做深爱婷婷综合一区 | 97电影手机版 | 亚洲五月婷 | 久久精品高清视频 | 四虎永久免费网站 | 欧美伊人网 | 免费av在线网站 | 欧美日韩国产二区 | 在线有码中文字幕 | 免费在线精品视频 | 91精品一区国产高清在线gif | 成人av免费 | 久久夜夜操| 91热视频 | 国产亚洲精品成人av久久ww | 精品视频免费在线 | 国产精品久久久久久久久久久久冷 | av大全在线| 国产一区二区三区黄 | 亚洲精品一区二区三区四区高清 | 91在线视频 | 欧美色噜噜 | 精品产品国产在线不卡 | 最新动作电影 | 欧美乱淫视频 | 97国产精品视频 | 九九热只有精品 | 国产精品视频在线观看 | 午夜精品福利一区二区三区蜜桃 | 久久九九国产精品 | 午夜国产福利在线 | 久久精品视频3 | 在线免费观看亚洲视频 | 欧美激情综合色综合啪啪五月 | 中文字幕在线免费看 | 黄色网址在线播放 | 99人成在线观看视频 | 人人草在线视频 | 日韩午夜剧场 | 国产人成免费视频 | 亚洲人视频在线 | 亚洲一级黄色av | 国产精品视频不卡 | 国产美女精品人人做人人爽 | 久久久久久久久免费 | 成人国产精品电影 | 精品在线观看一区二区 | 久久久精品免费看 | 日韩精品网址 | 粉嫩高清一区二区三区 | 日本三级香港三级人妇99 | 亚洲最大av| 黄色精品免费 | 国产91在线免费视频 | 国产人成精品一区二区三 | 久久9精品 | 中文字幕在线观看免费观看 | 毛片基地黄久久久久久天堂 | 亚州av一区| av黄免费看 | 亚洲欧洲视频 | 亚洲a免费| 高清日韩一区二区 | 婷婷六月激情 | 亚洲国产精品传媒在线观看 | 亚洲一区二区三区在线看 | 中文字幕乱码电影 | 三级黄色免费 | 欧美另类交在线观看 | 亚洲丁香日韩 | 亚洲国产日韩欧美在线 | 国产精品伦一区二区三区视频 | 国产精品久久久久av | 久久中文精品视频 | 国产一二三四在线观看视频 | 激情视频在线观看网址 | 伊人激情综合 | 日韩a在线看 | 免费看黄色大全 | 久久久片| 狠狠色丁香婷婷综合久小说久 | 在线а√天堂中文官网 | 亚洲综合成人专区片 | 91麻豆产精品久久久久久 | 一区二区视频在线观看免费 | 久久精品视频在线观看免费 | 丁香五月网久久综合 | 国产96在线 | 日韩有码欧美 | 伊人影院av | 91视频久久久 | 在线亚洲精品 | 久久有精品 | 日韩二区在线 | 视频国产一区二区三区 | 午夜精品导航 | av中文字幕第一页 | 欧美日韩国产一区 | 国产精品自产拍在线观看桃花 | 免费在线激情电影 | 一本一本久久a久久精品综合小说 | 免费观看国产精品视频 | 99视频久久| 中国一级特黄毛片大片久久 | 九九热中文字幕 | 天天操天天操天天 | www.黄色片网站 | 福利视频第一页 | 久久 亚洲视频 | 成人免费观看完整版电影 | 狠狠狠色| 亚洲精品成人在线 | 一区二区三区四区精品 | 蜜臀av在线一区二区三区 | 最近中文字幕免费 | 婷婷成人综合 | 久久国精品| av成人黄色 | 69国产精品成人在线播放 | www.av免费| 日韩国产欧美视频 | 国产一级片直播 | 在线观看成年人 | 一区中文字幕电影 | 婷婷伊人五月 | 欧美成人aa| 精品国内自产拍在线观看视频 | 免费黄色a网站 | av在线播放中文字幕 | 国产在线资源 | 久久精品中文字幕一区二区三区 | 成人免费视频网 | 亚洲成人免费在线观看 | 日日夜夜中文字幕 | 亚洲最大av网站 | 国产一区二区在线免费视频 | 97国产 | 最新国产精品视频 | 久久精品这里热有精品 | 在线成人一区 | ,午夜性刺激免费看视频 | 免费亚洲一区二区 | av免费在线观看网站 | 亚洲精品综合一区二区 | 四虎成人在线 | 国产一区在线视频播放 | 久久国产电影 | 日韩欧美在线免费 | 中文字幕在线观看第三页 | 精品国产一区二区三区久久久蜜臀 | a v在线观看 | 精品国产一区二区三区久久久蜜臀 | 亚洲精品国产视频 | 日韩欧美精品在线 | 国产午夜在线 | 特级黄色片免费看 | 一区二区视频在线免费观看 | 国产中文视 | 欧美日性视频 | 国产精品久久久久久久久久久久冷 | 久久免费成人网 | 免费在线黄网 | 免费美女久久99 | 久艹在线播放 | 91专区在线观看 | 婷婷色网视频在线播放 | 日韩久久精品一区二区 | 在线观看91久久久久久 | 在线看国产一区 | 天天干夜夜干 | 综合色爱| 五月天最新网址 | 亚洲一区精品人人爽人人躁 | 久久久久久久国产精品 | 欧美日韩午夜爽爽 | av先锋中文字幕 | 中文字幕一区二 | 999超碰| 福利视频一区二区 | 国产成人精品一区二区在线观看 | 久久免费片 | av不卡网站 | 日日天天干 | 国产美女主播精品一区二区三区 | 1024久久 | 激情视频在线高清看 | 成 人 黄 色 视频播放1 | 久久伊人精品一区二区三区 | 久久久久国产精品一区二区 | 粉嫩一区二区三区粉嫩91 | 国产精品资源在线观看 | 日本黄色免费大片 | 精品国产区 | 国内精品久久久久久久97牛牛 | 国产精品免费观看国产网曝瓜 | 免费观看午夜视频 | 九九久久久久99精品 | 久草在线综合网 | 99r在线| 久久婷婷久久 | 在线天堂中文www视软件 | 久久99视频免费观看 | 国内丰满少妇猛烈精品播放 | 亚洲电影一级黄 | 久久久精品久久日韩一区综合 | 伊人黄 | 国产亚洲一区二区在线观看 | 久久艹艹| 手机看片1042 | 又大又硬又黄又爽视频在线观看 | 色综合久久中文字幕综合网 | www在线免费观看 | 天天草天天干天天射 | 在线观看中文字幕一区 | 欧美va天堂在线电影 | 欧美一级视频免费 | 99色在线观看视频 | 免费日韩一区 | 精品久久精品久久 | 欧美日韩精品在线 | 中文字幕视频三区 | 91精品国产三级a在线观看 | 免费福利在线 | 丰满少妇在线 | 成人性生活大片 | 91天堂素人约啪 | 99 视频 高清 | 亚洲一级黄色大片 | 国产精品精品国产婷婷这里av | 五月婷婷欧美视频 | 中文字幕在线观看一区 | 人人精品| 青春草免费在线视频 | 日韩一区视频在线 | 日日干天天操 | 91成人小视频 | 亚洲永久精品视频 | 99热日本| 天天操夜夜操国产精品 | 中文字幕av在线不卡 | 亚洲国产中文字幕在线观看 | 国产免费av一区二区三区 | 手机av观看| 丁香伊人网| 亚洲欧洲日韩 | 免费精品人在线二线三线 | 玖玖爱国产在线 | 在线免费观看av网站 | 97国产在线观看 | 国产成人一二片 | 在线观看亚洲国产 | 最新av网站在线观看 | 亚洲美女免费精品视频在线观看 | 免费黄色av | 婷婷丁香色 | 一区二区三区免费在线 | 亚洲日韩精品欧美一区二区 | 粉嫩av一区二区三区免费 | 一区二区三区高清在线 | a在线观看国产 | 91精品久久久久久久久久入口 | 99久久久国产精品 | 99精品国产免费久久久久久下载 | 五月天婷婷狠狠 | 国产精品男女视频 | 国产成人免费网站 | 国产美女视频免费观看的网站 | 偷拍视频一区 | 黄p网站在线观看 | 欧美一级免费高清 | 九九在线免费视频 | 国产69精品久久久久久 | 免费国产ww | 久久在线看 | 日韩免费一级电影 | 国产小视频在线 | 九九日韩 | av中文字幕在线电影 | 国产精品一区二区吃奶在线观看 | 日免费视频 | 日韩午夜电影网 | 欧美黑吊大战白妞欧美 | 热久久免费视频精品 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 久热av在线 | 久久久国产精品一区二区中文 | 高清中文字幕av | 黄色av高清| 69av视频在线 | 亚洲国产欧美在线人成大黄瓜 | 亚洲精品午夜一区人人爽 | 欧美精品视 | 天天综合天天综合 | 美女视频黄是免费的 | 九九久久影视 | 国产精品久久久久久久电影 | 极品中文字幕 | 久久九九九九 | 日韩日韩日韩日韩 | 午夜视频不卡 | 丁香九月婷婷综合 | 婷婷网站天天婷婷网站 | 久99久在线视频 |