[{"data":1,"prerenderedAt":3616},["ShallowReactive",2],{"page-/post/nuxt/nuxtjs-mdc-docs":3,"surrounding-page":3607},{"id":4,"title":5,"author":6,"body":7,"date":3595,"description":3596,"extension":803,"group":6,"lastmod":3597,"meta":3598,"navigation":164,"path":3599,"rawbody":3600,"seo":3601,"showTitle":5,"stem":3602,"tags":3603,"versions":3604,"__hash__":3606},"content/post/nuxt/nuxtjs-mdc-docs.md","打造 Markdown 的绝美排版：@nuxtjs-mdc 使用指南",null,{"type":8,"value":9,"toc":3586},"minimark",[10,19,23,54,61,102,105,108,113,248,278,283,290,297,316,319,474,485,491,494,703,708,727,743,749,759,770,775,794,799,810,815,875,878,890,893,897,908,913,916,934,946,951,954,959,962,965,976,980,1000,1006,1012,1017,1020,1057,1063,1181,1187,1198,1201,1219,1222,1366,1369,1374,1377,1396,1399,1404,1407,1434,1437,1653,1656,1661,1668,1674,1680,1690,1704,1733,1736,1743,1762,1767,1810,1813,1822,1825,1828,1831,1868,1871,1874,1877,2065,2068,2077,2080,2083,2086,2096,2143,2146,2150,2159,2162,2170,2197,2202,2221,2231,2314,2319,2327,2334,2339,2345,2355,2360,2363,2387,2394,2404,2409,2416,2421,2424,2448,2454,2478,2483,2493,2601,2609,2614,2621,3238,3241,3388,3391,3394,3507,3520,3523,3537,3551,3558,3570,3583],[11,12,13,14,18],"p",{},"这是一份持续更新的@nuxtjs/mdc的使用说明书，扩充官方文档的同时，更正一些错误信息（因为官方更的不及时）。同时也会涵盖解析 ",[15,16,17],"code",{},"Makdown"," 语法的使用说明。",[20,21,22],"h2",{"id":22},"安装",[24,25,30],"pre",{"className":26,"code":27,"language":28,"meta":29,"style":29},"language-shell shiki shiki-themes github-light","npx nuxi@latest module add mdc\n","shell","",[15,31,32],{"__ignoreMap":29},[33,34,37,41,45,48,51],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"s7eDp","npx",[33,42,44],{"class":43},"sYBdl"," nuxi@latest",[33,46,47],{"class":43}," module",[33,49,50],{"class":43}," add",[33,52,53],{"class":43}," mdc\n",[11,55,56,57,60],{},"然后 @nuxtjs/mdc 就会被自动添加到 ",[15,58,59],{},"nuxt.config.ts"," 的 modules 中",[24,62,66],{"className":63,"code":64,"language":65,"meta":29,"style":29},"language-typescript shiki shiki-themes github-light","export default defineNuxtConfig({\n  modules: ['@nuxtjs/mdc']\n})\n","typescript",[15,67,68,84,96],{"__ignoreMap":29},[33,69,70,74,77,80],{"class":35,"line":36},[33,71,73],{"class":72},"sD7c4","export",[33,75,76],{"class":72}," default",[33,78,79],{"class":39}," defineNuxtConfig",[33,81,83],{"class":82},"sgsFI","({\n",[33,85,87,90,93],{"class":35,"line":86},2,[33,88,89],{"class":82},"  modules: [",[33,91,92],{"class":43},"'@nuxtjs/mdc'",[33,94,95],{"class":82},"]\n",[33,97,99],{"class":35,"line":98},3,[33,100,101],{"class":82},"})\n",[20,103,104],{"id":104},"组件",[11,106,107],{},"MDC 中提供了三个组件来渲染 markdown 内容",[11,109,110],{},[15,111,112],{},"MDC",[24,114,116],{"className":63,"code":115,"language":65,"meta":29,"style":29},"\u003Cscript setup lang=\"ts\">\nconst md = \"\n    # h1 标题\n\n    `代码快`\n\n\"\n\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CMDC :value=\"md\" tag=\"article\" />\n\u003C/template>\n\n",[15,117,118,135,150,159,166,172,177,183,188,196,201,211,238],{"__ignoreMap":29},[33,119,120,123,126,129,132],{"class":35,"line":36},[33,121,122],{"class":72},"\u003C",[33,124,125],{"class":82},"script setup lang",[33,127,128],{"class":72},"=",[33,130,131],{"class":43},"\"ts\"",[33,133,134],{"class":72},">\n",[33,136,137,140,144,147],{"class":35,"line":86},[33,138,139],{"class":72},"const",[33,141,143],{"class":142},"sYu0t"," md",[33,145,146],{"class":72}," =",[33,148,149],{"class":43}," \"\n",[33,151,152,155],{"class":35,"line":98},[33,153,154],{"class":43},"    # h1 标",[33,156,158],{"class":157},"sB1qb","题\n",[33,160,162],{"class":35,"line":161},4,[33,163,165],{"emptyLinePlaceholder":164},true,"\n",[33,167,169],{"class":35,"line":168},5,[33,170,171],{"class":43},"    `代码快`\n",[33,173,175],{"class":35,"line":174},6,[33,176,165],{"emptyLinePlaceholder":164},[33,178,180],{"class":35,"line":179},7,[33,181,182],{"class":43},"\"\n",[33,184,186],{"class":35,"line":185},8,[33,187,165],{"emptyLinePlaceholder":164},[33,189,191,194],{"class":35,"line":190},9,[33,192,193],{"class":43},"\u003C/script",[33,195,134],{"class":157},[33,197,199],{"class":35,"line":198},10,[33,200,165],{"emptyLinePlaceholder":164},[33,202,204,206,209],{"class":35,"line":203},11,[33,205,122],{"class":82},[33,207,208],{"class":39},"template",[33,210,134],{"class":82},[33,212,214,217,219,222,224,227,230,232,235],{"class":35,"line":213},12,[33,215,216],{"class":72},"  \u003C",[33,218,112],{"class":39},[33,220,221],{"class":82}," :value",[33,223,128],{"class":72},[33,225,226],{"class":43},"\"md\"",[33,228,229],{"class":82}," tag",[33,231,128],{"class":72},[33,233,234],{"class":43},"\"article\"",[33,236,237],{"class":72}," />\n",[33,239,241,244,246],{"class":35,"line":240},13,[33,242,243],{"class":72},"\u003C/",[33,245,208],{"class":82},[33,247,134],{"class":72},[11,249,250,252,253,256,257,260,261,265,266,269,270,273,274,277],{},[15,251,112],{}," 组件直接接受一个 ",[15,254,255],{},"value"," prop，传入 ",[15,258,259],{},"markdown"," 的",[262,263,264],"strong",{},"原始内容","即可，",[15,267,268],{},"tag"," 属性可以决定渲染后的内容被什么标签包裹，类似于 ",[15,271,272],{},"vue-router"," 的 ",[15,275,276],{},"RouterLink","。",[11,279,280],{},[15,281,282],{},"MDCRenderer",[11,284,285,286,289],{},"这个组件依赖于 ",[15,287,288],{},"parseMarkdown"," 函数提供的数据",[11,291,292,293,296],{},"此函数需要从 ",[15,294,295],{},"@nuxtjs/mdc/runtime"," 导入",[24,298,300],{"className":63,"code":299,"language":65,"meta":29,"style":29},"import { parseMarkdown } from '@nuxtjs/mdc/runtime'\n",[15,301,302],{"__ignoreMap":29},[33,303,304,307,310,313],{"class":35,"line":36},[33,305,306],{"class":72},"import",[33,308,309],{"class":82}," { parseMarkdown } ",[33,311,312],{"class":72},"from",[33,314,315],{"class":43}," '@nuxtjs/mdc/runtime'\n",[11,317,318],{},"使用时可以像这样",[24,320,324],{"className":321,"code":322,"language":323,"meta":29,"style":29},"language-vue shiki shiki-themes github-light","\u003Cscript setup lang=\"ts\">\nimport { parseMarkdown } from '@nuxtjs/mdc/runtime'\n\nconst { data: ast } = await useAsyncData('markdown', () => parseMarkdown('::alert\\nMissing markdown input\\n::'))\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CMDCRenderer :body=\"ast.body\" :data=\"ast.data\" />\n\u003C/template>\n","vue",[15,325,326,346,356,360,422,430,434,442,466],{"__ignoreMap":29},[33,327,328,330,334,337,340,342,344],{"class":35,"line":36},[33,329,122],{"class":82},[33,331,333],{"class":332},"shJU0","script",[33,335,336],{"class":39}," setup",[33,338,339],{"class":39}," lang",[33,341,128],{"class":82},[33,343,131],{"class":43},[33,345,134],{"class":82},[33,347,348,350,352,354],{"class":35,"line":86},[33,349,306],{"class":72},[33,351,309],{"class":82},[33,353,312],{"class":72},[33,355,315],{"class":43},[33,357,358],{"class":35,"line":98},[33,359,165],{"emptyLinePlaceholder":164},[33,361,362,364,367,371,374,377,380,382,385,388,391,394,397,400,403,405,408,411,414,416,419],{"class":35,"line":161},[33,363,139],{"class":72},[33,365,366],{"class":82}," { ",[33,368,370],{"class":369},"sqxcx","data",[33,372,373],{"class":82},": ",[33,375,376],{"class":142},"ast",[33,378,379],{"class":82}," } ",[33,381,128],{"class":72},[33,383,384],{"class":72}," await",[33,386,387],{"class":39}," useAsyncData",[33,389,390],{"class":82},"(",[33,392,393],{"class":43},"'markdown'",[33,395,396],{"class":82},", () ",[33,398,399],{"class":72},"=>",[33,401,402],{"class":39}," parseMarkdown",[33,404,390],{"class":82},[33,406,407],{"class":43},"'::alert",[33,409,410],{"class":142},"\\n",[33,412,413],{"class":43},"Missing markdown input",[33,415,410],{"class":142},[33,417,418],{"class":43},"::'",[33,420,421],{"class":82},"))\n",[33,423,424,426,428],{"class":35,"line":168},[33,425,243],{"class":82},[33,427,333],{"class":332},[33,429,134],{"class":82},[33,431,432],{"class":35,"line":174},[33,433,165],{"emptyLinePlaceholder":164},[33,435,436,438,440],{"class":35,"line":179},[33,437,122],{"class":82},[33,439,208],{"class":332},[33,441,134],{"class":82},[33,443,444,446,448,451,453,456,459,461,464],{"class":35,"line":185},[33,445,216],{"class":82},[33,447,282],{"class":332},[33,449,450],{"class":39}," :body",[33,452,128],{"class":82},[33,454,455],{"class":43},"\"ast.body\"",[33,457,458],{"class":39}," :data",[33,460,128],{"class":82},[33,462,463],{"class":43},"\"ast.data\"",[33,465,237],{"class":82},[33,467,468,470,472],{"class":35,"line":190},[33,469,243],{"class":82},[33,471,208],{"class":332},[33,473,134],{"class":82},[11,475,476,477,484],{},"它还有第二个参数 ",[478,479,483],"a",{"href":480,"rel":481},"https://github.com/nuxt-modules/mdc/blob/main/src/runtime/types/parser.ts",[482],"nofollow","MDCParseOptions","，可以用来控制解析起的行为。",[11,486,487],{},[488,489],"img",{"alt":29,"src":490},"https://img.zzao.club/picgo/Pasted%20image%2020250111113759.png",[11,492,493],{},"也可以在 nuxt.config.ts 中配置",[24,495,497],{"className":63,"code":496,"language":65,"meta":29,"style":29},"import { defineNuxtConfig } from 'nuxt/config'\n\nexport default defineNuxtConfig({\n  modules: ['@nuxtjs/mdc'],\n  mdc: {\n    remarkPlugins: {\n      plugins: {\n        // Register/Configure remark plugin to extend the parser\n      }\n    },\n    rehypePlugins: {\n      options: {\n        // Configure rehype options to extend the parser\n      },\n      plugins: {\n        // Register/Configure rehype plugin to extend the parser\n      }\n    },\n    headings: {\n      anchorLinks: {\n        // Enable/Disable heading anchor links. { h1: true, h2: false }\n      }\n    },\n    highlight: false, // Control syntax highlighting\n    components: {\n      prose: false, // Add predefined map to render Prose Components instead of HTML tags, like p, ul, code\n      map: {\n        // This map will be used in `\u003CMDCRenderer>` to control rendered components\n      }\n    }\n  }\n})\n",[15,498,499,511,515,525,534,539,544,549,555,560,565,570,575,580,586,591,597,602,607,613,619,625,630,635,650,656,669,675,681,686,692,698],{"__ignoreMap":29},[33,500,501,503,506,508],{"class":35,"line":36},[33,502,306],{"class":72},[33,504,505],{"class":82}," { defineNuxtConfig } ",[33,507,312],{"class":72},[33,509,510],{"class":43}," 'nuxt/config'\n",[33,512,513],{"class":35,"line":86},[33,514,165],{"emptyLinePlaceholder":164},[33,516,517,519,521,523],{"class":35,"line":98},[33,518,73],{"class":72},[33,520,76],{"class":72},[33,522,79],{"class":39},[33,524,83],{"class":82},[33,526,527,529,531],{"class":35,"line":161},[33,528,89],{"class":82},[33,530,92],{"class":43},[33,532,533],{"class":82},"],\n",[33,535,536],{"class":35,"line":168},[33,537,538],{"class":82},"  mdc: {\n",[33,540,541],{"class":35,"line":174},[33,542,543],{"class":82},"    remarkPlugins: {\n",[33,545,546],{"class":35,"line":179},[33,547,548],{"class":82},"      plugins: {\n",[33,550,551],{"class":35,"line":185},[33,552,554],{"class":553},"sAwPA","        // Register/Configure remark plugin to extend the parser\n",[33,556,557],{"class":35,"line":190},[33,558,559],{"class":82},"      }\n",[33,561,562],{"class":35,"line":198},[33,563,564],{"class":82},"    },\n",[33,566,567],{"class":35,"line":203},[33,568,569],{"class":82},"    rehypePlugins: {\n",[33,571,572],{"class":35,"line":213},[33,573,574],{"class":82},"      options: {\n",[33,576,577],{"class":35,"line":240},[33,578,579],{"class":553},"        // Configure rehype options to extend the parser\n",[33,581,583],{"class":35,"line":582},14,[33,584,585],{"class":82},"      },\n",[33,587,589],{"class":35,"line":588},15,[33,590,548],{"class":82},[33,592,594],{"class":35,"line":593},16,[33,595,596],{"class":553},"        // Register/Configure rehype plugin to extend the parser\n",[33,598,600],{"class":35,"line":599},17,[33,601,559],{"class":82},[33,603,605],{"class":35,"line":604},18,[33,606,564],{"class":82},[33,608,610],{"class":35,"line":609},19,[33,611,612],{"class":82},"    headings: {\n",[33,614,616],{"class":35,"line":615},20,[33,617,618],{"class":82},"      anchorLinks: {\n",[33,620,622],{"class":35,"line":621},21,[33,623,624],{"class":553},"        // Enable/Disable heading anchor links. { h1: true, h2: false }\n",[33,626,628],{"class":35,"line":627},22,[33,629,559],{"class":82},[33,631,633],{"class":35,"line":632},23,[33,634,564],{"class":82},[33,636,638,641,644,647],{"class":35,"line":637},24,[33,639,640],{"class":82},"    highlight: ",[33,642,643],{"class":142},"false",[33,645,646],{"class":82},", ",[33,648,649],{"class":553},"// Control syntax highlighting\n",[33,651,653],{"class":35,"line":652},25,[33,654,655],{"class":82},"    components: {\n",[33,657,659,662,664,666],{"class":35,"line":658},26,[33,660,661],{"class":82},"      prose: ",[33,663,643],{"class":142},[33,665,646],{"class":82},[33,667,668],{"class":553},"// Add predefined map to render Prose Components instead of HTML tags, like p, ul, code\n",[33,670,672],{"class":35,"line":671},27,[33,673,674],{"class":82},"      map: {\n",[33,676,678],{"class":35,"line":677},28,[33,679,680],{"class":553},"        // This map will be used in `\u003CMDCRenderer>` to control rendered components\n",[33,682,684],{"class":35,"line":683},29,[33,685,559],{"class":82},[33,687,689],{"class":35,"line":688},30,[33,690,691],{"class":82},"    }\n",[33,693,695],{"class":35,"line":694},31,[33,696,697],{"class":82},"  }\n",[33,699,701],{"class":35,"line":700},32,[33,702,101],{"class":82},[11,704,705],{},[262,706,707],{},"点进去可以看到，这地址都 404 了，文件都删了，这就是为什么我要写这篇文章....",[11,709,710,711,714,715,718,719,722,723,726],{},"事实上，",[15,712,713],{},"mdc"," 底层用到的很多插件，都是和 ",[15,716,717],{},"unified"," 的生态是一致的（都是基于",[15,720,721],{},"remarkPlugins","、",[15,724,725],{},"rehypePlugins","）。",[11,728,729,730,732,733,722,735,738,739,742],{},"但是 ",[15,731,713],{}," 搞的有点太封闭。没导出几个有用的Api，其实完全可以把关于 ",[15,734,259],{},[15,736,737],{},"html","、以及中间的 ",[15,740,741],{},"hastTree"," 都开放出来。",[11,744,745,746,748],{},"因为 ",[15,747,259],{}," 相关的内容，虽然没有官方的标准，但是因为使用范围很广，早就成了事实意义上的标准。有用的人自然会用了，不用的压根都不会看一眼。",[11,750,751,752,754,755,758],{},"实际使用中，这种方式还没有找到使用场景（在内容渲染中），不管是自己本地的数据，还是从第三方 API获取到数据，直接扔给 ",[15,753,112],{}," 组件是最方便的，在数据中存储原始数据（",[15,756,757],{},"rawbody","），在不同平台展示时自身处理渲染逻辑。",[11,760,761,762,765,766,769],{},"PS：但要做 RSS 订阅就不得不把生成后的 ",[15,763,764],{},"HTML"," 放在 ",[15,767,768],{},"xml"," 中 ，这就是我上边为啥吐槽它太封闭。",[11,771,772],{},[15,773,774],{},"MDCSlot",[11,776,777,778,781,782,784,785,787,788,790,791,793],{},"这个组件是为了替代 Vue 中的 ",[15,779,780],{},"slot"," 组件，针对 ",[15,783,112],{}," 做了特殊处理，使用这个组件时你可以删除其包裹元素",[15,786,11],{},"，（使用 ",[15,789,780],{}," 时会默认渲染一个 ",[15,792,11],{}," 标签包裹文字内容）",[11,795,796],{},[15,797,798],{},"demo.md",[24,800,804],{"className":801,"code":802,"language":803,"meta":29,"style":29},"language-md shiki shiki-themes github-light","ddddsadadasdasd\n","md",[15,805,806],{"__ignoreMap":29},[33,807,808],{"class":35,"line":36},[33,809,802],{},[11,811,812],{},[15,813,814],{},"ProseP.vue",[24,816,818],{"className":321,"code":817,"language":323,"meta":29,"style":29},"\u003Ctemplate>\n  \u003Cp>\n    \u003C!-- MDCSlot will only render the actual text without the wrapping \u003Cp> -->\n    \u003CMDCSlot unwrap=\"p\" />\n  \u003C/p>\n\u003C/template>\n\n",[15,819,820,828,836,841,858,867],{"__ignoreMap":29},[33,821,822,824,826],{"class":35,"line":36},[33,823,122],{"class":82},[33,825,208],{"class":332},[33,827,134],{"class":82},[33,829,830,832,834],{"class":35,"line":86},[33,831,216],{"class":82},[33,833,11],{"class":332},[33,835,134],{"class":82},[33,837,838],{"class":35,"line":98},[33,839,840],{"class":553},"    \u003C!-- MDCSlot will only render the actual text without the wrapping \u003Cp> -->\n",[33,842,843,846,848,851,853,856],{"class":35,"line":161},[33,844,845],{"class":82},"    \u003C",[33,847,774],{"class":332},[33,849,850],{"class":39}," unwrap",[33,852,128],{"class":82},[33,854,855],{"class":43},"\"p\"",[33,857,237],{"class":82},[33,859,860,863,865],{"class":35,"line":168},[33,861,862],{"class":82},"  \u003C/",[33,864,11],{"class":332},[33,866,134],{"class":82},[33,868,869,871,873],{"class":35,"line":174},[33,870,243],{"class":82},[33,872,208],{"class":332},[33,874,134],{"class":82},[11,876,877],{},"当你输入两段纯文本，并且中间有一段空行时，这两段文本会分别被 p 标签包裹，做到换行的效果。",[11,879,880,881,883,884,886,887,889],{},"而如果用上述的 ",[15,882,814],{}," 覆盖后，纯文本将不再被 ",[15,885,11],{}," 标签包裹，而是变成了 ",[15,888,33],{},"，也就是你在写 md 时，哪怕已经换了行，渲染后的内容也是连贯的排列在一起的。",[11,891,892],{},"那 ProseComponent 是什么呢",[20,894,896],{"id":895},"prose-component","Prose Component",[11,898,899,901,902,904,905,907],{},[15,900,112],{}," 渲染 ",[15,903,259],{}," 内容时，使用了一套组件来渲染对应的 ",[15,906,259],{}," 语法",[11,909,910],{},[488,911],{"alt":29,"src":912},"https://img.zzao.club/picgo/CleanShot%202025-01-11%20at%2011.28.56.png",[11,914,915],{},"同样的也支持你覆盖这些组件",[11,917,918,919,922,923,926,927,930,931],{},"如果你使用 ",[15,920,921],{},"nuxt3.15.1"," 并且开启了    ",[15,924,925],{},"compatibilityVersion: 4","，那你的 ",[15,928,929],{},"components"," 路径应该是在 ",[15,932,933],{},"app/components",[11,935,936,937,939,940,942,943],{},"在此路径下新建目录 ",[15,938,713],{}," ，然后创建一个同名的 ",[15,941,323],{}," 文件：",[15,944,945],{},"ProseA.vue",[11,947,948],{},[488,949],{"alt":29,"src":950},"https://img.zzao.club/picgo/Pasted%20image%2020250111114806.png",[11,952,953],{},"我改写了其样式，并且把跳转默认为打开新标签页",[11,955,956],{},[488,957],{"alt":29,"src":958},"https://img.zzao.club/picgo/Pasted%20image%2020250111114847.png",[11,960,961],{},"可以看到如上渲染内容",[20,963,964],{"id":964},"自定义组件",[11,966,967,969,970,972,973,975],{},[15,968,112],{}," 还支持在 ",[15,971,259],{}," 中写 ",[15,974,323],{}," 组件，语法是这样的",[11,977,978],{},[15,979,798],{},[24,981,983],{"className":801,"code":982,"language":803,"meta":29,"style":29},"::component-name\nThis is an vue component\n::\n",[15,984,985,990,995],{"__ignoreMap":29},[33,986,987],{"class":35,"line":36},[33,988,989],{},"::component-name\n",[33,991,992],{"class":35,"line":86},[33,993,994],{},"This is an vue component\n",[33,996,997],{"class":35,"line":98},[33,998,999],{},"::\n",[11,1001,1002,1003],{},"对应 ",[15,1004,1005],{},"app/components/mdc/ComponentName.vue",[11,1007,1008,1009],{},"如果你正在搭配 Nuxt Content 使用，则对应目录为 ",[15,1010,1011],{},"app/components/content/ComponentName.vue",[11,1013,1014],{},[262,1015,1016],{},"再来个更实际的例子",[11,1018,1019],{},"md 内容为：",[24,1021,1023],{"className":801,"code":1022,"language":803,"meta":29,"style":29},"下面是一个 CustomTag 组件\n\n::custom-tag\n内部内容演示\n::\n\n组件位于`app/components/mdc/CustomTag.vue`\n",[15,1024,1025,1030,1034,1039,1044,1048,1052],{"__ignoreMap":29},[33,1026,1027],{"class":35,"line":36},[33,1028,1029],{},"下面是一个 CustomTag 组件\n",[33,1031,1032],{"class":35,"line":86},[33,1033,165],{"emptyLinePlaceholder":164},[33,1035,1036],{"class":35,"line":98},[33,1037,1038],{},"::custom-tag\n",[33,1040,1041],{"class":35,"line":161},[33,1042,1043],{},"内部内容演示\n",[33,1045,1046],{"class":35,"line":168},[33,1047,999],{},[33,1049,1050],{"class":35,"line":174},[33,1051,165],{"emptyLinePlaceholder":164},[33,1053,1054],{"class":35,"line":179},[33,1055,1056],{},"组件位于`app/components/mdc/CustomTag.vue`\n",[11,1058,1059,1062],{},[15,1060,1061],{},"CustomTag.vue"," 内容为：",[24,1064,1066],{"className":321,"code":1065,"language":323,"meta":29,"style":29},"\u003Ctemplate>\n  \u003Cdiv class=\"text-center my-10\">\n    \u003Cdiv\n      class=\"text-black px-3 py-2 text-lg font-bold\">\n      \u003Cslot/>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\n\n\u003C/script>\n",[15,1067,1068,1076,1093,1100,1112,1124,1133,1141,1149,1153,1169,1173],{"__ignoreMap":29},[33,1069,1070,1072,1074],{"class":35,"line":36},[33,1071,122],{"class":82},[33,1073,208],{"class":332},[33,1075,134],{"class":82},[33,1077,1078,1080,1083,1086,1088,1091],{"class":35,"line":86},[33,1079,216],{"class":82},[33,1081,1082],{"class":332},"div",[33,1084,1085],{"class":39}," class",[33,1087,128],{"class":82},[33,1089,1090],{"class":43},"\"text-center my-10\"",[33,1092,134],{"class":82},[33,1094,1095,1097],{"class":35,"line":98},[33,1096,845],{"class":82},[33,1098,1099],{"class":332},"div\n",[33,1101,1102,1105,1107,1110],{"class":35,"line":161},[33,1103,1104],{"class":39},"      class",[33,1106,128],{"class":82},[33,1108,1109],{"class":43},"\"text-black px-3 py-2 text-lg font-bold\"",[33,1111,134],{"class":82},[33,1113,1114,1117,1119,1122],{"class":35,"line":168},[33,1115,1116],{"class":82},"      \u003C",[33,1118,780],{"class":332},[33,1120,1121],{"class":157},"/",[33,1123,134],{"class":82},[33,1125,1126,1129,1131],{"class":35,"line":174},[33,1127,1128],{"class":82},"    \u003C/",[33,1130,1082],{"class":332},[33,1132,134],{"class":82},[33,1134,1135,1137,1139],{"class":35,"line":179},[33,1136,862],{"class":82},[33,1138,1082],{"class":332},[33,1140,134],{"class":82},[33,1142,1143,1145,1147],{"class":35,"line":185},[33,1144,243],{"class":82},[33,1146,208],{"class":332},[33,1148,134],{"class":82},[33,1150,1151],{"class":35,"line":190},[33,1152,165],{"emptyLinePlaceholder":164},[33,1154,1155,1157,1159,1161,1163,1165,1167],{"class":35,"line":198},[33,1156,122],{"class":82},[33,1158,333],{"class":332},[33,1160,336],{"class":39},[33,1162,339],{"class":39},[33,1164,128],{"class":82},[33,1166,131],{"class":43},[33,1168,134],{"class":82},[33,1170,1171],{"class":35,"line":203},[33,1172,165],{"emptyLinePlaceholder":164},[33,1174,1175,1177,1179],{"class":35,"line":213},[33,1176,243],{"class":82},[33,1178,333],{"class":332},[33,1180,134],{"class":82},[11,1182,1183,1184],{},"渲染后的结果为：\n",[488,1185],{"alt":29,"src":1186},"https://img.zzao.club/picgo/Pasted%20image%2020250111185601.png",[11,1188,1189,1190,1193,1194,1197],{},"这种组件被称为 ",[15,1191,1192],{},"Block Components"," ，和 ",[15,1195,1196],{},"display: block"," 的意思相同，是个块级组件，单独占一行",[11,1199,1200],{},"既然是Vue组件，也给它传 props",[24,1202,1204],{"className":801,"code":1203,"language":803,"meta":29,"style":29},"::custom-tag{type=\"warning\"}\n内部内容演示\n::\n",[15,1205,1206,1211,1215],{"__ignoreMap":29},[33,1207,1208],{"class":35,"line":36},[33,1209,1210],{},"::custom-tag{type=\"warning\"}\n",[33,1212,1213],{"class":35,"line":86},[33,1214,1043],{},[33,1216,1217],{"class":35,"line":98},[33,1218,999],{},[11,1220,1221],{},"再把组件改一下",[24,1223,1225],{"className":321,"code":1224,"language":323,"meta":29,"style":29},"\u003Ctemplate>\n  \u003Cdiv class=\"text-center my-10\">\n    \u003Cdiv\n      class=\"text-black px-3 py-2 text-lg font-bold\" :class=\"{ 'bg-yellow-200': props.type === 'warning', 'bg-blue-200': props.type === 'info', 'bg-green-200': props.type === 'success', 'bg-red-200': props.type === 'error' }\">\n      \u003Cslot/>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{\n  type?: 'warning’ | ‘info’ | ‘success’ | ‘error’'\n}>()\n\u003C/script>\n",[15,1226,1227,1235,1249,1255,1273,1283,1291,1299,1307,1311,1327,1342,1353,1358],{"__ignoreMap":29},[33,1228,1229,1231,1233],{"class":35,"line":36},[33,1230,122],{"class":82},[33,1232,208],{"class":332},[33,1234,134],{"class":82},[33,1236,1237,1239,1241,1243,1245,1247],{"class":35,"line":86},[33,1238,216],{"class":82},[33,1240,1082],{"class":332},[33,1242,1085],{"class":39},[33,1244,128],{"class":82},[33,1246,1090],{"class":43},[33,1248,134],{"class":82},[33,1250,1251,1253],{"class":35,"line":98},[33,1252,845],{"class":82},[33,1254,1099],{"class":332},[33,1256,1257,1259,1261,1263,1266,1268,1271],{"class":35,"line":161},[33,1258,1104],{"class":39},[33,1260,128],{"class":82},[33,1262,1109],{"class":43},[33,1264,1265],{"class":39}," :class",[33,1267,128],{"class":82},[33,1269,1270],{"class":43},"\"{ 'bg-yellow-200': props.type === 'warning', 'bg-blue-200': props.type === 'info', 'bg-green-200': props.type === 'success', 'bg-red-200': props.type === 'error' }\"",[33,1272,134],{"class":82},[33,1274,1275,1277,1279,1281],{"class":35,"line":168},[33,1276,1116],{"class":82},[33,1278,780],{"class":332},[33,1280,1121],{"class":157},[33,1282,134],{"class":82},[33,1284,1285,1287,1289],{"class":35,"line":174},[33,1286,1128],{"class":82},[33,1288,1082],{"class":332},[33,1290,134],{"class":82},[33,1292,1293,1295,1297],{"class":35,"line":179},[33,1294,862],{"class":82},[33,1296,1082],{"class":332},[33,1298,134],{"class":82},[33,1300,1301,1303,1305],{"class":35,"line":185},[33,1302,243],{"class":82},[33,1304,208],{"class":332},[33,1306,134],{"class":82},[33,1308,1309],{"class":35,"line":190},[33,1310,165],{"emptyLinePlaceholder":164},[33,1312,1313,1315,1317,1319,1321,1323,1325],{"class":35,"line":198},[33,1314,122],{"class":82},[33,1316,333],{"class":332},[33,1318,336],{"class":39},[33,1320,339],{"class":39},[33,1322,128],{"class":82},[33,1324,131],{"class":43},[33,1326,134],{"class":82},[33,1328,1329,1331,1334,1336,1339],{"class":35,"line":203},[33,1330,139],{"class":72},[33,1332,1333],{"class":142}," props",[33,1335,146],{"class":72},[33,1337,1338],{"class":39}," defineProps",[33,1340,1341],{"class":82},"\u003C{\n",[33,1343,1344,1347,1350],{"class":35,"line":213},[33,1345,1346],{"class":369},"  type",[33,1348,1349],{"class":72},"?:",[33,1351,1352],{"class":43}," 'warning’ | ‘info’ | ‘success’ | ‘error’'\n",[33,1354,1355],{"class":35,"line":240},[33,1356,1357],{"class":82},"}>()\n",[33,1359,1360,1362,1364],{"class":35,"line":582},[33,1361,243],{"class":82},[33,1363,333],{"class":332},[33,1365,134],{"class":82},[11,1367,1368],{},"`\n看下渲染的内容：",[11,1370,1371],{},[488,1372],{"alt":29,"src":1373},"https://img.zzao.club/picgo/Pasted%20image%2020250111185907.png",[11,1375,1376],{},"也可以直接传 style",[24,1378,1380],{"className":801,"code":1379,"language":803,"meta":29,"style":29},"::custom-tag{type=\"warning\" style=\"margin-top:100px;\"} \n内部内容演示 \n::\n",[15,1381,1382,1387,1392],{"__ignoreMap":29},[33,1383,1384],{"class":35,"line":36},[33,1385,1386],{},"::custom-tag{type=\"warning\" style=\"margin-top:100px;\"} \n",[33,1388,1389],{"class":35,"line":86},[33,1390,1391],{},"内部内容演示 \n",[33,1393,1394],{"class":35,"line":98},[33,1395,999],{},[11,1397,1398],{},"可以看到有了一个很大的间距",[11,1400,1401],{},[488,1402],{"alt":29,"src":1403},"https://img.zzao.club/picgo/Pasted%20image%2020250111190522.png",[11,1405,1406],{},"还支持使用 YAML method 的方式传入",[24,1408,1410],{"className":801,"code":1409,"language":803,"meta":29,"style":29},"::custom-tag{type=\"warning\" style=\"margin-top:100px;\"} \n---\ndesc: \"我是描述内容\"\n---\n::\n",[15,1411,1412,1416,1421,1426,1430],{"__ignoreMap":29},[33,1413,1414],{"class":35,"line":36},[33,1415,1386],{},[33,1417,1418],{"class":35,"line":86},[33,1419,1420],{},"---\n",[33,1422,1423],{"class":35,"line":98},[33,1424,1425],{},"desc: \"我是描述内容\"\n",[33,1427,1428],{"class":35,"line":161},[33,1429,1420],{},[33,1431,1432],{"class":35,"line":168},[33,1433,999],{},[11,1435,1436],{},"把组件改为",[24,1438,1440],{"className":321,"code":1439,"language":323,"meta":29,"style":29},"\u003Ctemplate>\n  \u003Cdiv class=\"text-center my-10\">\n    \u003Cdiv\n      class=\"text-black px-3 py-2 text-lg font-bold\" :class=\"{ 'bg-yellow-200': props.type === 'warning', 'bg-blue-200': props.type === 'info', 'bg-green-200': props.type === 'success', 'bg-red-200': props.type === 'error' }\">\n      \u003Cdiv class=\"title\">\n        {{ props.type }}\n      \u003C/div>\n\n      \u003Cdiv class=\"desc text-red-600\">\n        {{ desc }}\n      \u003C/div>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{\n  type?: 'warning' | 'info' | 'success' | 'error',\n  desc?: string\n}>()\n\u003C/script>\n",[15,1441,1442,1450,1464,1470,1486,1501,1506,1515,1519,1534,1539,1547,1555,1563,1571,1575,1591,1603,1631,1641,1645],{"__ignoreMap":29},[33,1443,1444,1446,1448],{"class":35,"line":36},[33,1445,122],{"class":82},[33,1447,208],{"class":332},[33,1449,134],{"class":82},[33,1451,1452,1454,1456,1458,1460,1462],{"class":35,"line":86},[33,1453,216],{"class":82},[33,1455,1082],{"class":332},[33,1457,1085],{"class":39},[33,1459,128],{"class":82},[33,1461,1090],{"class":43},[33,1463,134],{"class":82},[33,1465,1466,1468],{"class":35,"line":98},[33,1467,845],{"class":82},[33,1469,1099],{"class":332},[33,1471,1472,1474,1476,1478,1480,1482,1484],{"class":35,"line":161},[33,1473,1104],{"class":39},[33,1475,128],{"class":82},[33,1477,1109],{"class":43},[33,1479,1265],{"class":39},[33,1481,128],{"class":82},[33,1483,1270],{"class":43},[33,1485,134],{"class":82},[33,1487,1488,1490,1492,1494,1496,1499],{"class":35,"line":168},[33,1489,1116],{"class":82},[33,1491,1082],{"class":332},[33,1493,1085],{"class":39},[33,1495,128],{"class":82},[33,1497,1498],{"class":43},"\"title\"",[33,1500,134],{"class":82},[33,1502,1503],{"class":35,"line":174},[33,1504,1505],{"class":82},"        {{ props.type }}\n",[33,1507,1508,1511,1513],{"class":35,"line":179},[33,1509,1510],{"class":82},"      \u003C/",[33,1512,1082],{"class":332},[33,1514,134],{"class":82},[33,1516,1517],{"class":35,"line":185},[33,1518,165],{"emptyLinePlaceholder":164},[33,1520,1521,1523,1525,1527,1529,1532],{"class":35,"line":190},[33,1522,1116],{"class":82},[33,1524,1082],{"class":332},[33,1526,1085],{"class":39},[33,1528,128],{"class":82},[33,1530,1531],{"class":43},"\"desc text-red-600\"",[33,1533,134],{"class":82},[33,1535,1536],{"class":35,"line":198},[33,1537,1538],{"class":82},"        {{ desc }}\n",[33,1540,1541,1543,1545],{"class":35,"line":203},[33,1542,1510],{"class":82},[33,1544,1082],{"class":332},[33,1546,134],{"class":82},[33,1548,1549,1551,1553],{"class":35,"line":213},[33,1550,1128],{"class":82},[33,1552,1082],{"class":332},[33,1554,134],{"class":82},[33,1556,1557,1559,1561],{"class":35,"line":240},[33,1558,862],{"class":82},[33,1560,1082],{"class":332},[33,1562,134],{"class":82},[33,1564,1565,1567,1569],{"class":35,"line":582},[33,1566,243],{"class":82},[33,1568,208],{"class":332},[33,1570,134],{"class":82},[33,1572,1573],{"class":35,"line":588},[33,1574,165],{"emptyLinePlaceholder":164},[33,1576,1577,1579,1581,1583,1585,1587,1589],{"class":35,"line":593},[33,1578,122],{"class":82},[33,1580,333],{"class":332},[33,1582,336],{"class":39},[33,1584,339],{"class":39},[33,1586,128],{"class":82},[33,1588,131],{"class":43},[33,1590,134],{"class":82},[33,1592,1593,1595,1597,1599,1601],{"class":35,"line":599},[33,1594,139],{"class":72},[33,1596,1333],{"class":142},[33,1598,146],{"class":72},[33,1600,1338],{"class":39},[33,1602,1341],{"class":82},[33,1604,1605,1607,1609,1612,1615,1618,1620,1623,1625,1628],{"class":35,"line":604},[33,1606,1346],{"class":369},[33,1608,1349],{"class":72},[33,1610,1611],{"class":43}," 'warning'",[33,1613,1614],{"class":72}," |",[33,1616,1617],{"class":43}," 'info'",[33,1619,1614],{"class":72},[33,1621,1622],{"class":43}," 'success'",[33,1624,1614],{"class":72},[33,1626,1627],{"class":43}," 'error'",[33,1629,1630],{"class":82},",\n",[33,1632,1633,1636,1638],{"class":35,"line":609},[33,1634,1635],{"class":369},"  desc",[33,1637,1349],{"class":72},[33,1639,1640],{"class":142}," string\n",[33,1642,1643],{"class":35,"line":615},[33,1644,1357],{"class":82},[33,1646,1647,1649,1651],{"class":35,"line":621},[33,1648,243],{"class":82},[33,1650,333],{"class":332},[33,1652,134],{"class":82},[11,1654,1655],{},"渲染后：",[11,1657,1658],{},[488,1659],{"alt":29,"src":1660},"https://img.zzao.club/picgo/Pasted%20image%2020250111191131.png",[11,1662,1663,1664,1667],{},"不过这种方式，",[262,1665,1666],{},"不能和 slot 混用","，渲染出来 slot 会把几个 props 都覆盖。",[11,1669,1670,1671,277],{},"实际使用时，",[262,1672,1673],{},"不应该对一个内容写如此复杂的组件",[11,1675,1676,1677,1679],{},"换句话说，Vue 组件应该足够完善， 让你在 ",[15,1678,259],{}," 中写足够少的信息，只传入必要的数据即可得到完美的展示才对。",[11,1681,1682,1683,1686,1687,1689],{},"上面的 ",[15,1684,1685],{},"Props"," 是我们自定义的组件提前写好的 ",[15,1688,1685],{}," ，而内置的 Prose Components 也是一套 Vue 组件而已。",[11,1691,1692,1693,1696,1697,1699,1700,1703],{},"所以除了在 ",[15,1694,1695],{},"app/components/mdc/"," 下创建一个同名的 ",[15,1698,896],{}," 覆盖原有组件，也可以直接给原组件传一些 ",[15,1701,1702],{},"style","，改变它的样式。",[24,1705,1707],{"className":801,"code":1706,"language":803,"meta":29,"style":29},"Attributes work on:\n\n- ![favicon](/favicon.ico){style=\"display: inline; margin: 0;\"} image,\n- [link](#attributes){style=\"background-color: pink;\"}, `code`{style=\"color: cyan;\"},\n- _italic_{style=\"background-color: yellow; color:black;\"} and **bold**{style=\"background-color: lightgreen;\"} texts.\n\n",[15,1708,1709,1714,1718,1723,1728],{"__ignoreMap":29},[33,1710,1711],{"class":35,"line":36},[33,1712,1713],{},"Attributes work on:\n",[33,1715,1716],{"class":35,"line":86},[33,1717,165],{"emptyLinePlaceholder":164},[33,1719,1720],{"class":35,"line":98},[33,1721,1722],{},"- ![favicon](/favicon.ico){style=\"display: inline; margin: 0;\"} image,\n",[33,1724,1725],{"class":35,"line":161},[33,1726,1727],{},"- [link](#attributes){style=\"background-color: pink;\"}, `code`{style=\"color: cyan;\"},\n",[33,1729,1730],{"class":35,"line":168},[33,1731,1732],{},"- _italic_{style=\"background-color: yellow; color:black;\"} and **bold**{style=\"background-color: lightgreen;\"} texts.\n",[11,1734,1735],{},"除了使用一个 Vue 组件并给他传 Props，设置 style",[11,1737,1738,1739,1742],{},"还能使用 ",[15,1740,1741],{},":ComponentName","  的语法直接使用一个写好的组件，比如这样",[24,1744,1746],{"className":801,"code":1745,"language":803,"meta":29,"style":29},"# Title\n\n:banner\n",[15,1747,1748,1753,1757],{"__ignoreMap":29},[33,1749,1750],{"class":35,"line":36},[33,1751,1752],{},"# Title\n",[33,1754,1755],{"class":35,"line":86},[33,1756,165],{"emptyLinePlaceholder":164},[33,1758,1759],{"class":35,"line":98},[33,1760,1761],{},":banner\n",[11,1763,1764],{},[15,1765,1766],{},"Banner.vue",[24,1768,1770],{"className":321,"code":1769,"language":323,"meta":29,"style":29},"\u003Ctemplate>\n  \u003Caside>\n    This component does not have any children.\n  \u003C/aside>\n\u003C/template>\n",[15,1771,1772,1780,1789,1794,1802],{"__ignoreMap":29},[33,1773,1774,1776,1778],{"class":35,"line":36},[33,1775,122],{"class":82},[33,1777,208],{"class":332},[33,1779,134],{"class":82},[33,1781,1782,1784,1787],{"class":35,"line":86},[33,1783,216],{"class":82},[33,1785,1786],{"class":332},"aside",[33,1788,134],{"class":82},[33,1790,1791],{"class":35,"line":98},[33,1792,1793],{"class":82},"    This component does not have any children.\n",[33,1795,1796,1798,1800],{"class":35,"line":161},[33,1797,862],{"class":82},[33,1799,1786],{"class":332},[33,1801,134],{"class":82},[33,1803,1804,1806,1808],{"class":35,"line":168},[33,1805,243],{"class":82},[33,1807,208],{"class":332},[33,1809,134],{"class":82},[11,1811,1812],{},"这在自己定制的平台上使用时，会很有用。 但同样的，如果你使用其他软件或 API 来获取 md，要考虑一下语法过多导致的各平台不兼容问题。",[11,1814,1815,1816,1818,1819,1821],{},"PS: 这种md里写属性传值的方式并不是 ",[15,1817,713],{}," 的原创，而是 ",[15,1820,717],{}," （remark/rehype）插件相关的生态，都是这样写的。",[20,1823,1824],{"id":1824},"绑定数据",[11,1826,1827],{},"贴两个官方的例子，很好理解",[11,1829,1830],{},"第一种是在 Markdown 的 YAML 中定义：",[24,1832,1834],{"className":801,"code":1833,"language":803,"meta":29,"style":29},"---\ntitle: 'Title of the page'\ndescription: 'meta description of the page'\ncustomVariable: 'Custom Value'\n---\n\n# The Title is {{ $doc.title }} and customVariable is {{ $doc.customVariable || 'defaultValue' }}\n\n",[15,1835,1836,1840,1845,1850,1855,1859,1863],{"__ignoreMap":29},[33,1837,1838],{"class":35,"line":36},[33,1839,1420],{},[33,1841,1842],{"class":35,"line":86},[33,1843,1844],{},"title: 'Title of the page'\n",[33,1846,1847],{"class":35,"line":98},[33,1848,1849],{},"description: 'meta description of the page'\n",[33,1851,1852],{"class":35,"line":161},[33,1853,1854],{},"customVariable: 'Custom Value'\n",[33,1856,1857],{"class":35,"line":168},[33,1858,1420],{},[33,1860,1861],{"class":35,"line":174},[33,1862,165],{"emptyLinePlaceholder":164},[33,1864,1865],{"class":35,"line":179},[33,1866,1867],{},"# The Title is {{ $doc.title }} and customVariable is {{ $doc.customVariable || 'defaultValue' }}\n",[11,1869,1870],{},"这个用法很有局限，因为你用来写 md 文章的软件大概率不支持这个语法，或者你要同步到其他平台的时候其他平台也不会支持这个语法。",[11,1872,1873],{},"但是如果你的用途很单一，说不定会比较有用",[11,1875,1876],{},"第二种是定义在 Vue 组件中",[24,1878,1880],{"className":321,"code":1879,"language":323,"meta":29,"style":29},"\u003Ctemplate>\n  \u003Cdiv>\n    \u003CContentRenderer :value=\"data\" :data=\"mdcVars\"/>\n    \u003Cbutton type=\"button\" v-on:click=\"mdcVars.name = 'Hugo'\">Change name\u003C/button>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData(() => queryCollection('content').path('/test').first());\nconst mdcVars = ref({ name: 'Maxime'});\n\u003C/script>\n",[15,1881,1882,1890,1898,1922,1952,1960,1968,1972,1988,2036,2057],{"__ignoreMap":29},[33,1883,1884,1886,1888],{"class":35,"line":36},[33,1885,122],{"class":82},[33,1887,208],{"class":332},[33,1889,134],{"class":82},[33,1891,1892,1894,1896],{"class":35,"line":86},[33,1893,216],{"class":82},[33,1895,1082],{"class":332},[33,1897,134],{"class":82},[33,1899,1900,1902,1905,1907,1909,1912,1914,1916,1919],{"class":35,"line":98},[33,1901,845],{"class":82},[33,1903,1904],{"class":332},"ContentRenderer",[33,1906,221],{"class":39},[33,1908,128],{"class":82},[33,1910,1911],{"class":43},"\"data\"",[33,1913,458],{"class":39},[33,1915,128],{"class":82},[33,1917,1918],{"class":43},"\"mdcVars\"",[33,1920,1921],{"class":82},"/>\n",[33,1923,1924,1926,1929,1932,1934,1937,1940,1942,1945,1948,1950],{"class":35,"line":161},[33,1925,845],{"class":82},[33,1927,1928],{"class":332},"button",[33,1930,1931],{"class":39}," type",[33,1933,128],{"class":82},[33,1935,1936],{"class":43},"\"button\"",[33,1938,1939],{"class":39}," v-on:click",[33,1941,128],{"class":82},[33,1943,1944],{"class":43},"\"mdcVars.name = 'Hugo'\"",[33,1946,1947],{"class":82},">Change name\u003C/",[33,1949,1928],{"class":332},[33,1951,134],{"class":82},[33,1953,1954,1956,1958],{"class":35,"line":168},[33,1955,862],{"class":82},[33,1957,1082],{"class":332},[33,1959,134],{"class":82},[33,1961,1962,1964,1966],{"class":35,"line":174},[33,1963,243],{"class":82},[33,1965,208],{"class":332},[33,1967,134],{"class":82},[33,1969,1970],{"class":35,"line":179},[33,1971,165],{"emptyLinePlaceholder":164},[33,1973,1974,1976,1978,1980,1982,1984,1986],{"class":35,"line":185},[33,1975,122],{"class":82},[33,1977,333],{"class":332},[33,1979,336],{"class":39},[33,1981,339],{"class":39},[33,1983,128],{"class":82},[33,1985,131],{"class":43},[33,1987,134],{"class":82},[33,1989,1990,1992,1994,1996,1998,2000,2002,2004,2007,2009,2012,2014,2017,2020,2023,2025,2028,2030,2033],{"class":35,"line":190},[33,1991,139],{"class":72},[33,1993,366],{"class":82},[33,1995,370],{"class":142},[33,1997,379],{"class":82},[33,1999,128],{"class":72},[33,2001,384],{"class":72},[33,2003,387],{"class":39},[33,2005,2006],{"class":82},"(() ",[33,2008,399],{"class":72},[33,2010,2011],{"class":39}," queryCollection",[33,2013,390],{"class":82},[33,2015,2016],{"class":43},"'content'",[33,2018,2019],{"class":82},").",[33,2021,2022],{"class":39},"path",[33,2024,390],{"class":82},[33,2026,2027],{"class":43},"'/test'",[33,2029,2019],{"class":82},[33,2031,2032],{"class":39},"first",[33,2034,2035],{"class":82},"());\n",[33,2037,2038,2040,2043,2045,2048,2051,2054],{"class":35,"line":198},[33,2039,139],{"class":72},[33,2041,2042],{"class":142}," mdcVars",[33,2044,146],{"class":72},[33,2046,2047],{"class":39}," ref",[33,2049,2050],{"class":82},"({ name: ",[33,2052,2053],{"class":43},"'Maxime'",[33,2055,2056],{"class":82},"});\n",[33,2058,2059,2061,2063],{"class":35,"line":203},[33,2060,243],{"class":82},[33,2062,333],{"class":332},[33,2064,134],{"class":82},[11,2066,2067],{},"md 中",[24,2069,2071],{"className":801,"code":2070,"language":803,"meta":29,"style":29},"# Hello {{ $doc.name || 'World' }}\n",[15,2072,2073],{"__ignoreMap":29},[33,2074,2075],{"class":35,"line":36},[33,2076,2070],{},[11,2078,2079],{},"还是那种话，定制的越多，越不可控。",[11,2081,2082],{},"文章内容还是要以高质量的文字为准，自定义组件更多的是作为锦上添花，是离不开一个封闭的平台的。",[2084,2085],"hr",{},[11,2087,2088,2089,2091,2092,2095],{},"官方还给出了一种自定义组件的方式，就是在 ",[15,2090,59],{}," 中配置 ",[15,2093,2094],{},"prose: false","，关闭 Prose Components 的渲染方式，自定义一个 map 指定组件",[24,2097,2099],{"className":63,"code":2098,"language":65,"meta":29,"style":29},"mdc: {\n    // components: {\n    //   prose: false,\n      // map: {\n      //   'a': 'MemoProseA'\n      // }\n    // }\n  },\n",[15,2100,2101,2108,2113,2118,2123,2128,2133,2138],{"__ignoreMap":29},[33,2102,2103,2105],{"class":35,"line":36},[33,2104,713],{"class":39},[33,2106,2107],{"class":82},": {\n",[33,2109,2110],{"class":35,"line":86},[33,2111,2112],{"class":553},"    // components: {\n",[33,2114,2115],{"class":35,"line":98},[33,2116,2117],{"class":553},"    //   prose: false,\n",[33,2119,2120],{"class":35,"line":161},[33,2121,2122],{"class":553},"      // map: {\n",[33,2124,2125],{"class":35,"line":168},[33,2126,2127],{"class":553},"      //   'a': 'MemoProseA'\n",[33,2129,2130],{"class":35,"line":174},[33,2131,2132],{"class":553},"      // }\n",[33,2134,2135],{"class":35,"line":179},[33,2136,2137],{"class":553},"    // }\n",[33,2139,2140],{"class":35,"line":185},[33,2141,2142],{"class":82},"  },\n",[11,2144,2145],{},"但我觉得这种方式和直接在 mdc 目录在覆盖掉原组件的区别很小，这种方式可以做到只支持部分 md 语法的渲染，比如你只写一个 a ，那其他内容就是纯文本，只有 a 标签是通过自定义组件渲染出来的，不清楚什么场景下才会有这种选择～",[20,2147,2149],{"id":2148},"tailwind-css-主题","tailwind CSS 主题",[11,2151,2152,2153,2158],{},"Prose Components 支持使用 ",[478,2154,2157],{"href":2155,"rel":2156},"https://github.com/tailwindlabs/tailwindcss-typography",[482],"tailwindcss-typography"," 覆盖 html 排版",[11,2160,2161],{},"这是我觉得比较实用的样式修改方式，因为 tailwindcss 足够通用，并且在全局的固定位置修改样式，便于管理",[11,2163,2164,2165],{},"Tailwind CSS Typography 提供了一组 prose class，可以给默认的 html 元素附加排版，➡️点击查看",[478,2166,2169],{"href":2167,"rel":2168},"https://play.tailwindcss.com/uj1vGACRJA?layout=preview",[482],"演示",[24,2171,2174],{"className":2172,"code":2173,"language":737,"meta":29,"style":29},"language-html shiki shiki-themes github-light","\u003Carticle class=\"prose lg:prose-xl\">{{ markdown }}\u003C/article>\n",[15,2175,2176],{"__ignoreMap":29},[33,2177,2178,2180,2183,2185,2187,2190,2193,2195],{"class":35,"line":36},[33,2179,122],{"class":82},[33,2181,2182],{"class":332},"article",[33,2184,1085],{"class":39},[33,2186,128],{"class":82},[33,2188,2189],{"class":43},"\"prose lg:prose-xl\"",[33,2191,2192],{"class":82},">{{ markdown }}\u003C/",[33,2194,2182],{"class":332},[33,2196,134],{"class":82},[11,2198,2199],{},[262,2200,2201],{},"安装插件",[24,2203,2205],{"className":26,"code":2204,"language":28,"meta":29,"style":29},"npm install -D @tailwindcss/typography\n",[15,2206,2207],{"__ignoreMap":29},[33,2208,2209,2212,2215,2218],{"class":35,"line":36},[33,2210,2211],{"class":39},"npm",[33,2213,2214],{"class":43}," install",[33,2216,2217],{"class":142}," -D",[33,2219,2220],{"class":43}," @tailwindcss/typography\n",[11,2222,2223,2226,2227,2230],{},[262,2224,2225],{},"新建或添加","到 ",[15,2228,2229],{},"tailwind.config.js"," 中",[24,2232,2236],{"className":2233,"code":2234,"language":2235,"meta":29,"style":29},"language-js shiki shiki-themes github-light","/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  theme: {\n    // ...\n  },\n  plugins: [\n    require('@tailwindcss/typography'),\n    // ...\n  ],\n}\n","js",[15,2237,2238,2252,2268,2273,2278,2282,2287,2300,2304,2309],{"__ignoreMap":29},[33,2239,2240,2243,2246,2249],{"class":35,"line":36},[33,2241,2242],{"class":553},"/** ",[33,2244,2245],{"class":72},"@type",[33,2247,2248],{"class":39}," {import('tailwindcss').Config}",[33,2250,2251],{"class":553}," */\n",[33,2253,2254,2257,2260,2263,2265],{"class":35,"line":86},[33,2255,2256],{"class":142},"module",[33,2258,2259],{"class":82},".",[33,2261,2262],{"class":142},"exports",[33,2264,146],{"class":72},[33,2266,2267],{"class":82}," {\n",[33,2269,2270],{"class":35,"line":98},[33,2271,2272],{"class":82},"  theme: {\n",[33,2274,2275],{"class":35,"line":161},[33,2276,2277],{"class":553},"    // ...\n",[33,2279,2280],{"class":35,"line":168},[33,2281,2142],{"class":82},[33,2283,2284],{"class":35,"line":174},[33,2285,2286],{"class":82},"  plugins: [\n",[33,2288,2289,2292,2294,2297],{"class":35,"line":179},[33,2290,2291],{"class":39},"    require",[33,2293,390],{"class":82},[33,2295,2296],{"class":43},"'@tailwindcss/typography'",[33,2298,2299],{"class":82},"),\n",[33,2301,2302],{"class":35,"line":185},[33,2303,2277],{"class":553},[33,2305,2306],{"class":35,"line":190},[33,2307,2308],{"class":82},"  ],\n",[33,2310,2311],{"class":35,"line":198},[33,2312,2313],{"class":82},"}\n",[11,2315,2316],{},[262,2317,2318],{},"修改灰度",[24,2320,2325],{"className":2321,"code":2323,"language":2324},[2322],"language-text","prose prose-gray(默认) prose-slate prose-zinc prose-neutral prose-stone\n","text",[15,2326,2323],{"__ignoreMap":29},[11,2328,2329,2330,2333],{},"不管使用哪个，都要带有 ",[15,2331,2332],{},"prose"," 这个基类",[11,2335,2336],{},[262,2337,2338],{},"文字整体尺寸",[24,2340,2343],{"className":2341,"code":2342,"language":2324},[2322],"prose prose-sm (14px) prose-base (默认16px) prose-lg (18px) prose-xl (20px) prose-2xl (24px)\n",[15,2344,2342],{"__ignoreMap":29},[11,2346,2347,2348,2350,2351,2354],{},"和灰度一样，也要带有 ",[15,2349,2332],{}," 这个基类，实际使用下来，还是 ",[15,2352,2353],{},"prose-base"," 用的最多，可以在自己发文发帖的多个平台尝试不同字号",[11,2356,2357],{},[262,2358,2359],{},"适配深色模式",[11,2361,2362],{},"上面的几个调整灰度的主题，都有默认的深色模式版本，可以使用 prose-invert 来触发",[24,2364,2366],{"className":2172,"code":2365,"language":737,"meta":29,"style":29},"\u003Carticle class=\"prose dark:prose-invert\">{{ markdown }}\u003C/article>\n",[15,2367,2368],{"__ignoreMap":29},[33,2369,2370,2372,2374,2376,2378,2381,2383,2385],{"class":35,"line":36},[33,2371,122],{"class":82},[33,2373,2182],{"class":332},[33,2375,1085],{"class":39},[33,2377,128],{"class":82},[33,2379,2380],{"class":43},"\"prose dark:prose-invert\"",[33,2382,2192],{"class":82},[33,2384,2182],{"class":332},[33,2386,134],{"class":82},[11,2388,2389,2390,2393],{},"如果你使用了自定义组件，则需要自己使用 ",[15,2391,2392],{},"dark:"," 修饰符适配一下深色模式",[11,2395,2396,2399,2400,2403],{},[15,2397,2398],{},"Nuxt"," 中使用 ",[15,2401,2402],{},"@nuxtjs/color-mode"," 来控制颜色模式",[11,2405,2406],{},[262,2407,2408],{},"精细化控制样式",[11,2410,2411,2412,2415],{},"除了全局设置默认的样式，也可以通过 ",[15,2413,2414],{},"prose-xxx"," 来控制目标标签的样式",[11,2417,2418],{},[488,2419],{"alt":29,"src":2420},"https://img.zzao.club/picgo/Pasted%20image%2020250112101943.png",[11,2422,2423],{},"像这样：",[24,2425,2427],{"className":2172,"code":2426,"language":737,"meta":29,"style":29},"\u003Carticle class=\"prose prose-a:text-blue-600 hover:prose-a:text-blue-500\">{{ markdown }}\u003C/article>\n",[15,2428,2429],{"__ignoreMap":29},[33,2430,2431,2433,2435,2437,2439,2442,2444,2446],{"class":35,"line":36},[33,2432,122],{"class":82},[33,2434,2182],{"class":332},[33,2436,1085],{"class":39},[33,2438,128],{"class":82},[33,2440,2441],{"class":43},"\"prose prose-a:text-blue-600 hover:prose-a:text-blue-500\"",[33,2443,2192],{"class":82},[33,2445,2182],{"class":332},[33,2447,134],{"class":82},[11,2449,2450,2451],{},"另外，每个修饰符都为了保证内容的可读性，设置了最大宽度。 如果你希望内容能够填充其容器的宽度，可以使用 ",[15,2452,2453],{},"max-w-none",[24,2455,2457],{"className":2172,"code":2456,"language":737,"meta":29,"style":29},"\u003Carticle class=\"prose max-w-none\">{{ markdown }}\u003C/article>\n",[15,2458,2459],{"__ignoreMap":29},[33,2460,2461,2463,2465,2467,2469,2472,2474,2476],{"class":35,"line":36},[33,2462,122],{"class":82},[33,2464,2182],{"class":332},[33,2466,1085],{"class":39},[33,2468,128],{"class":82},[33,2470,2471],{"class":43},"\"prose max-w-none\"",[33,2473,2192],{"class":82},[33,2475,2182],{"class":332},[33,2477,134],{"class":82},[11,2479,2480],{},[262,2481,2482],{},"取消 prose 样式",[11,2484,2485,2486,2489,2490,2492],{},"使用 ",[15,2487,2488],{},"not-prose"," 标记一些元素，不使用 ",[15,2491,2332],{}," 的样式",[24,2494,2496],{"className":2172,"code":2495,"language":737,"meta":29,"style":29},"\u003Carticle class=\"prose\">\n  \u003Ch1>My Heading\u003C/h1>\n  \u003Cp>...\u003C/p>\n\n  \u003Cdiv class=\"not-prose\">\n    \u003C!-- Some example or demo that needs to be prose-free -->\n  \u003C/div>\n\n  \u003Cp>...\u003C/p>\n  \u003C!-- ... -->\n\u003C/article>\n",[15,2497,2498,2513,2527,2540,2544,2559,2564,2572,2576,2588,2593],{"__ignoreMap":29},[33,2499,2500,2502,2504,2506,2508,2511],{"class":35,"line":36},[33,2501,122],{"class":82},[33,2503,2182],{"class":332},[33,2505,1085],{"class":39},[33,2507,128],{"class":82},[33,2509,2510],{"class":43},"\"prose\"",[33,2512,134],{"class":82},[33,2514,2515,2517,2520,2523,2525],{"class":35,"line":86},[33,2516,216],{"class":82},[33,2518,2519],{"class":332},"h1",[33,2521,2522],{"class":82},">My Heading\u003C/",[33,2524,2519],{"class":332},[33,2526,134],{"class":82},[33,2528,2529,2531,2533,2536,2538],{"class":35,"line":98},[33,2530,216],{"class":82},[33,2532,11],{"class":332},[33,2534,2535],{"class":82},">...\u003C/",[33,2537,11],{"class":332},[33,2539,134],{"class":82},[33,2541,2542],{"class":35,"line":161},[33,2543,165],{"emptyLinePlaceholder":164},[33,2545,2546,2548,2550,2552,2554,2557],{"class":35,"line":168},[33,2547,216],{"class":82},[33,2549,1082],{"class":332},[33,2551,1085],{"class":39},[33,2553,128],{"class":82},[33,2555,2556],{"class":43},"\"not-prose\"",[33,2558,134],{"class":82},[33,2560,2561],{"class":35,"line":174},[33,2562,2563],{"class":553},"    \u003C!-- Some example or demo that needs to be prose-free -->\n",[33,2565,2566,2568,2570],{"class":35,"line":179},[33,2567,862],{"class":82},[33,2569,1082],{"class":332},[33,2571,134],{"class":82},[33,2573,2574],{"class":35,"line":185},[33,2575,165],{"emptyLinePlaceholder":164},[33,2577,2578,2580,2582,2584,2586],{"class":35,"line":190},[33,2579,216],{"class":82},[33,2581,11],{"class":332},[33,2583,2535],{"class":82},[33,2585,11],{"class":332},[33,2587,134],{"class":82},[33,2589,2590],{"class":35,"line":198},[33,2591,2592],{"class":553},"  \u003C!-- ... -->\n",[33,2594,2595,2597,2599],{"class":35,"line":203},[33,2596,243],{"class":82},[33,2598,2182],{"class":332},[33,2600,134],{"class":82},[11,2602,2603,2604,2606,2607],{},"但无法继续在 ",[15,2605,2488],{}," 里再嵌套 ",[15,2608,2332],{},[11,2610,2611],{},[262,2612,2613],{},"自定义颜色主题",[11,2615,2616,2617,2620],{},"可以在 ",[15,2618,2619],{},"tailwindcss.config.js"," 中设置自定义的颜色主题",[24,2622,2624],{"className":2233,"code":2623,"language":2235,"meta":29,"style":29},"/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  theme: {\n    extend: {\n      typography: ({ theme }) => ({\n        pink: {\n          css: {\n            '--tw-prose-body': theme('colors.pink[800]'),\n            '--tw-prose-headings': theme('colors.pink[900]'),\n            '--tw-prose-lead': theme('colors.pink[700]'),\n            '--tw-prose-links': theme('colors.pink[900]'),\n            '--tw-prose-bold': theme('colors.pink[900]'),\n            '--tw-prose-counters': theme('colors.pink[600]'),\n            '--tw-prose-bullets': theme('colors.pink[400]'),\n            '--tw-prose-hr': theme('colors.pink[300]'),\n            '--tw-prose-quotes': theme('colors.pink[900]'),\n            '--tw-prose-quote-borders': theme('colors.pink[300]'),\n            '--tw-prose-captions': theme('colors.pink[700]'),\n            '--tw-prose-code': theme('colors.pink[900]'),\n            '--tw-prose-pre-code': theme('colors.pink[100]'),\n            '--tw-prose-pre-bg': theme('colors.pink[900]'),\n            '--tw-prose-th-borders': theme('colors.pink[300]'),\n            '--tw-prose-td-borders': theme('colors.pink[200]'),\n            '--tw-prose-invert-body': theme('colors.pink[200]'),\n            '--tw-prose-invert-headings': theme('colors.white'),\n            '--tw-prose-invert-lead': theme('colors.pink[300]'),\n            '--tw-prose-invert-links': theme('colors.white'),\n            '--tw-prose-invert-bold': theme('colors.white'),\n            '--tw-prose-invert-counters': theme('colors.pink[400]'),\n            '--tw-prose-invert-bullets': theme('colors.pink[600]'),\n            '--tw-prose-invert-hr': theme('colors.pink[700]'),\n            '--tw-prose-invert-quotes': theme('colors.pink[100]'),\n            '--tw-prose-invert-quote-borders': theme('colors.pink[700]'),\n            '--tw-prose-invert-captions': theme('colors.pink[400]'),\n            '--tw-prose-invert-code': theme('colors.white'),\n            '--tw-prose-invert-pre-code': theme('colors.pink[300]'),\n            '--tw-prose-invert-pre-bg': 'rgb(0 0 0 / 50%)',\n            '--tw-prose-invert-th-borders': theme('colors.pink[600]'),\n            '--tw-prose-invert-td-borders': theme('colors.pink[700]'),\n          },\n        },\n      }),\n    },\n  },\n  plugins: [\n    require('@tailwindcss/typography'),\n    // ...\n  ],\n}\n",[15,2625,2626,2636,2648,2652,2657,2676,2681,2686,2702,2718,2734,2749,2764,2780,2796,2812,2827,2842,2857,2872,2888,2903,2918,2934,2949,2965,2980,2995,3010,3025,3040,3055,3070,3086,3102,3118,3134,3147,3163,3179,3185,3191,3197,3202,3207,3212,3223,3228,3233],{"__ignoreMap":29},[33,2627,2628,2630,2632,2634],{"class":35,"line":36},[33,2629,2242],{"class":553},[33,2631,2245],{"class":72},[33,2633,2248],{"class":39},[33,2635,2251],{"class":553},[33,2637,2638,2640,2642,2644,2646],{"class":35,"line":86},[33,2639,2256],{"class":142},[33,2641,2259],{"class":82},[33,2643,2262],{"class":142},[33,2645,146],{"class":72},[33,2647,2267],{"class":82},[33,2649,2650],{"class":35,"line":98},[33,2651,2272],{"class":82},[33,2653,2654],{"class":35,"line":161},[33,2655,2656],{"class":82},"    extend: {\n",[33,2658,2659,2662,2665,2668,2671,2673],{"class":35,"line":168},[33,2660,2661],{"class":39},"      typography",[33,2663,2664],{"class":82},": ({ ",[33,2666,2667],{"class":369},"theme",[33,2669,2670],{"class":82}," }) ",[33,2672,399],{"class":72},[33,2674,2675],{"class":82}," ({\n",[33,2677,2678],{"class":35,"line":174},[33,2679,2680],{"class":82},"        pink: {\n",[33,2682,2683],{"class":35,"line":179},[33,2684,2685],{"class":82},"          css: {\n",[33,2687,2688,2691,2693,2695,2697,2700],{"class":35,"line":185},[33,2689,2690],{"class":43},"            '--tw-prose-body'",[33,2692,373],{"class":82},[33,2694,2667],{"class":39},[33,2696,390],{"class":82},[33,2698,2699],{"class":43},"'colors.pink[800]'",[33,2701,2299],{"class":82},[33,2703,2704,2707,2709,2711,2713,2716],{"class":35,"line":190},[33,2705,2706],{"class":43},"            '--tw-prose-headings'",[33,2708,373],{"class":82},[33,2710,2667],{"class":39},[33,2712,390],{"class":82},[33,2714,2715],{"class":43},"'colors.pink[900]'",[33,2717,2299],{"class":82},[33,2719,2720,2723,2725,2727,2729,2732],{"class":35,"line":198},[33,2721,2722],{"class":43},"            '--tw-prose-lead'",[33,2724,373],{"class":82},[33,2726,2667],{"class":39},[33,2728,390],{"class":82},[33,2730,2731],{"class":43},"'colors.pink[700]'",[33,2733,2299],{"class":82},[33,2735,2736,2739,2741,2743,2745,2747],{"class":35,"line":203},[33,2737,2738],{"class":43},"            '--tw-prose-links'",[33,2740,373],{"class":82},[33,2742,2667],{"class":39},[33,2744,390],{"class":82},[33,2746,2715],{"class":43},[33,2748,2299],{"class":82},[33,2750,2751,2754,2756,2758,2760,2762],{"class":35,"line":213},[33,2752,2753],{"class":43},"            '--tw-prose-bold'",[33,2755,373],{"class":82},[33,2757,2667],{"class":39},[33,2759,390],{"class":82},[33,2761,2715],{"class":43},[33,2763,2299],{"class":82},[33,2765,2766,2769,2771,2773,2775,2778],{"class":35,"line":240},[33,2767,2768],{"class":43},"            '--tw-prose-counters'",[33,2770,373],{"class":82},[33,2772,2667],{"class":39},[33,2774,390],{"class":82},[33,2776,2777],{"class":43},"'colors.pink[600]'",[33,2779,2299],{"class":82},[33,2781,2782,2785,2787,2789,2791,2794],{"class":35,"line":582},[33,2783,2784],{"class":43},"            '--tw-prose-bullets'",[33,2786,373],{"class":82},[33,2788,2667],{"class":39},[33,2790,390],{"class":82},[33,2792,2793],{"class":43},"'colors.pink[400]'",[33,2795,2299],{"class":82},[33,2797,2798,2801,2803,2805,2807,2810],{"class":35,"line":588},[33,2799,2800],{"class":43},"            '--tw-prose-hr'",[33,2802,373],{"class":82},[33,2804,2667],{"class":39},[33,2806,390],{"class":82},[33,2808,2809],{"class":43},"'colors.pink[300]'",[33,2811,2299],{"class":82},[33,2813,2814,2817,2819,2821,2823,2825],{"class":35,"line":593},[33,2815,2816],{"class":43},"            '--tw-prose-quotes'",[33,2818,373],{"class":82},[33,2820,2667],{"class":39},[33,2822,390],{"class":82},[33,2824,2715],{"class":43},[33,2826,2299],{"class":82},[33,2828,2829,2832,2834,2836,2838,2840],{"class":35,"line":599},[33,2830,2831],{"class":43},"            '--tw-prose-quote-borders'",[33,2833,373],{"class":82},[33,2835,2667],{"class":39},[33,2837,390],{"class":82},[33,2839,2809],{"class":43},[33,2841,2299],{"class":82},[33,2843,2844,2847,2849,2851,2853,2855],{"class":35,"line":604},[33,2845,2846],{"class":43},"            '--tw-prose-captions'",[33,2848,373],{"class":82},[33,2850,2667],{"class":39},[33,2852,390],{"class":82},[33,2854,2731],{"class":43},[33,2856,2299],{"class":82},[33,2858,2859,2862,2864,2866,2868,2870],{"class":35,"line":609},[33,2860,2861],{"class":43},"            '--tw-prose-code'",[33,2863,373],{"class":82},[33,2865,2667],{"class":39},[33,2867,390],{"class":82},[33,2869,2715],{"class":43},[33,2871,2299],{"class":82},[33,2873,2874,2877,2879,2881,2883,2886],{"class":35,"line":615},[33,2875,2876],{"class":43},"            '--tw-prose-pre-code'",[33,2878,373],{"class":82},[33,2880,2667],{"class":39},[33,2882,390],{"class":82},[33,2884,2885],{"class":43},"'colors.pink[100]'",[33,2887,2299],{"class":82},[33,2889,2890,2893,2895,2897,2899,2901],{"class":35,"line":621},[33,2891,2892],{"class":43},"            '--tw-prose-pre-bg'",[33,2894,373],{"class":82},[33,2896,2667],{"class":39},[33,2898,390],{"class":82},[33,2900,2715],{"class":43},[33,2902,2299],{"class":82},[33,2904,2905,2908,2910,2912,2914,2916],{"class":35,"line":627},[33,2906,2907],{"class":43},"            '--tw-prose-th-borders'",[33,2909,373],{"class":82},[33,2911,2667],{"class":39},[33,2913,390],{"class":82},[33,2915,2809],{"class":43},[33,2917,2299],{"class":82},[33,2919,2920,2923,2925,2927,2929,2932],{"class":35,"line":632},[33,2921,2922],{"class":43},"            '--tw-prose-td-borders'",[33,2924,373],{"class":82},[33,2926,2667],{"class":39},[33,2928,390],{"class":82},[33,2930,2931],{"class":43},"'colors.pink[200]'",[33,2933,2299],{"class":82},[33,2935,2936,2939,2941,2943,2945,2947],{"class":35,"line":637},[33,2937,2938],{"class":43},"            '--tw-prose-invert-body'",[33,2940,373],{"class":82},[33,2942,2667],{"class":39},[33,2944,390],{"class":82},[33,2946,2931],{"class":43},[33,2948,2299],{"class":82},[33,2950,2951,2954,2956,2958,2960,2963],{"class":35,"line":652},[33,2952,2953],{"class":43},"            '--tw-prose-invert-headings'",[33,2955,373],{"class":82},[33,2957,2667],{"class":39},[33,2959,390],{"class":82},[33,2961,2962],{"class":43},"'colors.white'",[33,2964,2299],{"class":82},[33,2966,2967,2970,2972,2974,2976,2978],{"class":35,"line":658},[33,2968,2969],{"class":43},"            '--tw-prose-invert-lead'",[33,2971,373],{"class":82},[33,2973,2667],{"class":39},[33,2975,390],{"class":82},[33,2977,2809],{"class":43},[33,2979,2299],{"class":82},[33,2981,2982,2985,2987,2989,2991,2993],{"class":35,"line":671},[33,2983,2984],{"class":43},"            '--tw-prose-invert-links'",[33,2986,373],{"class":82},[33,2988,2667],{"class":39},[33,2990,390],{"class":82},[33,2992,2962],{"class":43},[33,2994,2299],{"class":82},[33,2996,2997,3000,3002,3004,3006,3008],{"class":35,"line":677},[33,2998,2999],{"class":43},"            '--tw-prose-invert-bold'",[33,3001,373],{"class":82},[33,3003,2667],{"class":39},[33,3005,390],{"class":82},[33,3007,2962],{"class":43},[33,3009,2299],{"class":82},[33,3011,3012,3015,3017,3019,3021,3023],{"class":35,"line":683},[33,3013,3014],{"class":43},"            '--tw-prose-invert-counters'",[33,3016,373],{"class":82},[33,3018,2667],{"class":39},[33,3020,390],{"class":82},[33,3022,2793],{"class":43},[33,3024,2299],{"class":82},[33,3026,3027,3030,3032,3034,3036,3038],{"class":35,"line":688},[33,3028,3029],{"class":43},"            '--tw-prose-invert-bullets'",[33,3031,373],{"class":82},[33,3033,2667],{"class":39},[33,3035,390],{"class":82},[33,3037,2777],{"class":43},[33,3039,2299],{"class":82},[33,3041,3042,3045,3047,3049,3051,3053],{"class":35,"line":694},[33,3043,3044],{"class":43},"            '--tw-prose-invert-hr'",[33,3046,373],{"class":82},[33,3048,2667],{"class":39},[33,3050,390],{"class":82},[33,3052,2731],{"class":43},[33,3054,2299],{"class":82},[33,3056,3057,3060,3062,3064,3066,3068],{"class":35,"line":700},[33,3058,3059],{"class":43},"            '--tw-prose-invert-quotes'",[33,3061,373],{"class":82},[33,3063,2667],{"class":39},[33,3065,390],{"class":82},[33,3067,2885],{"class":43},[33,3069,2299],{"class":82},[33,3071,3073,3076,3078,3080,3082,3084],{"class":35,"line":3072},33,[33,3074,3075],{"class":43},"            '--tw-prose-invert-quote-borders'",[33,3077,373],{"class":82},[33,3079,2667],{"class":39},[33,3081,390],{"class":82},[33,3083,2731],{"class":43},[33,3085,2299],{"class":82},[33,3087,3089,3092,3094,3096,3098,3100],{"class":35,"line":3088},34,[33,3090,3091],{"class":43},"            '--tw-prose-invert-captions'",[33,3093,373],{"class":82},[33,3095,2667],{"class":39},[33,3097,390],{"class":82},[33,3099,2793],{"class":43},[33,3101,2299],{"class":82},[33,3103,3105,3108,3110,3112,3114,3116],{"class":35,"line":3104},35,[33,3106,3107],{"class":43},"            '--tw-prose-invert-code'",[33,3109,373],{"class":82},[33,3111,2667],{"class":39},[33,3113,390],{"class":82},[33,3115,2962],{"class":43},[33,3117,2299],{"class":82},[33,3119,3121,3124,3126,3128,3130,3132],{"class":35,"line":3120},36,[33,3122,3123],{"class":43},"            '--tw-prose-invert-pre-code'",[33,3125,373],{"class":82},[33,3127,2667],{"class":39},[33,3129,390],{"class":82},[33,3131,2809],{"class":43},[33,3133,2299],{"class":82},[33,3135,3137,3140,3142,3145],{"class":35,"line":3136},37,[33,3138,3139],{"class":43},"            '--tw-prose-invert-pre-bg'",[33,3141,373],{"class":82},[33,3143,3144],{"class":43},"'rgb(0 0 0 / 50%)'",[33,3146,1630],{"class":82},[33,3148,3150,3153,3155,3157,3159,3161],{"class":35,"line":3149},38,[33,3151,3152],{"class":43},"            '--tw-prose-invert-th-borders'",[33,3154,373],{"class":82},[33,3156,2667],{"class":39},[33,3158,390],{"class":82},[33,3160,2777],{"class":43},[33,3162,2299],{"class":82},[33,3164,3166,3169,3171,3173,3175,3177],{"class":35,"line":3165},39,[33,3167,3168],{"class":43},"            '--tw-prose-invert-td-borders'",[33,3170,373],{"class":82},[33,3172,2667],{"class":39},[33,3174,390],{"class":82},[33,3176,2731],{"class":43},[33,3178,2299],{"class":82},[33,3180,3182],{"class":35,"line":3181},40,[33,3183,3184],{"class":82},"          },\n",[33,3186,3188],{"class":35,"line":3187},41,[33,3189,3190],{"class":82},"        },\n",[33,3192,3194],{"class":35,"line":3193},42,[33,3195,3196],{"class":82},"      }),\n",[33,3198,3200],{"class":35,"line":3199},43,[33,3201,564],{"class":82},[33,3203,3205],{"class":35,"line":3204},44,[33,3206,2142],{"class":82},[33,3208,3210],{"class":35,"line":3209},45,[33,3211,2286],{"class":82},[33,3213,3215,3217,3219,3221],{"class":35,"line":3214},46,[33,3216,2291],{"class":39},[33,3218,390],{"class":82},[33,3220,2296],{"class":43},[33,3222,2299],{"class":82},[33,3224,3226],{"class":35,"line":3225},47,[33,3227,2277],{"class":553},[33,3229,3231],{"class":35,"line":3230},48,[33,3232,2308],{"class":82},[33,3234,3236],{"class":35,"line":3235},49,[33,3237,2313],{"class":82},[11,3239,3240],{},"也可以使用自定义的色值",[24,3242,3244],{"className":2233,"code":3243,"language":2235,"meta":29,"style":29},"/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  theme: {\n    extend: {\n      typography: {\n        DEFAULT: {\n          css: {\n            color: '#333',\n            a: {\n              color: '#3182ce',\n              '&:hover': {\n                color: '#2c5282',\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n  plugins: [\n    require('@tailwindcss/typography'),\n    // ...\n  ],\n}\n",[15,3245,3246,3256,3268,3272,3276,3281,3286,3290,3300,3305,3315,3322,3332,3337,3342,3346,3350,3354,3358,3362,3366,3376,3380,3384],{"__ignoreMap":29},[33,3247,3248,3250,3252,3254],{"class":35,"line":36},[33,3249,2242],{"class":553},[33,3251,2245],{"class":72},[33,3253,2248],{"class":39},[33,3255,2251],{"class":553},[33,3257,3258,3260,3262,3264,3266],{"class":35,"line":86},[33,3259,2256],{"class":142},[33,3261,2259],{"class":82},[33,3263,2262],{"class":142},[33,3265,146],{"class":72},[33,3267,2267],{"class":82},[33,3269,3270],{"class":35,"line":98},[33,3271,2272],{"class":82},[33,3273,3274],{"class":35,"line":161},[33,3275,2656],{"class":82},[33,3277,3278],{"class":35,"line":168},[33,3279,3280],{"class":82},"      typography: {\n",[33,3282,3283],{"class":35,"line":174},[33,3284,3285],{"class":82},"        DEFAULT: {\n",[33,3287,3288],{"class":35,"line":179},[33,3289,2685],{"class":82},[33,3291,3292,3295,3298],{"class":35,"line":185},[33,3293,3294],{"class":82},"            color: ",[33,3296,3297],{"class":43},"'#333'",[33,3299,1630],{"class":82},[33,3301,3302],{"class":35,"line":190},[33,3303,3304],{"class":82},"            a: {\n",[33,3306,3307,3310,3313],{"class":35,"line":198},[33,3308,3309],{"class":82},"              color: ",[33,3311,3312],{"class":43},"'#3182ce'",[33,3314,1630],{"class":82},[33,3316,3317,3320],{"class":35,"line":203},[33,3318,3319],{"class":43},"              '&:hover'",[33,3321,2107],{"class":82},[33,3323,3324,3327,3330],{"class":35,"line":213},[33,3325,3326],{"class":82},"                color: ",[33,3328,3329],{"class":43},"'#2c5282'",[33,3331,1630],{"class":82},[33,3333,3334],{"class":35,"line":240},[33,3335,3336],{"class":82},"              },\n",[33,3338,3339],{"class":35,"line":582},[33,3340,3341],{"class":82},"            },\n",[33,3343,3344],{"class":35,"line":588},[33,3345,3184],{"class":82},[33,3347,3348],{"class":35,"line":593},[33,3349,3190],{"class":82},[33,3351,3352],{"class":35,"line":599},[33,3353,585],{"class":82},[33,3355,3356],{"class":35,"line":604},[33,3357,564],{"class":82},[33,3359,3360],{"class":35,"line":609},[33,3361,2142],{"class":82},[33,3363,3364],{"class":35,"line":615},[33,3365,2286],{"class":82},[33,3367,3368,3370,3372,3374],{"class":35,"line":621},[33,3369,2291],{"class":39},[33,3371,390],{"class":82},[33,3373,2296],{"class":43},[33,3375,2299],{"class":82},[33,3377,3378],{"class":35,"line":627},[33,3379,2277],{"class":553},[33,3381,3382],{"class":35,"line":632},[33,3383,2308],{"class":82},[33,3385,3386],{"class":35,"line":637},[33,3387,2313],{"class":82},[11,3389,3390],{},"不过不建议在这里配置颜色相关的，因为提供了通过 prose-xxx 的形式灵活控制样式时，在这里在写一遍自定义的样式会难以覆盖，可以在这里设置一些间距类的样式。",[11,3392,3393],{},"而颜色使用一个自定义的 class 去使用：",[24,3395,3399],{"className":3396,"code":3397,"language":3398,"meta":29,"style":29},"language-css shiki shiki-themes github-light",".mdc-page-prose {\n  @apply prose prose-zinc prose-pre:bg-gray-100 dark:prose-pre:bg-zinc-400 dark:text-zinc-200 dark:prose-strong:text-zinc-200 prose-code:bg-zinc-200 dark:prose-code:bg-zinc-200 prose-code:text-zinc-800 dark:prose-blockquote:text-zinc-300 w-full max-w-full\n}\n\n.mdc-prose {\n  @apply prose prose-zinc prose-pre:bg-gray-100 dark:prose-pre:bg-zinc-400 dark:text-zinc-200 dark:prose-strong:text-zinc-200 prose-code:bg-zinc-200 dark:prose-code:bg-zinc-200 prose-code:text-zinc-800 dark:prose-blockquote:text-zinc-300 w-full max-w-full\n}\n","css",[15,3400,3401,3408,3454,3458,3462,3469,3503],{"__ignoreMap":29},[33,3402,3403,3406],{"class":35,"line":36},[33,3404,3405],{"class":39},".mdc-page-prose",[33,3407,2267],{"class":82},[33,3409,3410,3413,3416,3419,3422,3425,3428,3431,3434,3436,3439,3441,3444,3446,3449,3451],{"class":35,"line":86},[33,3411,3412],{"class":82},"  @",[33,3414,3415],{"class":142},"apply",[33,3417,3418],{"class":142}," prose",[33,3420,3421],{"class":142}," prose-zinc",[33,3423,3424],{"class":142}," prose-pre",[33,3426,3427],{"class":82},":bg-gray-100 ",[33,3429,3430],{"class":142},"dark",[33,3432,3433],{"class":82},":prose-pre:bg-zinc-400 ",[33,3435,3430],{"class":142},[33,3437,3438],{"class":82},":text-zinc-200 ",[33,3440,3430],{"class":142},[33,3442,3443],{"class":82},":prose-strong:text-zinc-200 prose-code:bg-zinc-200 ",[33,3445,3430],{"class":142},[33,3447,3448],{"class":82},":prose-code:bg-zinc-200 prose-code:text-zinc-800 ",[33,3450,3430],{"class":142},[33,3452,3453],{"class":82},":prose-blockquote:text-zinc-300 w-full max-w-full\n",[33,3455,3456],{"class":35,"line":98},[33,3457,2313],{"class":82},[33,3459,3460],{"class":35,"line":161},[33,3461,165],{"emptyLinePlaceholder":164},[33,3463,3464,3467],{"class":35,"line":168},[33,3465,3466],{"class":39},".mdc-prose",[33,3468,2267],{"class":82},[33,3470,3471,3473,3475,3477,3479,3481,3483,3485,3487,3489,3491,3493,3495,3497,3499,3501],{"class":35,"line":174},[33,3472,3412],{"class":82},[33,3474,3415],{"class":142},[33,3476,3418],{"class":142},[33,3478,3421],{"class":142},[33,3480,3424],{"class":142},[33,3482,3427],{"class":82},[33,3484,3430],{"class":142},[33,3486,3433],{"class":82},[33,3488,3430],{"class":142},[33,3490,3438],{"class":82},[33,3492,3430],{"class":142},[33,3494,3443],{"class":82},[33,3496,3430],{"class":142},[33,3498,3448],{"class":82},[33,3500,3430],{"class":142},[33,3502,3453],{"class":82},[33,3504,3505],{"class":35,"line":179},[33,3506,2313],{"class":82},[11,3508,3509,3510,3512,3513,3516,3517,3519],{},"这样的话，在一个项目中，出现两组或多组不同的 ",[15,3511,2332],{}," 样式，就比较方便使用 ",[15,3514,3515],{},"class"," 控制了，毕竟 ",[15,3518,2619],{}," 只有一个，尽量设置一些通用的不常变化的属性。",[20,3521,3522],{"id":3522},"结语",[11,3524,3525,3526,3529,3530,3533,3534,3536],{},"以上就是 ",[15,3527,3528],{},"nuxtjs/mdc"," 的大部分使用场景了，通常这个库会在使用 ",[15,3531,3532],{},"Nuxt Content"," 时使用，但也可以只使用它来支持多种来源，片段化的 ",[15,3535,803],{}," 内容渲染。",[11,3538,3539,3540,3543,3544,3547,3548,277],{},"但是要注意，虽然支持自定义组件，但我还是不建议你的 ",[15,3541,3542],{},"md 文章","里不要包含太多的",[15,3545,3546],{},"魔法","，",[262,3549,3550],{},"在自己定制的平台上是魔法，在其他不支持的软件和 web 里就是麻瓜",[11,3552,3553,3554,3557],{},"但是自定义组件很适合用来",[262,3555,3556],{},"支持自己的自建平台","，这也是我为什么会把 mdc 这个库拿出来单独使用。",[11,3559,3560,3561,3563,3564,3569],{},"使用时注意文章开头的 ",[15,3562,713],{}," 版本号，表示此文章的生效范围，后续更新只能在我的",[478,3565,3568],{"href":3566,"rel":3567},"https://blog.zzao.club",[482],"博客站","同步了",[11,3571,3572,3573,3575,3576,3579,3580,3582],{},"如果你也是 ",[15,3574,2398],{}," 的使用者，或是 ",[15,3577,3578],{},"Vue"," 使用者对 ",[15,3581,2398],{}," 感兴趣，欢迎在文末或博客站首页添加我的微信，一起交流，知无不言😎",[1702,3584,3585],{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sB1qb, html code.shiki .sB1qb{--shiki-default:#B31D28;--shiki-default-font-style:italic}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":29,"searchDepth":86,"depth":86,"links":3587},[3588,3589,3590,3591,3592,3593,3594],{"id":22,"depth":86,"text":22},{"id":104,"depth":86,"text":104},{"id":895,"depth":86,"text":896},{"id":964,"depth":86,"text":964},{"id":1824,"depth":86,"text":1824},{"id":2148,"depth":86,"text":2149},{"id":3522,"depth":86,"text":3522},"2025-01-13T00:00:00.000Z","这是一份持续更新的@nuxtjs/mdc的使用说明书，扩充官方文档的同时，更正一些错误信息（因为官方更的不及时）。同时也会涵盖解析 Makdown 语法的使用说明。","2025-02-12T00:00:00.000Z",{},"/post/nuxt/nuxtjs-mdc-docs","---\ntitle: 打造 Markdown 的绝美排版：@nuxtjs-mdc 使用指南\ndate: 2025-01-13\nlastmod: 2025-02-12\ntags: [\"Nuxt\"]\nversions: [\"@nuxtjs/mdc@0.12.1\"]\nshowTitle: 打造 Markdown 的绝美排版：@nuxtjs-mdc 使用指南\n---\n这是一份持续更新的@nuxtjs/mdc的使用说明书，扩充官方文档的同时，更正一些错误信息（因为官方更的不及时）。同时也会涵盖解析 `Makdown` 语法的使用说明。\n\n## 安装\n\n```shell\nnpx nuxi@latest module add mdc\n```\n\n然后 @nuxtjs/mdc 就会被自动添加到 `nuxt.config.ts` 的 modules 中\n\n```typescript\nexport default defineNuxtConfig({\n  modules: ['@nuxtjs/mdc']\n})\n```\n## 组件\n\nMDC 中提供了三个组件来渲染 markdown 内容\n\n`MDC`\n\n```typescript\n\u003Cscript setup lang=\"ts\">\nconst md = \"\n\t# h1 标题\n\n\t`代码快`\n\n\"\n\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CMDC :value=\"md\" tag=\"article\" />\n\u003C/template>\n\n```\n\n`MDC` 组件直接接受一个 `value` prop，传入 `markdown` 的**原始内容**即可，`tag` 属性可以决定渲染后的内容被什么标签包裹，类似于 `vue-router` 的 `RouterLink`。\n\n`MDCRenderer`\n\n这个组件依赖于 `parseMarkdown` 函数提供的数据\n\n此函数需要从 `@nuxtjs/mdc/runtime` 导入\n\n```typescript\nimport { parseMarkdown } from '@nuxtjs/mdc/runtime'\n```\n\n使用时可以像这样\n\n```vue\n\u003Cscript setup lang=\"ts\">\nimport { parseMarkdown } from '@nuxtjs/mdc/runtime'\n\nconst { data: ast } = await useAsyncData('markdown', () => parseMarkdown('::alert\\nMissing markdown input\\n::'))\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CMDCRenderer :body=\"ast.body\" :data=\"ast.data\" />\n\u003C/template>\n```\n\n它还有第二个参数 [MDCParseOptions](https://github.com/nuxt-modules/mdc/blob/main/src/runtime/types/parser.ts)，可以用来控制解析起的行为。\n\n![](https://img.zzao.club/picgo/Pasted%20image%2020250111113759.png)\n\n也可以在 nuxt.config.ts 中配置\n\n```typescript\nimport { defineNuxtConfig } from 'nuxt/config'\n\nexport default defineNuxtConfig({\n  modules: ['@nuxtjs/mdc'],\n  mdc: {\n    remarkPlugins: {\n      plugins: {\n        // Register/Configure remark plugin to extend the parser\n      }\n    },\n    rehypePlugins: {\n      options: {\n        // Configure rehype options to extend the parser\n      },\n      plugins: {\n        // Register/Configure rehype plugin to extend the parser\n      }\n    },\n    headings: {\n      anchorLinks: {\n        // Enable/Disable heading anchor links. { h1: true, h2: false }\n      }\n    },\n    highlight: false, // Control syntax highlighting\n    components: {\n      prose: false, // Add predefined map to render Prose Components instead of HTML tags, like p, ul, code\n      map: {\n        // This map will be used in `\u003CMDCRenderer>` to control rendered components\n      }\n    }\n  }\n})\n```\n\n**点进去可以看到，这地址都 404 了，文件都删了，这就是为什么我要写这篇文章....**\n\n事实上，`mdc` 底层用到的很多插件，都是和 `unified` 的生态是一致的（都是基于`remarkPlugins`、`rehypePlugins`）。\n\n但是 `mdc` 搞的有点太封闭。没导出几个有用的Api，其实完全可以把关于 `markdown`、`html`、以及中间的 `hastTree` 都开放出来。\n\n因为 `markdown` 相关的内容，虽然没有官方的标准，但是因为使用范围很广，早就成了事实意义上的标准。有用的人自然会用了，不用的压根都不会看一眼。\n\n实际使用中，这种方式还没有找到使用场景（在内容渲染中），不管是自己本地的数据，还是从第三方 API获取到数据，直接扔给 `MDC` 组件是最方便的，在数据中存储原始数据（`rawbody`），在不同平台展示时自身处理渲染逻辑。\n\nPS：但要做 RSS 订阅就不得不把生成后的 `HTML` 放在 `xml` 中 ，这就是我上边为啥吐槽它太封闭。\n\n`MDCSlot`\n\n这个组件是为了替代 Vue 中的 `slot` 组件，针对 `MDC` 做了特殊处理，使用这个组件时你可以删除其包裹元素`p`，（使用 `slot` 时会默认渲染一个 `p` 标签包裹文字内容）\n\n`demo.md`\n\n```md\nddddsadadasdasd\n```\n\n`ProseP.vue`\n\n```vue\n\u003Ctemplate>\n  \u003Cp>\n    \u003C!-- MDCSlot will only render the actual text without the wrapping \u003Cp> -->\n    \u003CMDCSlot unwrap=\"p\" />\n  \u003C/p>\n\u003C/template>\n\n```\n\n当你输入两段纯文本，并且中间有一段空行时，这两段文本会分别被 p 标签包裹，做到换行的效果。\n\n而如果用上述的 `ProseP.vue` 覆盖后，纯文本将不再被 `p` 标签包裹，而是变成了 `span`，也就是你在写 md 时，哪怕已经换了行，渲染后的内容也是连贯的排列在一起的。\n\n那 ProseComponent 是什么呢\n\n## Prose Component\n\n`MDC` 渲染 `markdown` 内容时，使用了一套组件来渲染对应的 `markdown` 语法\n\n![](https://img.zzao.club/picgo/CleanShot%202025-01-11%20at%2011.28.56.png)\n\n同样的也支持你覆盖这些组件\n\n如果你使用 `nuxt3.15.1` 并且开启了    `compatibilityVersion: 4`，那你的 `components` 路径应该是在 `app/components` \n\n在此路径下新建目录 `mdc` ，然后创建一个同名的 `vue` 文件：`ProseA.vue` \n\n![](https://img.zzao.club/picgo/Pasted%20image%2020250111114806.png)\n\n我改写了其样式，并且把跳转默认为打开新标签页\n\n![](https://img.zzao.club/picgo/Pasted%20image%2020250111114847.png)\n\n可以看到如上渲染内容\n\n## 自定义组件\n\n`MDC` 还支持在 `markdown` 中写 `vue` 组件，语法是这样的\n\n`demo.md`\n\n```md\n::component-name\nThis is an vue component\n::\n```\n\n对应 `app/components/mdc/ComponentName.vue`\n\n如果你正在搭配 Nuxt Content 使用，则对应目录为 `app/components/content/ComponentName.vue`\n\n**再来个更实际的例子**\n\nmd 内容为：\n```md\n下面是一个 CustomTag 组件\n\n::custom-tag\n内部内容演示\n::\n\n组件位于`app/components/mdc/CustomTag.vue`\n```\n\n`CustomTag.vue` 内容为：\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv class=\"text-center my-10\">\n    \u003Cdiv\n      class=\"text-black px-3 py-2 text-lg font-bold\">\n      \u003Cslot/>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\n\n\u003C/script>\n```\n\n渲染后的结果为：\n![](https://img.zzao.club/picgo/Pasted%20image%2020250111185601.png)\n\n这种组件被称为 `Block Components` ，和 `display: block` 的意思相同，是个块级组件，单独占一行\n\n既然是Vue组件，也给它传 props\n\n```md\n::custom-tag{type=\"warning\"}\n内部内容演示\n::\n```\n\n再把组件改一下\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv class=\"text-center my-10\">\n    \u003Cdiv\n      class=\"text-black px-3 py-2 text-lg font-bold\" :class=\"{ 'bg-yellow-200': props.type === 'warning', 'bg-blue-200': props.type === 'info', 'bg-green-200': props.type === 'success', 'bg-red-200': props.type === 'error' }\">\n      \u003Cslot/>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{\n  type?: 'warning’ | ‘info’ | ‘success’ | ‘error’'\n}>()\n\u003C/script>\n```\n`\n看下渲染的内容：\n\n![](https://img.zzao.club/picgo/Pasted%20image%2020250111185907.png)\n\n也可以直接传 style\n\n```md\n::custom-tag{type=\"warning\" style=\"margin-top:100px;\"} \n内部内容演示 \n::\n```\n\n可以看到有了一个很大的间距\n\n![](https://img.zzao.club/picgo/Pasted%20image%2020250111190522.png)\n\n还支持使用 YAML method 的方式传入\n\n```md\n::custom-tag{type=\"warning\" style=\"margin-top:100px;\"} \n---\ndesc: \"我是描述内容\"\n---\n::\n```\n\n把组件改为\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv class=\"text-center my-10\">\n    \u003Cdiv\n      class=\"text-black px-3 py-2 text-lg font-bold\" :class=\"{ 'bg-yellow-200': props.type === 'warning', 'bg-blue-200': props.type === 'info', 'bg-green-200': props.type === 'success', 'bg-red-200': props.type === 'error' }\">\n      \u003Cdiv class=\"title\">\n        {{ props.type }}\n      \u003C/div>\n\n      \u003Cdiv class=\"desc text-red-600\">\n        {{ desc }}\n      \u003C/div>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{\n  type?: 'warning' | 'info' | 'success' | 'error',\n  desc?: string\n}>()\n\u003C/script>\n```\n\n渲染后：\n\n![](https://img.zzao.club/picgo/Pasted%20image%2020250111191131.png)\n\n不过这种方式，**不能和 slot 混用**，渲染出来 slot 会把几个 props 都覆盖。\n\n实际使用时，**不应该对一个内容写如此复杂的组件**。\n\n换句话说，Vue 组件应该足够完善， 让你在 `markdown` 中写足够少的信息，只传入必要的数据即可得到完美的展示才对。\n\n上面的 `Props` 是我们自定义的组件提前写好的 `Props` ，而内置的 Prose Components 也是一套 Vue 组件而已。\n\n所以除了在 `app/components/mdc/` 下创建一个同名的 `Prose Component` 覆盖原有组件，也可以直接给原组件传一些 `style`，改变它的样式。\n\n```md\nAttributes work on:\n\n- ![favicon](/favicon.ico){style=\"display: inline; margin: 0;\"} image,\n- [link](#attributes){style=\"background-color: pink;\"}, `code`{style=\"color: cyan;\"},\n- _italic_{style=\"background-color: yellow; color:black;\"} and **bold**{style=\"background-color: lightgreen;\"} texts.\n\n```\n\n除了使用一个 Vue 组件并给他传 Props，设置 style\n\n还能使用 `:ComponentName`  的语法直接使用一个写好的组件，比如这样\n\n```md\n# Title\n\n:banner\n```\n\n`Banner.vue`\n\n```vue\n\u003Ctemplate>\n  \u003Caside>\n    This component does not have any children.\n  \u003C/aside>\n\u003C/template>\n```\n\n这在自己定制的平台上使用时，会很有用。 但同样的，如果你使用其他软件或 API 来获取 md，要考虑一下语法过多导致的各平台不兼容问题。\n\nPS: 这种md里写属性传值的方式并不是 `mdc` 的原创，而是 `unified` （remark/rehype）插件相关的生态，都是这样写的。\n## 绑定数据\n\n贴两个官方的例子，很好理解\n\n第一种是在 Markdown 的 YAML 中定义：\n\n```md\n---\ntitle: 'Title of the page'\ndescription: 'meta description of the page'\ncustomVariable: 'Custom Value'\n---\n\n# The Title is {{ $doc.title }} and customVariable is {{ $doc.customVariable || 'defaultValue' }}\n\n```\n\n这个用法很有局限，因为你用来写 md 文章的软件大概率不支持这个语法，或者你要同步到其他平台的时候其他平台也不会支持这个语法。\n\n但是如果你的用途很单一，说不定会比较有用\n\n第二种是定义在 Vue 组件中\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003CContentRenderer :value=\"data\" :data=\"mdcVars\"/>\n    \u003Cbutton type=\"button\" v-on:click=\"mdcVars.name = 'Hugo'\">Change name\u003C/button>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData(() => queryCollection('content').path('/test').first());\nconst mdcVars = ref({ name: 'Maxime'});\n\u003C/script>\n```\n\nmd 中\n\n```md\n# Hello {{ $doc.name || 'World' }}\n```\n\n还是那种话，定制的越多，越不可控。\n\n文章内容还是要以高质量的文字为准，自定义组件更多的是作为锦上添花，是离不开一个封闭的平台的。\n\n----\n\n官方还给出了一种自定义组件的方式，就是在 `nuxt.config.ts` 中配置 `prose: false`，关闭 Prose Components 的渲染方式，自定义一个 map 指定组件\n\n```typescript\nmdc: {\n    // components: {\n    //   prose: false,\n      // map: {\n      //   'a': 'MemoProseA'\n      // }\n    // }\n  },\n```\n\n但我觉得这种方式和直接在 mdc 目录在覆盖掉原组件的区别很小，这种方式可以做到只支持部分 md 语法的渲染，比如你只写一个 a ，那其他内容就是纯文本，只有 a 标签是通过自定义组件渲染出来的，不清楚什么场景下才会有这种选择～\n\n## tailwind CSS 主题\n\nProse Components 支持使用 [tailwindcss-typography](https://github.com/tailwindlabs/tailwindcss-typography) 覆盖 html 排版\n\n这是我觉得比较实用的样式修改方式，因为 tailwindcss 足够通用，并且在全局的固定位置修改样式，便于管理\n\nTailwind CSS Typography 提供了一组 prose class，可以给默认的 html 元素附加排版，➡️点击查看[演示](https://play.tailwindcss.com/uj1vGACRJA?layout=preview)\n\n```html\n\u003Carticle class=\"prose lg:prose-xl\">{{ markdown }}\u003C/article>\n```\n\n**安装插件**\n\n```shell\nnpm install -D @tailwindcss/typography\n```\n\n**新建或添加**到 `tailwind.config.js` 中\n\n```js\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  theme: {\n    // ...\n  },\n  plugins: [\n    require('@tailwindcss/typography'),\n    // ...\n  ],\n}\n```\n\n**修改灰度**\n\n```\nprose prose-gray(默认) prose-slate prose-zinc prose-neutral prose-stone\n```\n\n不管使用哪个，都要带有 `prose` 这个基类\n\n**文字整体尺寸**\n\n```\nprose prose-sm (14px) prose-base (默认16px) prose-lg (18px) prose-xl (20px) prose-2xl (24px)\n```\n\n和灰度一样，也要带有 `prose` 这个基类，实际使用下来，还是 `prose-base` 用的最多，可以在自己发文发帖的多个平台尝试不同字号\n\n**适配深色模式**\n\n上面的几个调整灰度的主题，都有默认的深色模式版本，可以使用 prose-invert 来触发\n\n```html\n\u003Carticle class=\"prose dark:prose-invert\">{{ markdown }}\u003C/article>\n```\n\n如果你使用了自定义组件，则需要自己使用 `dark:` 修饰符适配一下深色模式\n\n`Nuxt` 中使用 `@nuxtjs/color-mode` 来控制颜色模式\n\n**精细化控制样式**\n\n除了全局设置默认的样式，也可以通过 `prose-xxx` 来控制目标标签的样式\n\n![](https://img.zzao.club/picgo/Pasted%20image%2020250112101943.png)\n\n像这样：\n\n```html\n\u003Carticle class=\"prose prose-a:text-blue-600 hover:prose-a:text-blue-500\">{{ markdown }}\u003C/article>\n```\n\n另外，每个修饰符都为了保证内容的可读性，设置了最大宽度。 如果你希望内容能够填充其容器的宽度，可以使用 `max-w-none`\n\n```html\n\u003Carticle class=\"prose max-w-none\">{{ markdown }}\u003C/article>\n```\n\n**取消 prose 样式**\n\n使用 `not-prose` 标记一些元素，不使用 `prose` 的样式\n\n```html\n\u003Carticle class=\"prose\">\n  \u003Ch1>My Heading\u003C/h1>\n  \u003Cp>...\u003C/p>\n\n  \u003Cdiv class=\"not-prose\">\n    \u003C!-- Some example or demo that needs to be prose-free -->\n  \u003C/div>\n\n  \u003Cp>...\u003C/p>\n  \u003C!-- ... -->\n\u003C/article>\n```\n\n但无法继续在 `not-prose` 里再嵌套 `prose`\n\n**自定义颜色主题**\n\n可以在 `tailwindcss.config.js` 中设置自定义的颜色主题\n\n```js\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  theme: {\n    extend: {\n      typography: ({ theme }) => ({\n        pink: {\n          css: {\n            '--tw-prose-body': theme('colors.pink[800]'),\n            '--tw-prose-headings': theme('colors.pink[900]'),\n            '--tw-prose-lead': theme('colors.pink[700]'),\n            '--tw-prose-links': theme('colors.pink[900]'),\n            '--tw-prose-bold': theme('colors.pink[900]'),\n            '--tw-prose-counters': theme('colors.pink[600]'),\n            '--tw-prose-bullets': theme('colors.pink[400]'),\n            '--tw-prose-hr': theme('colors.pink[300]'),\n            '--tw-prose-quotes': theme('colors.pink[900]'),\n            '--tw-prose-quote-borders': theme('colors.pink[300]'),\n            '--tw-prose-captions': theme('colors.pink[700]'),\n            '--tw-prose-code': theme('colors.pink[900]'),\n            '--tw-prose-pre-code': theme('colors.pink[100]'),\n            '--tw-prose-pre-bg': theme('colors.pink[900]'),\n            '--tw-prose-th-borders': theme('colors.pink[300]'),\n            '--tw-prose-td-borders': theme('colors.pink[200]'),\n            '--tw-prose-invert-body': theme('colors.pink[200]'),\n            '--tw-prose-invert-headings': theme('colors.white'),\n            '--tw-prose-invert-lead': theme('colors.pink[300]'),\n            '--tw-prose-invert-links': theme('colors.white'),\n            '--tw-prose-invert-bold': theme('colors.white'),\n            '--tw-prose-invert-counters': theme('colors.pink[400]'),\n            '--tw-prose-invert-bullets': theme('colors.pink[600]'),\n            '--tw-prose-invert-hr': theme('colors.pink[700]'),\n            '--tw-prose-invert-quotes': theme('colors.pink[100]'),\n            '--tw-prose-invert-quote-borders': theme('colors.pink[700]'),\n            '--tw-prose-invert-captions': theme('colors.pink[400]'),\n            '--tw-prose-invert-code': theme('colors.white'),\n            '--tw-prose-invert-pre-code': theme('colors.pink[300]'),\n            '--tw-prose-invert-pre-bg': 'rgb(0 0 0 / 50%)',\n            '--tw-prose-invert-th-borders': theme('colors.pink[600]'),\n            '--tw-prose-invert-td-borders': theme('colors.pink[700]'),\n          },\n        },\n      }),\n    },\n  },\n  plugins: [\n    require('@tailwindcss/typography'),\n    // ...\n  ],\n}\n```\n\n也可以使用自定义的色值\n\n```js\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  theme: {\n    extend: {\n      typography: {\n        DEFAULT: {\n          css: {\n            color: '#333',\n            a: {\n              color: '#3182ce',\n              '&:hover': {\n                color: '#2c5282',\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n  plugins: [\n    require('@tailwindcss/typography'),\n    // ...\n  ],\n}\n```\n\n不过不建议在这里配置颜色相关的，因为提供了通过 prose-xxx 的形式灵活控制样式时，在这里在写一遍自定义的样式会难以覆盖，可以在这里设置一些间距类的样式。\n\n而颜色使用一个自定义的 class 去使用：\n\n```css\n.mdc-page-prose {\n  @apply prose prose-zinc prose-pre:bg-gray-100 dark:prose-pre:bg-zinc-400 dark:text-zinc-200 dark:prose-strong:text-zinc-200 prose-code:bg-zinc-200 dark:prose-code:bg-zinc-200 prose-code:text-zinc-800 dark:prose-blockquote:text-zinc-300 w-full max-w-full\n}\n\n.mdc-prose {\n  @apply prose prose-zinc prose-pre:bg-gray-100 dark:prose-pre:bg-zinc-400 dark:text-zinc-200 dark:prose-strong:text-zinc-200 prose-code:bg-zinc-200 dark:prose-code:bg-zinc-200 prose-code:text-zinc-800 dark:prose-blockquote:text-zinc-300 w-full max-w-full\n}\n```\n\n这样的话，在一个项目中，出现两组或多组不同的 `prose` 样式，就比较方便使用 `class` 控制了，毕竟 `tailwindcss.config.js` 只有一个，尽量设置一些通用的不常变化的属性。\n\n## 结语\n\n以上就是 `nuxtjs/mdc` 的大部分使用场景了，通常这个库会在使用 `Nuxt Content` 时使用，但也可以只使用它来支持多种来源，片段化的 `md` 内容渲染。\n\n但是要注意，虽然支持自定义组件，但我还是不建议你的 `md 文章`里不要包含太多的`魔法`，**在自己定制的平台上是魔法，在其他不支持的软件和 web 里就是麻瓜**。\n\n但是自定义组件很适合用来**支持自己的自建平台**，这也是我为什么会把 mdc 这个库拿出来单独使用。\n\n使用时注意文章开头的 `mdc` 版本号，表示此文章的生效范围，后续更新只能在我的[博客站](https://blog.zzao.club)同步了\n\n如果你也是 `Nuxt` 的使用者，或是 `Vue` 使用者对 `Nuxt` 感兴趣，欢迎在文末或博客站首页添加我的微信，一起交流，知无不言😎\n\n",{"title":5,"description":3596},"post/nuxt/nuxtjs-mdc-docs",[2398],[3605],"@nuxtjs/mdc@0.12.1","R38Hsc2F7K1tMOXH7HqE1X4uPEB9y7_mqLMRvAUbri8",[3608,3612],{"title":3609,"path":3610,"stem":3611},"OpenClaw 安装入门（Windows）","/post/zzao/openclaw/openclaw-install-windows","post/zzao/openclaw/openclaw-install-windows",{"title":3613,"path":3614,"stem":3615},"假设你是AI，你的Skill应该是什么样的","/post/zzao/ai-skill-structure","post/zzao/ai-skill-structure",1779005086310]