2024-03-18 00:12:25 +08:00

845 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 高阶
author: pengzhanbo
icon: ic:outline-auto-fix-high
createTime: 2024/03/05 16:27:59
permalink: /guide/markdown/advance/
---
## 选项组
让你的 Markdown 文件支持选项卡。
你需要将选项卡包装在 `tabs` 容器中。
你可以在 `tabs` 容器中添加一个 id 后缀,该后缀将用作选项卡 id。
所有具有相同 id 的选项卡将共享相同的切换事件。
```md
::: tabs#fruit
<!-- 这里fruit 将用作 id它是可选的 -->
<!-- 选项卡内容 -->
:::
```
在这个容器内,你应该使用 `@tab` 标记来标记和分隔选项卡内容。
`@tab` 标记后,你可以添加文本 `:active` 默认激活选项卡,之后的文本将被解析为选项卡标题。
```md
::: tabs
@tab 标题 1
<!-- tab 1 内容 -->
@tab 标题 2
<!-- tab 2 内容 -->
@tab:active 标题 3
<!-- tab 3 将会被默认激活 -->
<!-- tab 3 内容 -->
:::
```
默认情况下,标题将用作选项卡的值,但你可以使用 id 后缀覆盖它。
```md
::: tabs
@tab 标题 1
<!-- 此处,选项卡 1 的标题“标题 1”将用作值。 -->
<!-- tab 1 内容 -->
@tab 标题 2#值 2
<!-- 这里tab 2 的标题将是 “标题 2”但它会使用 “值 2” 作为选项卡的值-->
<!-- tab 2 内容 -->
:::
```
你可以在每个选项卡中使用 Vue 语法和组件,并且你可以访问 value 和 isActive
表示选项卡的绑定值和选项卡是否处于激活状态。
**输入**
````
::: tabs
@tab npm
npm 应该与 Node.js 被一同安装。
@tab pnpm
```sh
corepack enable
corepack use pnpm@8
```
:::
````
**输出**
::: tabs
@tab npm
npm 应该与 Node.js 被一同安装。
@tab pnpm
```sh
corepack enable
corepack use pnpm@8
```
:::
## 示例容器
有时候,你可能需要在 内容中补充一些 示例,但期望能与 其它内容 分隔开来呈现。
主题支持在 Markdown 文件中添加示例容器。
### 语法
````md
::: demo-wrapper
添加你的示例
:::
````
### 选项
- `title="xxx"`:标题
- `no-padding`:不添加内边距
- `img`: 仅包含图片时使用
- `height="xxx"`: 高度
### 示例
仅包含图片:
```md
::: demo-wrapper img no-padding
![](/images/custom-hero.png)
:::
```
**输出:**
::: demo-wrapper img no-padding
![](/images/custom-hero.png)
:::
包含 markdown 语法:
```md
::: demo-wrapper title="标题"
### 三级标题
这是示例容器中的内容。
:::
```
**输出:**
::: demo-wrapper title="标题"
### 三级标题
这是示例容器中的内容。
:::
包含 html /vue 代码:
```md
::: demo-wrapper
<h1 class="your-demo-title">这是标题</h1>
<p class="your-demo-paragraph">这是段落</p>
<style>
.your-demo-title {
color: red;
}
.your-demo-paragraph {
color: blue;
}
</style>
:::
```
**输出:**
::: demo-wrapper
<h1 class="your-demo-title">这是标题</h1>
<p class="your-demo-paragraph">这是段落</p>
<style>
.your-demo-title {
color: red !important;
}
.your-demo-paragraph {
color: blue !important;
}
</style>
:::
## can I use
在编写文章时, 提供嵌入 [can-i-use](https://caniuse.com/) WEB feature 各平台支持说明 的功能。
方便在描述某个 WEB feature 时,能更直观的表述 该特性的支持程度。
在你的 文章 markdown文件中使用以下格式
``` md
::: caniuse <feature> {browser_versions}
:::
```
__示例 获取 css 伪类选择器 `:dir()` 在各个浏览器的支持情况图标__
``` md
::: caniuse css-matches-pseudo
:::
```
效果:
::: caniuse css-matches-pseudo
:::
### 语法
``` md
::: caniuse <feature> {browser_versions}
:::
```
- `<feature>`
必填。 正确取值请参考 [https://caniuse.bitsofco.de/](https://caniuse.bitsofco.de/)
- `{browser_versions}`
可选。当前特性在多个版本中的支持情况。
默认值为: `{-2,-1,1}`
格式: `{number,number,...}` 取值范围为 `-5 ~ 3`
- 小于`0` 表示低于当前浏览器版本的支持情况
- `0` 表示当前浏览器版本的支持情况
- 大于`0` 表示高于当前浏览器版本的支持情况
## 导入文件
主题支持在 Markdown 文件中导入文件切片。
导入文件 默认不启用,你可以通过配置来启用它。
::: code-tabs
@tab .vuepress/config.ts
```ts
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownEnhance: {
include: true, // [!code highlight]
},
}
})
})
```
:::
### 语法
使用 `<!-- @include: filename -->` 导入文件。
如果要部分导入文件,你可以指定导入的行数:
- `<!-- @include: filename{start-end} -->`
- `<!-- @include: filename{start-} -->`
- `<!-- @include: filename{-end} -->`
同时你也可以导入文件区域:
- `<!-- @include: filename#region -->`
::::tip 文件区域
文件区域是 vscode 中的一个概念,区域内容被 `#region` 和 `#endregion` 注释包围。
<!-- @include: ../../snippet/include-1.snippet.md -->
::::
### 高级
你还可以设置一个对象来自定义包含文件路径和包含行为。
```ts
interface IncludeOptions {
/**
* 处理 include 文件路径
*
* @default (path) => path
*/
resolvePath?: (path: string, cwd: string | null) => string
/**
* 是否深度导入包含的 Markdown 文件
*
* @default false
*/
deep?: boolean
/**
* 是否使用 `<!-- @include: xxx -->` 代替 `@include: xxx` 导入文件
*
* @default true
*/
useComment?: boolean
/**
* 是否解析包含的 Markdown 文件的里的相对图像路径
*
* @default true
*/
resolveImagePath?: boolean
/**
* 是否解析包含的 Markdown 文件的里的文件相对路径
*
* @default true
*/
resolveLinkPath?: boolean
}
```
例如: 你可以使用 @src 作为源文件夹的别名。
::: code-tabs
@tab .vuepress/config.ts
```ts{5-11}
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownEnhance: {
include: {
resolvePath: (file) => {
if (file.startsWith('@src'))
return file.replace('@src', path.resolve(__dirname, '..'))
return file
},
},
},
}
})
})
```
:::
此外,如果你想将 Markdown 文件直接放在实际文件旁边,但不希望它们呈现为页面,
你可以在 VuePress 配置中设置 `pagePatterns` 选项。
有关详细信息,请参阅 [pagePatterns](https://vuejs.press/zh/reference/config.html#pagepatterns)。
::: code-tabs
@tab .vuepress/config.ts
```ts
export default defineUserConfig({
// 现在任何带有 `.snippet.md` 扩展名的文件都不会呈现为页面
pagePatterns: ['**/*.md', '!**/*.snippet.md', '!.vuepress', '!node_modules'], // [!code ++]
theme: plumeTheme({
plugins: {
markdownEnhance: {
include: true,
},
}
})
})
```
:::
### 示例
在项目中有一个 `foo.snippet.md` 文件:
:::: code-tabs
@tab foo.snippet.md
```md
### 三级标题
这是 foo.snippet.md 文件中的内容。
::: info
提示容器包括的内容
:::
<!-- region snippet -->
这里是被 `<!-- region snippet -->` 包裹的内容。
通过 `<!-- @include: ./foo.snippet.md#snippet -->` 来引入。
<!-- endregion snippet -->
```
::::
使用 `<!-- @include: ./foo.snippet.md -->` 导入文件:
:::: demo-wrapper title="Include by file"
<!-- @include: ../../snippet/include-2.snippet.md -->
::::
使用 `<!-- @include: ./foo.snippet.md{5-7} -->` 导入文件内的 5 到 7 行:
:::: demo-wrapper title="Include by lines"
<!-- @include: ../../snippet/include-2.snippet.md{5-7} -->
::::
使用 `<!-- @include: ./foo.snippet.md#snippet -->` 导入 `snippet` 区域
:::: demo-wrapper title="Include by file region"
<!-- @include: ../../snippet/include-2.snippet.md#snippet -->
::::
## 代码演示
代码演示 默认不启用,你可以通过配置来启用它。
::: code-tabs
@tab .vuepress/config.ts
```ts
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownEnhance: {
demo: true,
},
}
})
})
```
:::
### 语法
```` md
::: [类型]-demo 可选的标题文字
```html
<!-- ↑ 使用可用的语言 -->
<!-- 在代码块中放置你对应语言的代码,一个语言不能出现多个块 -->
<!-- 你可以有多个代码块,并且 html, js, css 都是视情况可选的 -->
```
```json
// json block 作为插件配置存放处
{
// 放置你的配置 (可选的)
}
```
:::
````
::: tip 提示
JSON 块是可选的,可用的配置详见[配置](https://vuepress-theme-hope.github.io/v2/md-enhance/zh/config.html)
:::
插件支持三种类型
- normal(默认)
- vue
- react
### 可用的语言
你可以在演示块中使用不同语言。
当你设置一些不能在浏览器上直接运行的语言时,由于插件无法解析它们,因此网页演示将被禁用。插件只显示代码。同时提供一个 "在 CodePen 中打开" 按钮允许用户直接在 CodePen 打开并浏览代码。
可用的 HTML 语言:
- `"html"` (默认)
- `"slim"`
- `"haml"`
- `"markdown"`
可用的 JS 语言:
- `"javascript"` (default)
- `"coffeescript"`
- `"babel"`
- `"livescript"`
- `"typescript"`
> 你也可以在代码块中使用 `js`, `ts`, `coffee` 和 `ls。`
可用的 CSS 语言:
- `"css"` (default)
- `"less"`
- `"scss"`
- `"sass"`
- `"stylus"`
### 不支持的语言
::: normal-demo 一个使用浏览器不支持解析语言 Demo
```md
# 标题
十分强大
```
```ts
const message: string = 'VuePress Theme Hope'
document.querySelector('h1').innerHTML = message
```
```scss
h1 {
font-style: italic;
+ p {
color: red;
}
}
```
:::
:::: details 代码
```` md
::: normal-demo 一个使用浏览器不支持解析语言 Demo
```md
# 标题
十分强大
```
```ts
const message: string = 'VuePress Theme Hope'
document.querySelector('h1').innerHTML = message
```
```scss
h1 {
font-style: italic;
+ p {
color: red;
}
}
```
:::
````
::::
### 普通代码演示
格式:
```` md
::: normal-demo 可选的标题文字
```html
<!-- html code -->
```
```js
// js code
```
```css
/* css code */
```
```json
// 配置 (可选)
{
"jsLib": [
// ...
],
"cssLib": [
// ...
]
}
```
:::
````
::: warning 注意事项
我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document请访问` `window.document`。
:::
#### 例子
::: normal-demo Demo 演示
```html
<h1>Hello Word!</h1>
<p><span id="very">非常</span>强大!</p>
```
```js
document.querySelector('#very').addEventListener('click', () => {
alert('非常强大')
})
```
```css
span {
color: red;
}
```
:::
:::: details 代码
```` md
::: normal-demo Demo 演示
```html
<h1>Hello Word!</h1>
<p><span id="very">非常</span>强大!</p>
```
```js
document.querySelector('#very').addEventListener('click', () => {
alert('非常强大')
})
```
```css
span {
color: red;
}
```
:::
````
::::
### Vue 代码演示
#### 格式
```` md
::: vue-demo 可选的标题文字
```vue
<!-- ↑ 你也可以使用 html -->
<script>
export default {
// vue 组件
}
</script>
<template>
<!-- vue 模板 -->
<div>demo</div>
</template>
<style>
/* css 代码 */
</style>
```
```json
// 配置 (可选)
{}
```
:::
````
::: warning 注意事项
- 你只能使用 `Vue3`。
- 必须将组件通过 `export default` 默认导出
- 我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document`,请访问 `window.document`。
:::
#### 演示
::: vue-demo 一个 Vue Composition 演示
```vue
<script>
const { ref } = Vue
export default {
setup() {
const message = ref('powerful')
const handler = () => {
message.value = `very ${message.value}`
}
return {
message,
handler,
}
},
}
</script>
<template>
<div class="box">
<code>Hello Word</code> is
<span @click="handler">{{ message }}</span>!
</div>
</template>
<style>
.box span {
color: red;
}
</style>
```
:::
:::: details 代码
```` md
::: vue-demo 一个 Vue Composition 演示
```vue
<script>
const { ref } = Vue
export default {
setup() {
const message = ref('powerful')
const handler = () => {
message.value = `very ${message.value}`
}
return {
message,
handler,
}
},
}
</script>
<template>
<div class="box">
<code>Hello Word</code> is
<span @click="handler">{{ message }}</span>!
</div>
</template>
<style>
.box span {
color: red;
}
</style>
```
:::
````
::::
### React 代码演示
#### 格式
```` md
::: react-demo 可选的标题文字
```js
// 放置脚本,并通过 `export default` 导出你的 react 组件
```
```css
/* 你的 css 内容 */
```
```json
// 配置 (可选)
{}
```
:::
````
::: warning 注意事项
- 使用 React 的时候,为了解析 JSX 必须引入 Babel此过程由插件自动完成。
- 必须将组件通过 `export default` 默认导出
- 我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document`,请访问 `window.document`。
:::
#### 演示
::: react-demo 一个函数式 React Demo
```js
const { useState } = React
export default () => {
const [message, setMessage] = useState(' 强大')
const handler = () => {
setMessage(`十分${message}`)
}
return (
<div className="box">
<code>Hello Word !</code>
<span id="powerful" onClick={handler}>
{message}
</span>
</div>
)
}
```
```css
.box #powerful {
color: blue;
}
```
:::
:::: details 代码
```` md
::: react-demo 一个函数式 React Demo
```js
const { useState } = React
export default () => {
const [message, setMessage] = useState(' 强大')
const handler = () => {
setMessage(`十分${message}`)
}
return (
<div className="box">
<code>Hello Word !</code>
<span id="powerful" onClick={handler}>
{message}
</span>
</div>
)
}
```
```css
.box #powerful {
color: blue;
}
```
:::
````
::::