文章目录调整

This commit is contained in:
jimmy committed 2025-01-20 14:16:26 +08:00
1 parent 21654b1a92
commit 668119c264
16 files changed
+853 -168

No files matched your search

@@ -10,6 +10,7 @@ tags:
- JavaScript
- i18n
- BUG
- Blog
head:
- - meta
- name: description
@@ -21,7 +22,9 @@ editLink: false
lastUpdated: 2025-01-20T10:08:00
---
> 文章摘要
# {{ $frontmatter.title }}
> :black_nib: 文章摘要
<!-- DESC SEP -->
这篇文章讨论了在 Vue3 环境下使用 vue-i18n 和 element-plus 处理多语言提示时遇到的问题及解决方案。具体来说,文章描述了在使用
@@ -8,6 +8,7 @@ tags:
- Html
- JavaScript
- vue
- Blog
head:
- - meta
- name: description
@@ -19,7 +20,9 @@ editLink: false
lastUpdated: 2025-01-20T10:09:00
---
> 文章摘要
# {{ $frontmatter.title }}
> :black_nib: 文章摘要
<!-- DESC SEP -->
这篇文章介绍了如何在 JS 或 Vue 中实现表格的列和表头固定功能,适用于不同的开发环境(如原生
JavaScript、Vue、React、小程序等)。文章详细展示了实现这一功能的思路和具体步骤,包括使用 Vue3 和 TypeScript 结合 Less
@@ -6,6 +6,7 @@ tags:
- 编程
- 学习
- JavaScript
- Blog
head:
- - meta
- name: keywords
@@ -13,9 +14,9 @@ head:
editLink: false
lastUpdated: 2025-01-20T10:08:00
---
# {{ $frontmatter.title }}
> 文章摘要
> :black_nib: 文章摘要
<!-- DESC SEP -->
@@ -1,11 +1,12 @@
---
layout: doc
title: Vue3新属性 — css中使用v-bind(v-bind in css)
date: 2022-08-11
date: 2024-08-11
tags:
- 编程
- 学习
- vue
- Blog
head:
- - meta
- name: description
@@ -16,8 +17,9 @@ head:
editLink: false
lastUpdated: 2025-01-20T10:09:00
---
# {{ $frontmatter.title }}
> 文章摘要
> :black_nib: 文章摘要
<!-- DESC SEP -->
@@ -37,11 +39,11 @@ LESS:与 CSS 类似,使用变量和 v-bind() 绑定数据,但在 LESS 中
# Vue3新属性:CSS 中的 `v-bind()`
## 写在前面:
## 写在前面 {#write-in-front}
本文主要介绍Vue3中的新增的`v-bind()`的常用使用方式,主要包括在`css`,`less`,`scss`中的使用,可以参考官方文档查看:[Vue3官方文档](https://cn.vuejs.org/api/sfc-css-features.html#v-bind-in-css),本文将主要通过一个demo中的使用来展示
## 实际使用:
## 实际使用{#actual-use}
先创建一个通过的页面结构,因为是结构是通用内容,所以这里在直接进行简单的定义
@@ -6,6 +6,7 @@ tags:
- 编程
- 学习
- vue
- Blog
head:
- - meta
- name: description
@@ -16,8 +17,9 @@ head:
editLink: false
lastUpdated: 2025-01-20T10:09:00
---
# {{ $frontmatter.title }}
> 文章摘要
> :black_nib: 文章摘要
<!-- DESC SEP -->
这篇文章对比了 Vue2 和 Vue3 中的数据响应式处理方式,特别是如何定义和代理数据。在 Vue2 中,所有数据都通过一个统一的 data 对象进行管理,使用 Object.defineProperty 来实现响应式绑定。而在 Vue3 中,数据定义变得更加灵活,允许直接使用单一的数据类型,通过 ref 和 reactive 来创建响应式数据。虽然 ref 看似代理了普通数据,但实际上 Vue3 使用了 Proxy 技术对数据进行处理,这使得响应式机制变得更加高效和灵活。
@@ -6,17 +6,20 @@ tags:
- 编程
- 学习
- 设计
- Blog
head:
- - meta
- name: description
content: 有研究显示,打字的时候不喜欢在中文和英文之间加空格的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。毕竟爱情跟书写都需要适时地留白。与大家共勉之。
content: 这篇文章讨论了中英文混排时,是否应在汉字与拉丁字母之间加入空格的争议。研究和实践表明,虽然专业排版软件如Adobe InDesign通常会自动调整汉字与西文之间的间距,但许多普通用户常常手动插入半角空格以保证文本的可读性和美观。文章介绍了“空格派”在排版中的一些习惯,阐述了何时应该加空格、何时不加空格,并引用了刘昕等人关于中英文混排的标准,最后强调了空格的使用对提高文本阅读体验的重要性。
- - meta
- name: keywords
content: 文字排版 布局
editLink: false
lastUpdated: 2025-01-20T10:10:00
---
> 文章摘要
# {{ $frontmatter.title }}
> :black_nib: 文章摘要
<!-- DESC SEP -->
这篇文章讨论了中英文混排时,是否应在汉字与拉丁字母之间加入空格的争议。研究和实践表明,虽然专业排版软件如Adobe InDesign通常会自动调整汉字与西文之间的间距,但许多普通用户常常手动插入半角空格以保证文本的可读性和美观。文章介绍了“空格派”在排版中的一些习惯,阐述了何时应该加空格、何时不加空格,并引用了刘昕等人关于中英文混排的标准,最后强调了空格的使用对提高文本阅读体验的重要性。
@@ -6,7 +6,11 @@ tags:
- 编程
- 思考
- TypeScript
- Blog
head:
- - meta
- name: description
content: Turbo 8 放弃 TypeScript:作者认为 TypeScript 的类型检查反而增加了开发中的负担,并且声明类型复杂化代码,减少了开发效率。这个观点在 Reddit 和知乎引发了激烈讨论,部分评论指出 Turbo 8 并不具备广泛影响力,且作者习惯发表反向意见。TypeScript 的额外成本:第二篇文章提到,在某些场景下,TypeScript 的类型体操带来不必要的复杂度,尤其是对于小型项目,编写精确的类型定义可能比核心逻辑代码更为冗长。然而,TypeScript 相比于 JavaScript 在维护性和可扩展性上具有优势,尤其是对于框架和类库的开发者而言,尽管带来一些额外的维护成本。总体来看,放弃 TypeScript 的选择多见于小型或开源项目的维护者,而对于大多数开发者来说,TypeScript 提供的类型系统和可维护性仍然是更受欢迎的选择。
- - meta
- name: keywords
content: vue vue3 js javascript react ts typescript
@@ -14,7 +18,9 @@ editLink: false
lastUpdated: 2025-01-20T10:09:34
---
> 文章摘要
# {{ $frontmatter.title }}
> :black_nib: 文章摘要
<!-- DESC SEP -->
@@ -1,10 +1,11 @@
---
layout: doc
title: 登录功能的思考
date: 2024-08-05
date: 2023-08-05
tags:
- 编程
- 想法
- Blog
head:
- - meta
- name: keywords
@@ -12,8 +13,9 @@ head:
editLink: false
lastUpdated: 2025-01-20T10:10:00
---
# {{ $frontmatter.title }}
> 文章摘要
> :black_nib: 文章摘要
<!-- DESC SEP -->
这篇文章介绍了如何安全地存储用户数据,包括用户名、密码哈希、邮箱等,强调使用 bcrypt 加密密码和唯一盐来提升安全性。它还详细解释了 HTTPS 如何通过加密、身份验证和数据完整性保护来确保通信安全,并探讨了前端加密与 HTTPS 的配合使用。此外,文章还讨论了如何管理 SSL/TLS 证书、Token 存储和安全性防护策略,如防止 XSS 和 CSRF 攻击。
@@ -7,18 +7,21 @@ tags:
- 思考
- vue
- React
- Blog
head:
- - meta
- name: description
content: Vue和React、Nextjs如何选择
content: 这篇文章探讨了 Vue、React 和 Next.js 之间的选择,并深入分析了 React 的一些优缺点。作者指出,虽然 Vue 在国内市场占据主导地位,React 在国外仍然保持强大的活力。但与此同时,React 面临不少批评,特别是其逐渐显现的技术债务和性能问题。文章引用了一些反对 React 的观点,强调 React 已显老化,且与其他框架相比,存在着难以兼容和过度依赖自定义模块的问题。同时,文章还提到其他框架如 Svelte 的优越性,认为它能提供类似 React 的功能,但更加简洁和高效。
- - meta
- name: keywords
content: vue vue3 js javascript react ts typescript
editLink: false
lastUpdated: 2025-01-20T10:09:34
---
# {{ $frontmatter.title }}
> 文章摘要
> :black_nib: 文章摘要
<!-- DESC SEP -->
@@ -1,9 +1,10 @@
---
layout: doc
title: 主流网站主页布局展示内容及渲染方式调研
date: 2024-08-03
date: 2023-08-03
tags:
- 设计
- Blog
head:
- - meta
- name: keywords
@@ -11,7 +12,7 @@ head:
editLink: false
lastUpdated: 2025-01-20T10:09:34
---
# {{ $frontmatter.title }}
对于大部分信息展示网站中都是通过大块的区域内容展示来展现更多信息,并且国内的对应的网站相对较老,所以UI设计以及UI风格上更加的质朴
@@ -1,146 +0,0 @@
---
layout: doc
title: VitePress 笔记使用
date: 2025-01-20
tags:
- 学习
- VitePress
editLink: false
lastUpdated: 2025-01-20T10:09:34
---
## 内部链接
内部链接将转换为单页导航的路由链接。此外,子目录中包含的每个 `index.md` 都会自动转换为 `index.html`,并带有相应的 URL `/`。
[VitePress 链接跳转](./VitePress%20链接跳转.md) <!-- 可以添加 .md -->
```html
[VitePress 链接跳转](./VitePress 链接跳转.md)
```
## YAML front matter
任何包含 [YAML](https://yaml.org/) front matter 块的文件都将是 由 Jekyll 作为特殊文件处理。前言必须是第一件事 ,并且必须采用在三短划线 线。下面是一个基本示例:
``` markdown
---
layout: post
title: Blogging Like a Hacker
---
```
### frontmatter 配置
示例:
``` markdown
---
title: Docs with VitePress
editLink: true
---
```
可以通过 Vue 表达式中的 `$frontmatter` 全局变量访问 frontmatter 数据:
``` Vue
{{ $frontmatter.title }}
```
> 该内容由 Vue 渲染: **{{ $frontmatter.title }}**
## head
- 类型:`HeadConfig[]`
指定要为当前页面注入的额外 head 标签。将附加在站点级配置注入的头部标签之后。
yaml
``` markdown
---
head:
- - meta
- name: description
content: hello
- - meta
- name: keywords
content: super duper SEO
---
```
## layout
- 类型:`doc | home | page`
- 默认值:`doc`
指定页面的布局。
- `doc`——它将默认文档样式应用于 markdown 内容。
- `home`——“主页”的特殊布局。可以添加额外的选项,例如 `hero` 和 `features`,以快速创建漂亮的落地页。
- `page`——表现类似于 `doc`,但它不对内容应用任何样式。当想创建一个完全自定义的页面时很有用。
``` yaml
---
layout: doc
---
```
## navbar
- 类型:`boolean`
- 默认值:`true`
是否显示导航栏。
``` yaml
---
navbar: false
---
```
## sidebar
- 类型:`boolean`
- 默认值:`true`
是否显示 侧边栏
```
---
sidebar: false
---
```
## aside
- 类型:`boolean | 'left'`
- 默认值:`true`
定义侧边栏组件在 `doc` 布局中的位置。
将此值设置为 `false` 可禁用侧边栏容器。
将此值设置为 `true` 会将侧边栏渲染到右侧。
将此值设置为 `left` 会将侧边栏渲染到左侧。
```yaml
---
aside: false
---
```
## lastUpdated
- 类型:`boolean | Date`
- 默认值:`true`
是否在当前页面的页脚中显示最后更新时间的文本。如果指定了日期时间,则会显示该日期时间而不是上次 git 修改的时间戳。
``` yaml
---
lastUpdated: false
---
```
> [!TIP]
> 你必须提交 markdown 文件才能看到最后更新时间。
@@ -1,4 +0,0 @@
# 完成跳转 ,可以点击返回
[返回](./VitePress%20笔记使用.md)
@@ -0,0 +1,181 @@
---
layout: doc
title: tauri 中创建和管理全局 emit 任务
date: 2025-01-21
tags:
- 编程
- Blog
- tauri
- rust
- argus
- 思考
- tokio
head:
- - meta
- name: description
content: 本文详细介绍了如何在 Tauri 中使用全局 Emit 机制来触发错误信息传递,解决后端错误处理问题。通过创建后台异步任务和管理全局事件,实现在没有前端 command 触发的情况下,后端能够主动触发前端事件的解决方案。
- - meta
- name: keywords
content: Tauri emit Tauri错误处理 Tauri全局事件 Tauri后端 emit触发 Tauri command 与 emit Tauri异步任务管理 Tauri后端错误传递 Tauri frontend emit Tauri异步错误处理
editLink: false
lastUpdated: 2025-01-21T10:34:34
---
# Tauri 全局 Emit 任务管理与错误处理机制
> :black_nib: 文章摘要
<!-- DESC SEP -->
在使用 Tauri 开发时,可以通过 `command` 来让前端调用后端,或通过 `emit` 实现后端触发前端事件。`emit` 的设计初衷是为了能够触发多个任务,尤其适用于后端错误信息的传递。在一些场景中,比如后端出错时,利用全局的 `emit` 可以方便地将错误信息传递给前端进行展示或处理。
在 Tauri 中,前端通过 `listen` API 来监听特定事件,而后端则通过 `AppHandle` 中的 `emit` 方法触发这些事件。然而,由于 `AppHandle` 的生命周期问题,它不能作为全局对象存储,这就引发了一个问题:如何在没有前端 `command` 触发的情况下,从后端触发全局的 `emit`。
为了解决这个问题,笔者提出了一种通过创建异步任务管理器的方法。通过使用 Tokio 创建一个后台线程来监听 `mpsc` 通道,后端可以通过该通道发送全局错误消息。当错误发生时,消息通过通道发送到前端,前端通过 `emit` API 处理并展示这些信息。此方案避免了 `AppHandle` 的生命周期问题,并保证了全局事件的触发机制。
<!-- DESC SEP -->
## 前言{#preface}
当在使用 `tauri` 时,可以使用其提供的 `command` 通过前端来调用后端,也可以使用 `emit` 通过后端来调用前端,当后端发生错误时,我们需要一种机制将错误信息传递到前端并进行处理。传统的 `command` 机制依赖于前端调用,而 `emit` 则更适合处理这种场景,因为它支持多个事件的触发。通过在多个地方绑定相同的事件,后端可以通过触发 `emit` 来统一通知前端进行错误处理。
基于此就可以做出很多事情,其中之一就是当后端运行出错时,可以通过全局的 `emit` 将错误信息传递到前端,并通过前端进行展示,或者提示用户错误错误处理,因为后端的报错是不可预知的,所以对于该 `emit` 来说,也应该是全局的,随时可以调用的。
## `emit` 介绍{#emit-introduce}
我们先介绍 `tauri` 中是如何做到 `emit` 的触发和绑定的
#### 前端监听
NPM 软件包提供了用于侦听全局事件和特定于 webview 的事件的 API。`@tauri-apps/api`
```js{9}
import { listen } from '@tauri-apps/api/event';
type DownloadStarted = {
url: string;
downloadId: number;
contentLength: number;
};
listen<DownloadStarted>('download-started', (event) => {
console.log(
`downloading ${event.payload.contentLength} bytes from ${event.payload.url}`
);
});
```
绑定方式通过对一个 '频道' 进行监听,然后来监控是否触发,可以定义接收的数据类型来传递数据
#### 后端触发
```rust{4}
use tauri::{AppHandle, Emitter};
#[tauri::command]
fn download(app: AppHandle, url: String) {
app.emit("download-started", &url).unwrap();
for progress in [1, 15, 50, 80, 100] {
app.emit("download-progress", progress).unwrap();
}
app.emit("download-finished", &url).unwrap();
}
```
后端的触发使用 `AppHandle` 中提供的 `emit` 函数,调用时
1. 通过前端调用后端提供的指令`download` 然后将对应的链接(`url`)传递进来
2. 而 `app: AppHandle` 则由 `tauri` 自动填充,这里的 `app` 就是软件的实例
3. 当拿到 `app` 后,使用其 `emit` 函数进行触发,从而触发前端的监听
整个过程在类似点击下载,后端开始下载,并且前端需要展示下载进度的场景没有什么问题,不过还记得我们的目的吗?我们需要完成的是全局的 `emit` 的触发,并通过此完成错误的提示
这时就会造成一个很严重的问题 :
> 我们的错误是不可预知的,而前端 `emit` 的触发是需要 `AppHandle` 的,> `AppHandle` 作为 Tauri 应用的实例对象,其生命周期和应用的运行状态密切相关,因此不能存储为全局静态对象。在常规情况下,`emit` 触发需要通过 `AppHandle`,但如果依赖前端的 `command` 触发 `emit`,就会陷入循环问题。为了避免这一问题,我们采用了异步线程管理,通过 `tokio` 和 `mpsc` 通道将事件传递给前端。
## 想法{#think}
我们重新整理一下现在需要做什么,现在需要将后端错误通过全局的 `emit` 进行前端,并且想要触发就需要 `AppHandle` ;并且不能将其存储为静态内容。
不过仔细观察官方提供的示例,我们的确无法将 `AppHandle` 进行存储,但是就像官方实例中那样,通过 `Command` 不仅可以拿到 `AppHandle` 实例,还可以通过 `while` 等循环方式让 `emit` 多次触发。
不过我们可以在 `command` 调用时,可以通过 `takio` 创建一个消息等待的线程,并 `takio` 的消息通知渠道保存起来,通过消息通知来传递触发对应的事件
## 创建通用线程处理{#common-thread-processing}
主要的思路是,创建对应的全局的后台任务处理,并通过循环等待
创建一个通用的任务管理器:
``` rust:line-numbers
pub async fn task_h<T, F>(mut rx: mpsc::Receiver<T>, f: F)
where
F: Fn(T),
{
// 无限循环确保 Receiver 一直保持活跃
loop {
match rx.recv().await {
Some(task) => {
f(task);
}
None => {
// 如果通道关闭,可以选择如何处理(这里是等待并继续)
println!("通道关闭,继续等待...");
}
}
}
}
```
`task_h` 函数是一个异步任务管理器,它通过 `mpsc` 通道不断接收任务并执行相应的处理。这个函数的作用是确保事件能够在后台持续触发,而不会受到生命周期的限制。`emit_global_msg` 则是一个全局任务初始化函数,它在首次调用时设置状态并启动一个新的线程来处理错误信息的传递。
使用时,通过将要调用的函数,传递的数据都传递过来,根据我们需求,将会是这样:
```rust{22}
#[tauri::command]
pub fn emit_global_msg(app: AppHandle) {
let mut is_init = GLOBAL_EMIT_IS_INIT.lock().unwrap();
if is_init.clone() {
return;
}
println!("前端 emit 初始化!");
*is_init = true;
let mut emit = GLOBAL_EMIT_APP_HANDLE.lock().unwrap();
let (emit_tx, emit_rx) = mpsc::channel::<String>(100);
*emit = Some(emit_tx);
let f = move |info: String| {
app.clone().emit(global_front_emit::GLOBAL_ERROR_MSG_DISPLAY, info).unwrap();
};
// 在一个新的线程中启动 Tokio 运行时
thread::spawn(move || {
// 创建 Tokio 运行时并运行异步任务
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.block_on(async move {
task_h(emit_rx, f).await;
});
});
}
```
`GLOBAL_EMIT_APP_HANDLE` 和 `GLOBAL_EMIT_IS_INIT` 分别用于管理全局事件的发送者和初始化状态。通过 `lock` 锁定这些全局状态,确保多次调用时不会重复初始化,从而避免不必要的资源浪费和逻辑错误。
获取到 `AppHandle` 后,我们创建一个闭包,并将具体逻辑传入其中。由于该函数会多次触发,我们需要将 `AppHandle` 移入闭包并进行克隆使用。所有的内容准备好后,创建一个新的 `channel` 将`发送者`保存为全局对象,以供后期使用,而`接收者`交给新线程的任务处理者使用。
最后,通过 `thread::spawn` 启动一个新的线程,并创建一个 `tokio` 运行时来单独运行。
这个函数在进入运行时后,将一直循环和等待任务,`AppHandle` 会被劫持在其中
调用时:
```rust{14}
let emit_option = {
let emit = GLOBAL_EMIT_APP_HANDLE.lock().unwrap();
emit.clone() // 移出作用域以释放锁
};
if let Some(x) = emit_option.as_ref() {
let ms = GlobalErrorMsg {
title: "标题".parse().unwrap(),
msg: "内容".parse().unwrap(),
duration: 5000,
kind: crate::structs::global_error_msg::GlobalErrorMsgTypeEnum::Success,
};
let result = JsonUtil::stringify(&ms).expect("数据序列化失败!");
let qqq = x.send(result).await;
if qqq.is_err() {
println!("发送失败!");
}
}
```
通过拿到保存的`发送者`,并调用其中的 `send` 函数将数据传递到封装的函数中,以完成函数调用。
@@ -0,0 +1,7 @@
---
date: 2025-01-21
title: VitePress 链接使用
---
# 完成跳转 ,可以点击返回
[返回](vitepress-note-use.md)
+621
View File
@@ -0,0 +1,621 @@
---
layout: doc
title: VitePress 笔记使用
date: 2025-01-20
tags:
- 学习
- VitePress
- Blog
- Markdown
editLink: false
lastUpdated: 2025-01-20T10:09:34
head:
- - meta
- name: description
content: 本文介绍了如何使用 vitepress
---
> :black_nib: 文章摘要
<!-- DESC SEP -->
本文介绍了如何使用 vitepress
<!-- DESC SEP -->
## 内部链接
内部链接将转换为单页导航的路由链接。此外,子目录中包含的每个 `index.md` 都会自动转换为 `index.html`,并带有相应的 URL `/`。
[vitepress-link-jump](vitepress-link-jump.md) <!-- 可以添加 .md -->
```html
[VitePress 链接跳转](./VitePress 链接跳转.md)
```
## YAML front matter
任何包含 [YAML](https://yaml.org/) front matter 块的文件都将是 由 Jekyll 作为特殊文件处理。前言必须是第一件事 ,并且必须采用在三短划线 线。下面是一个基本示例:
``` markdown
---
layout: post
title: Blogging Like a Hacker
---
```
### frontmatter 配置
示例:
``` markdown
---
title: Docs with VitePress
editLink: true
---
```
可以通过 Vue 表达式中的 `$frontmatter` 全局变量访问 frontmatter 数据:
``` Vue
{{ $frontmatter.title }}
```
> 该内容由 Vue 渲染: **{{ $frontmatter.title }}**
## head
- 类型:`HeadConfig[]`
指定要为当前页面注入的额外 head 标签。将附加在站点级配置注入的头部标签之后。
yaml
``` markdown
---
head:
- - meta
- name: description
content: hello
- - meta
- name: keywords
content: super duper SEO
---
```
## layout
- 类型:`doc | home | page`
- 默认值:`doc`
指定页面的布局。
- `doc`——它将默认文档样式应用于 markdown 内容。
- `home`——“主页”的特殊布局。可以添加额外的选项,例如 `hero` 和 `features`,以快速创建漂亮的落地页。
- `page`——表现类似于 `doc`,但它不对内容应用任何样式。当想创建一个完全自定义的页面时很有用。
``` yaml
---
layout: doc
---
```
## navbar
- 类型:`boolean`
- 默认值:`true`
是否显示导航栏。
``` yaml
---
navbar: false
---
```
## sidebar
- 类型:`boolean`
- 默认值:`true`
是否显示 侧边栏
```
---
sidebar: false
---
```
## aside
- 类型:`boolean | 'left'`
- 默认值:`true`
定义侧边栏组件在 `doc` 布局中的位置。
将此值设置为 `false` 可禁用侧边栏容器。
将此值设置为 `true` 会将侧边栏渲染到右侧。
将此值设置为 `left` 会将侧边栏渲染到左侧。
```yaml
---
aside: false
---
```
## lastUpdated
- 类型:`boolean | Date`
- 默认值:`true`
是否在当前页面的页脚中显示最后更新时间的文本。如果指定了日期时间,则会显示该日期时间而不是上次 git 修改的时间戳。
``` yaml
---
lastUpdated: false
---
```
> [!TIP]
> 你必须提交 markdown 文件才能看到最后更新时间。
## Emoji
输入:
```html
:tada: :100:
```
输出:
:tada: :100:
## 自定义容器
自定义容器可以通过它们的类型、标题和内容来定义。
**输入**
```md
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
```
**输出**
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
## 自定义标题
可以通过在容器的 "type" 之后附加文本来设置自定义标题。
**输入**
``` md
::: danger STOP
危险区域,请勿继续
:::
::: details 点我查看代码
```js
console.log('Hello, VitePress!')
```
**输出**
::: danger STOP
危险区域,请勿继续
:::
::: details 点我查看代码
```js
console.log('Hello, VitePress!')
```
:::
## GitHub 风格的警报
```markdown
> [!NOTE]
> Useful information that users should know, even when skimming content.
> [!TIP]
> Helpful advice for doing things better or more easily.
> [!IMPORTANT]
> Key information users need to know to achieve their goal.
> [!WARNING]
> Urgent info that needs immediate user attention to avoid problems.
> [!CAUTION]
> Advises about risks or negative outcomes of certain actions.
```
> [!NOTE]
> Useful information that users should know, even when skimming content.
> [!TIP]
> Helpful advice for doing things better or more easily.
> [!IMPORTANT]
> Key information users need to know to achieve their goal.
> [!WARNING]
> Urgent info that needs immediate user attention to avoid problems.
> [!CAUTION]
> Advises about risks or negative outcomes of certain actions.
## 在代码块中实现行高亮
**输入**
```` md
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
````
**输出**
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
除了单行之外,还可以指定多个单行、多行,或两者均指定:
- 多行:例如 `{5-8}`、`{3-10}`、`{10-17}`
- 多个单行:例如 `{4,7,9}`
- 多行与单行:例如 `{4,7-13,16,23-27,40}`
**输入**
```` md
```js{1,4,6-8}
export default { // Highlighted
data () {
return {
msg: `Highlighted!
This line isn't highlighted,
but this and the next 2 are.`,
motd: 'VitePress is awesome',
lorem: 'ipsum'
}
}
}
```
````
**输出**
```js{1,4,6-8}
export default { // Highlighted
data () {
return {
msg: `Highlighted!
This line isn't highlighted,
but this and the next 2 are.`,
motd: 'VitePress is awesome',
lorem: 'ipsum'
}
}
}
```
也可以使用 `// [!code highlight]` 注释实现行高亮。
**输入**
````
```js
export default {
data () {
return {
msg: 'Highlighted!' // [!code highlight]
}
}
}
```
````
**输出**
```js
export default {
data () {
return {
msg: 'Highlighted!' // [!code highlight]
}
}
}
```
## 代码块中聚焦
在某一行上添加 `// [!code focus]` 注释将聚焦它并模糊代码的其他部分。
此外,可以使用 `// [!code focus:<lines>]` 定义要聚焦的行数。
**输入**
````
```js
export default {
data () {
return {
msg: 'Focused!' // [!!code focus]
}
}
}
```
````
**输出**
```js
export default {
data () {
return {
msg: 'Focused!' // [!code focus]
}
}
}
```
## 代码块中的颜色差异 {#colored-diffs-in-code-blocks}
在某一行添加 `// [!code --]` 或 `// [!code ++]` 注释将会为该行创建 diff,同时保留代码块的颜色。
**输入**
````
```js
export default {
data () {
return {
msg: 'Removed' // [!!code --]
msg: 'Added' // [!!code ++]
}
}
}
```
````
**输出**
```js
export default {
data () {
return {
msg: 'Removed' // [!code --]
msg: 'Added' // [!code ++]
}
}
}
```
## 高亮“错误”和“警告” {#errors-and-warnings-in-code-blocks}
在某一行添加 `// [!code warning]` 或 `// [!code error]` 注释将会为该行相应的着色。
**输入**
````
```js
export default {
data () {
return {
msg: 'Error', // [!!code error]
msg: 'Warning' // [!!code warning]
}
}
}
```
````
**输出**
```js
export default {
data() {
return {
msg: 'Error', // [!code error]
msg: 'Warning' // [!code warning]
}
}
}
```
## 行号 {#line-numbers}
可以通过以下配置为每个代码块启用行号:
```js
export default {
markdown: {
lineNumbers: true
}
}
```
查看 [`markdown` 选项](../reference/site-config#markdown) 获取更多信息。
可以在代码块中添加 `:line-numbers` / `:no-line-numbers` 标记来覆盖在配置中的设置。
还可以通过在 `:line-numbers` 之后添加 `=` 来自定义起始行号,例如 `:line-numbers=2` 表示代码块中的行号从 2 开始。
**输入**
````md
```ts {1}
// 默认禁用行号
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers {1}
// 启用行号
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers=2 {1}
// 行号已启用,并从 2 开始
const line3 = 'This is line 3'
const line4 = 'This is line 4'
```
````
**输出**
```ts {1}
// 默认禁用行号
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers {1}
// 启用行号
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers=2 {1}
// 行号已启用,并从 2 开始
const line3 = 'This is line 3'
const line4 = 'This is line 4'
```
## 代码组 {#code-groups}
可以像这样对多个代码块进行分组:
**输入**
````md
::: code-group
```js [config.js]
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
}
export default config
```
```ts [config.ts]
import type { UserConfig } from 'vitepress'
const config: UserConfig = {
// ...
}
export default config
```
:::
````
**输出**
::: code-group
```js [config.js]
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
}
export default config
```
```ts [config.ts]
import type { UserConfig } from 'vitepress'
const config: UserConfig = {
// ...
}
export default config
```
:::
## 数学方程 {#math-equations}
现在这是可选的。要启用它,需要安装 `markdown-it-mathjax3`,在配置文件中设置`markdown.math` 为 `true`:
```sh
npm add -D markdown-it-mathjax3
```
```ts [.vitepress/config.ts]
export default {
markdown: {
math: true
}
}
```
**输入**
```md
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
**Maxwell's equations:**
| equation | description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
```
**输出**
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
**Maxwell's equations:**
| equation | description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
Whitespace-only changes.