mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
796 lines
17 KiB
Markdown
796 lines
17 KiB
Markdown
---
|
|
title: Frontend Demo
|
|
icon: icon-park-outline:html-five
|
|
createTime: 2025/01/08 21:34:26
|
|
permalink: /en/guide/repl/frontend/
|
|
---
|
|
|
|
::: important Legacy Frontend Code Demo Deprecated - Please Migrate to New Solution
|
|
|
|
The legacy solution was provided by [vuepress-plugin-md-enhance](https://plugin-md-enhance.vuejs.press/zh/).
|
|
We appreciate its support for code demos in the past. The code demo functionality in
|
|
`vuepress-plugin-md-enhance` will be migrated to [vuepress/ecosystem](https://github.com/vuepress/ecosystem). For details, please refer to [vuepress/ecosystem#293](https://github.com/vuepress/ecosystem/pull/293).
|
|
|
|
:::
|
|
|
|
::: details Why Redesign?
|
|
|
|
Frontend code demos are a highly useful feature, but the legacy implementation did not align with actual usage scenario expectations.
|
|
|
|
In the legacy solution, for example, `vue-demo` only supported simple Vue component demonstrations
|
|
and could not directly import dependencies from the project. It relied on loading external scripts for
|
|
additional functionality and did not provide full support for Vue SFC, being limited to simple code demonstrations.
|
|
|
|
Furthermore, script code compilation occurred in the browser runtime. It required loading `babel` from a
|
|
CDN first, then performing the transformation via `babel`, which introduced additional waiting time.
|
|
Additionally, for internal enterprise projects within an intranet environment that cannot access external
|
|
resources, the demos failed to display properly.
|
|
|
|
In the new solution, all demo code is compiled and transformed during the Node.js runtime.
|
|
Therefore, demo code can be displayed directly in the browser runtime without extra waiting time.
|
|
Leveraging Node.js's powerful capabilities, it fully supports all features of Vue SFC and allows direct
|
|
import of project dependencies, enabling richer demonstrations that better match real-world usage scenarios.
|
|
:::
|
|
|
|
## Overview
|
|
|
|
This feature supports embedding code demonstration functionality within pages. A frontend code demo consists of two main areas:
|
|
==Render Area== and ==Code Area==.
|
|
|
|
The **Render Area** displays the execution results of the code, including UI rendering and interactions.
|
|
The **Code Area** displays the source code and is collapsed by default.
|
|
|
|
The theme provides support for three different types of frontend code demos:
|
|
|
|
- ==Vue Component Demo==: Supports demonstrations of `Vue` components.
|
|
Write your demo code as you would a `Vue` component.
|
|
It can be used to demonstrate external dependencies like component libraries or `Composables API`.
|
|
- ==Markdown Demo==: Supports demonstrations of `Markdown`.
|
|
- ==Normal Code Demo==: Supports native `HTML` + `JS/TS` + `CSS/Less/Sass/Stylus` code demos. Write your demo code as you would a web page.
|
|
|
|
The theme also provides two different methods for writing demo code:
|
|
|
|
- Embed Demo Code Files:
|
|
|
|
```md
|
|
@[demo type](url)
|
|
```
|
|
|
|
Use simple embedding syntax to import demo code from files.
|
|
|
|
- Inline Demo Code within Demo Container:
|
|
|
|
````md
|
|
::: demo type
|
|
``` [lang]
|
|
code
|
|
```
|
|
:::
|
|
````
|
|
|
|
Write demo code directly within the markdown file, wrapped in a `demo` container.
|
|
|
|
## Configuration
|
|
|
|
Frontend code demos are powered by [vuepress-plugin-md-power](../../config/plugins/markdown-power.md).
|
|
|
|
Frontend code demos are disabled by default. You can enable them via configuration.
|
|
|
|
```ts title=".vuepress/config.ts"
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
markdown: {
|
|
demo: true, // [!code ++]
|
|
},
|
|
})
|
|
})
|
|
```
|
|
|
|
## Language Support
|
|
|
|
Code demos support the following languages:
|
|
|
|
- javascript
|
|
- typescript
|
|
- html
|
|
- css
|
|
- less
|
|
- sass
|
|
- stylus
|
|
|
|
For CSS preprocessor languages, you need to install the corresponding preprocessor in your project, such as `less`, `sass`, or `stylus`.
|
|
|
|
## Embed Syntax
|
|
|
|
Different code demos use the same embed syntax, allowing you to quickly grasp their usage.
|
|
|
|
```md
|
|
<!-- Syntax -->
|
|
@[demo](url)
|
|
@[demo [type]](url)
|
|
@[demo [type] title="" desc="" expanded code-setting=""](url)
|
|
```
|
|
|
|
`@[demo](url)` is a fixed syntax format.
|
|
|
|
`[type]` indicates the type and supports three different values:
|
|
|
|
- `normal`: Normal code demo type. This is the default type when the `[type]` parameter is omitted.
|
|
- `vue`: Vue component demo type.
|
|
- `markdown`: Markdown demo type.
|
|
|
|
`url` indicates the path to the demo code file, which can be relative or absolute.
|
|
|
|
- Relative paths start with `./` or `../` and are relative to the current markdown file's path.
|
|
- Absolute paths start with `/` and are resolved from the [VuePress source directory path](../quick-start/project-structure.md#document-source-directory).
|
|
|
|
```md
|
|
<!-- Normal Code Demo -->
|
|
@[demo](./demo/normal.html)
|
|
@[demo normal](./demo/normal.html)
|
|
@[demo](/.vuepress/demo/normal.html)
|
|
|
|
<!-- Vue Component Demo -->
|
|
@[demo vue](./demo/Counter.vue)
|
|
@[demo vue](./demo/Counter.ts)
|
|
@[demo](/.vuepress/demo/Counter.vue)
|
|
|
|
<!-- Markdown Demo -->
|
|
@[demo markdown](./demo/example.md)
|
|
@[demo markdown](/.vuepress/demo/example.md)
|
|
```
|
|
|
|
Additional parameters:
|
|
|
|
- `title="xxx"`: Demo title.
|
|
- `desc="xxx"`: Demo description.
|
|
- `expanded`: Expand the code area.
|
|
- `code-setting="xxx"`: Code settings. The value will be appended after ``` [lang]` and is used to add configurations to the code block.
|
|
|
|
`code-setting=":lines-number"` will add `:lines-number` after the code block, enabling line numbers.
|
|
|
|
`code-setting=":collapsed-lines=10"` will add `:collapsed-lines=10` after the code block,
|
|
causing the code block to be collapsed starting from line 10.
|
|
|
|
```md
|
|
@[demo vue expanded title="Title" desc="Description" code-setting=":collapsed-lines=10"](./demo/Counter.vue)
|
|
```
|
|
|
|
## Demo Container Inline Demo
|
|
|
|
Demo container inline demos use the `demo` container to wrap the demo code, allowing quick writing of demo code within the markdown file:
|
|
|
|
```md
|
|
::: demo [type] title="" desc="" expanded
|
|
<!-- Code Block -->
|
|
:::
|
|
```
|
|
|
|
All parameters are the same as the `@[demo](url)` syntax.
|
|
|
|
````md
|
|
<!-- Normal Code Demo -->
|
|
::: demo
|
|
```html
|
|
<!-- html code -->
|
|
```
|
|
``` js
|
|
// js code
|
|
```
|
|
``` css
|
|
/* css code */
|
|
```
|
|
:::
|
|
|
|
<!-- Vue Component Demo -->
|
|
::: demo vue
|
|
``` vue
|
|
<!-- vue code -->
|
|
```
|
|
:::
|
|
|
|
<!-- Markdown Demo -->
|
|
::: demo markdown
|
|
``` md
|
|
<!-- markdown code -->
|
|
```
|
|
:::
|
|
````
|
|
|
|
You can also wrap code blocks with the `::: code-tabs` container within the `::: demo` container for better interactive presentation.
|
|
|
|
````md
|
|
:::: demo
|
|
::: code-tabs
|
|
@tab HTML
|
|
```html
|
|
<!-- html code -->
|
|
```
|
|
@tab javascript
|
|
``` js
|
|
// js code
|
|
```
|
|
@tab css
|
|
``` css
|
|
/* css code */
|
|
```
|
|
:::
|
|
:::::
|
|
````
|
|
|
|
When using TypeScript or `Less/Sass/Stylus`, simply modify the value of ` ``` [lang]`:
|
|
|
|
````md
|
|
:::: demo
|
|
::: code-tabs
|
|
@tab HTML
|
|
```html
|
|
<!-- html code -->
|
|
```
|
|
@tab Typescript
|
|
``` ts
|
|
// ts code
|
|
```
|
|
@tab Scss
|
|
``` scss
|
|
/* scss code */
|
|
```
|
|
:::
|
|
:::::
|
|
````
|
|
|
|
## Vue Component Demo
|
|
|
|
Vue component demo is a powerful feature with no restrictions on the demo code—it ultimately depends on the `bundler`'s support for Vue.
|
|
You can directly import dependencies installed in your project within the demo code, just as you would when writing a component in a Vue project.
|
|
|
|
Therefore, you can use it directly to provide demonstration examples for your component library or for your `Composables API`.
|
|
|
|
### Embed Syntax
|
|
|
|
You can directly embed a Vue component demo in a page using the following method:
|
|
|
|
**Input:**
|
|
|
|
```md
|
|
@[demo vue title="Counter" desc="Click the +1 button to increment the counter by 1"](./demo/Counter.vue)
|
|
```
|
|
|
|
::: details View `./demo/Counter.vue` Code
|
|
|
|
@[code](./demo/Counter.vue)
|
|
|
|
:::
|
|
|
|
**Output:**
|
|
|
|
@[demo vue title="Counter" desc="Click the +1 button to increment the counter by 1"](./demo/Counter.vue)
|
|
|
|
---
|
|
|
|
You can also embed a Vue component written in `.ts`:
|
|
|
|
**Input:**
|
|
|
|
```md
|
|
@[demo vue title="Counter" desc="Click the +1 button to increment the counter by 1"](./demo/Counter.ts)
|
|
```
|
|
|
|
::: details View `./demo/Counter.ts` Code
|
|
|
|
::: code-tabs
|
|
@tab Counter.ts
|
|
@[code](./demo/Counter.ts)
|
|
@tab Counter.module.css
|
|
@[code](./demo/Counter.module.css)
|
|
:::
|
|
|
|
**Output:**
|
|
|
|
@[demo vue title="Counter" desc="Click the +1 button to increment the counter by 1"](./demo/Counter.ts)
|
|
|
|
:::info For components written in `.js/.ts`, use `CSS Module` to write styles for style isolation.
|
|
:::
|
|
|
|
---
|
|
You can import external dependencies in the demo code.
|
|
Example using `useToggle()` from `@vueuse/core`:
|
|
|
|
**Input:**
|
|
|
|
```md
|
|
@[demo vue title="useToggle" desc="useToggle() Demo"](./demo/Toggle.vue)
|
|
```
|
|
|
|
::: details ./demo/Toggle.vue
|
|
@[code](./demo/Toggle.vue)
|
|
:::
|
|
|
|
**Output:**
|
|
|
|
@[demo vue title="useToggle" desc="useToggle() Demo"](./demo/Toggle.vue)
|
|
|
|
### Container Syntax
|
|
|
|
Using the `demo` container to wrap demo code in a markdown file allows for quick demo code writing:
|
|
|
|
**Input:**
|
|
|
|
:::: details Expand to view full code
|
|
|
|
````md
|
|
::: demo vue title="Counter" desc="Click the +1 button to increment the counter by 1"
|
|
```vue
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
|
|
const count = ref(0)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="counter">
|
|
<p>Counter: {{ count }}</p>
|
|
<button type="button" class="btn" @click="count += 1">
|
|
+ 1
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.btn {
|
|
border: 1px solid var(--vp-c-divider);
|
|
border-radius: 4px;
|
|
}
|
|
</style>
|
|
```
|
|
:::
|
|
````
|
|
|
|
::::
|
|
|
|
**Output:**
|
|
|
|
::: demo vue title="Counter" desc="Click the +1 button to increment the counter by 1"
|
|
|
|
```vue
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
|
|
const count = ref(0)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="counter">
|
|
<p>Counter: {{ count }}</p>
|
|
<button type="button" class="btn" @click="count += 1">
|
|
+ 1
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.btn {
|
|
border: 1px solid var(--vp-c-divider);
|
|
border-radius: 4px;
|
|
}
|
|
</style>
|
|
```
|
|
|
|
:::
|
|
|
|
:::::: warning
|
|
The Vue demo container syntax also supports embedding demo code using the `.js/ts + css` approach,
|
|
but this is not recommended by the theme. Styles cannot be isolated, which may lead to style pollution.
|
|
|
|
::::: details Reference Example
|
|
|
|
````md
|
|
:::: demo vue title="Title" desc="Description"
|
|
::: code-tabs
|
|
@tab Counter.ts
|
|
```ts
|
|
import { defineComponent, ref } from 'vue'
|
|
|
|
export default defineComponent({
|
|
// code
|
|
})
|
|
```
|
|
@tab Counter.css
|
|
```css
|
|
/* css code */
|
|
```
|
|
:::
|
|
::::
|
|
````
|
|
|
|
:::::
|
|
::::::
|
|
|
|
## Normal Code Demo
|
|
|
|
Normal code demos support `html`, `css/less/sass/stylus`, and `js/ts` languages.
|
|
|
|
They are suitable for relatively simple code demonstrations, such as a style rendering effect, an interaction effect, or a functionality.
|
|
|
|
Normal code demos also support jumping to `CodePen` and `jsFiddle` for viewing.
|
|
|
|
Additionally, they support importing third-party libraries via external links, such as `jQuery` or `dayjs`.
|
|
|
|
::: warning Overly complex demonstrations are not recommended.
|
|
:::
|
|
|
|
### Embed Syntax
|
|
|
|
When using the embed syntax, use `.html` as the file suffix for the imported demo code file.
|
|
In the `.html` file, you can write the demo code as you would an HTML page:
|
|
|
|
```html
|
|
<!-- html code -->
|
|
<div id="app">
|
|
Demo Content
|
|
<div>
|
|
|
|
<!-- Script content, use lang attribute to set language, defaults to js -->
|
|
<script lang="ts">
|
|
</script>
|
|
|
|
<!-- Style content, use lang attribute to set language, defaults to css -->
|
|
<style lang="css">
|
|
</style>
|
|
|
|
<!-- Optional configuration file in json format -->
|
|
<script type="config">
|
|
{
|
|
"jsLib": [],
|
|
"cssLib": []
|
|
}
|
|
</script>
|
|
```
|
|
|
|
Each section is optional. However, note that multiple identical sections are not supported. The order of sections does not matter.
|
|
Content outside of `<script>` and `<style>` is considered HTML code.
|
|
|
|
You can declare additional dependency resources to load using JSON format within `<script type="config"></script>`.
|
|
|
|
For example, loading `jQuery` and `normalize.css`:
|
|
|
|
```html
|
|
<div>xxxx</div>
|
|
|
|
<script type="config">
|
|
{
|
|
"jsLib": [
|
|
"https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"
|
|
],
|
|
"cssLib": [
|
|
"https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.min.css"
|
|
]
|
|
}
|
|
</script>
|
|
```
|
|
|
|
---
|
|
|
|
A conventional example:
|
|
|
|
**Input:**
|
|
|
|
```md
|
|
@[demo title="Example" desc="This is a conventional demo"](./demo/normal.html)
|
|
```
|
|
|
|
::: details View `./demo/normal.html` Code
|
|
@[code](./demo/normal.html)
|
|
:::
|
|
|
|
**Output:**
|
|
|
|
@[demo title="Example" desc="This is a conventional demo"](./demo/normal.html)
|
|
|
|
---
|
|
|
|
Example introducing `jQuery`, `dayjs`, and `normalize.css`:
|
|
|
|
**Input:**
|
|
|
|
```md
|
|
@[demo title="Example" desc="This is a conventional demo"](./demo/normal-lib.html)
|
|
```
|
|
|
|
::: details View `./demo/normal-lib.html` Code
|
|
@[code](./demo/normal-lib.html)
|
|
:::
|
|
|
|
**Output:**
|
|
|
|
@[demo title="Example" desc="This is a conventional demo"](./demo/normal-lib.html)
|
|
|
|
### Container Syntax
|
|
|
|
Using the demo container to wrap demo code in a markdown file allows for quick demo code writing:
|
|
|
|
:::: details Expand to view full example code
|
|
|
|
````md
|
|
::: demo title="Example" desc="Description" expanded
|
|
```json
|
|
{
|
|
"jsLib": [],
|
|
"cssLib": []
|
|
}
|
|
```
|
|
|
|
```html
|
|
<!-- html code -->
|
|
```
|
|
|
|
```js
|
|
// js code
|
|
```
|
|
|
|
```css
|
|
/* css code */
|
|
```
|
|
:::
|
|
````
|
|
|
|
::::
|
|
|
|
You can also wrap `::: code-tabs` within `::: demo` for better code block presentation:
|
|
|
|
::::: details Expand to view full example code
|
|
|
|
````md
|
|
:::: demo title="Example" desc="Description" expanded
|
|
```json
|
|
{
|
|
"jsLib": [],
|
|
"cssLib": []
|
|
}
|
|
```
|
|
::: code-tabs
|
|
@tab HTML
|
|
```html
|
|
<!-- html code -->
|
|
```
|
|
@tab Javascript
|
|
```js
|
|
// js code
|
|
```
|
|
@tab CSS
|
|
```css
|
|
/* css code */
|
|
```
|
|
:::
|
|
::::
|
|
````
|
|
|
|
:::::
|
|
|
|
---
|
|
|
|
A conventional container example:
|
|
|
|
**Input:**
|
|
|
|
::::: details Expand to view full example code
|
|
|
|
````md
|
|
:::: demo title="Conventional Example" desc="A conventional example"
|
|
::: code-tabs
|
|
@tab HTML
|
|
```html
|
|
<div id="app">
|
|
<h3>vuepress-theme-plume</h3>
|
|
</div>
|
|
```
|
|
@tab Javascript
|
|
```js
|
|
const a = 'So Awesome!'
|
|
const app = document.querySelector('#app')
|
|
app.appendChild(document.createElement('small')).textContent = a
|
|
```
|
|
@tab CSS
|
|
```css
|
|
#app {
|
|
font-size: 2em;
|
|
text-align: center;
|
|
}
|
|
```
|
|
:::
|
|
::::
|
|
````
|
|
|
|
:::::
|
|
|
|
**Output:**
|
|
|
|
:::: demo title="Conventional Example" desc="A conventional example"
|
|
|
|
::: code-tabs
|
|
@tab HTML
|
|
|
|
```html
|
|
<div id="app">
|
|
<h3>vuepress-theme-plume</h3>
|
|
</div>
|
|
```
|
|
|
|
@tab Javascript
|
|
|
|
```js
|
|
const a = 'So Awesome!'
|
|
const app = document.querySelector('#app')
|
|
app.appendChild(document.createElement('small')).textContent = a
|
|
```
|
|
|
|
@tab CSS
|
|
|
|
```css
|
|
#app {
|
|
font-size: 2em;
|
|
text-align: center;
|
|
}
|
|
```
|
|
|
|
:::
|
|
::::
|
|
|
|
---
|
|
|
|
Example introducing jQuery, dayjs, and normalize.css:
|
|
|
|
**Input:**
|
|
|
|
::::: details Expand to view full example code
|
|
|
|
````md
|
|
:::: demo title="Conventional Example" desc="A conventional example"
|
|
```json
|
|
{
|
|
"jsLib": [
|
|
"https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js",
|
|
"https://cdn.jsdelivr.net/npm/dayjs@1.11.13/dayjs.min.js"
|
|
],
|
|
"cssLib": ["https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.min.css"]
|
|
}
|
|
```
|
|
::: code-tabs
|
|
@tab HTML
|
|
```html
|
|
<div id="app">
|
|
<h3>vuepress-theme-plume</h3>
|
|
<p id="message"></p>
|
|
<datetime id="datetime"></datetime>
|
|
</div>
|
|
```
|
|
@tab Javascript
|
|
```js
|
|
$('#message').text('So Awesome!')
|
|
const datetime = $('#datetime')
|
|
setInterval(() => {
|
|
datetime.text(dayjs().format('YYYY-MM-DD HH:mm:ss'))
|
|
}, 1000)
|
|
```
|
|
@tab CSS
|
|
```css
|
|
#app {
|
|
font-size: 2em;
|
|
text-align: center;
|
|
}
|
|
```
|
|
:::
|
|
::::
|
|
````
|
|
|
|
:::::
|
|
|
|
**Output:**
|
|
|
|
:::: demo title="Conventional Example" desc="A conventional example"
|
|
|
|
```json
|
|
{
|
|
"jsLib": [
|
|
"https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js",
|
|
"https://cdn.jsdelivr.net/npm/dayjs@1.11.13/dayjs.min.js"
|
|
],
|
|
"cssLib": ["https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.min.css"]
|
|
}
|
|
```
|
|
|
|
::: code-tabs
|
|
@tab HTML
|
|
|
|
```html
|
|
<div id="app">
|
|
<h3>vuepress-theme-plume</h3>
|
|
<p id="message"></p>
|
|
<datetime id="datetime"></datetime>
|
|
</div>
|
|
```
|
|
|
|
@tab Javascript
|
|
|
|
```js
|
|
$('#message').text('So Awesome!')
|
|
const datetime = $('#datetime')
|
|
setInterval(() => {
|
|
datetime.text(dayjs().format('YYYY-MM-DD HH:mm:ss'))
|
|
}, 1000)
|
|
```
|
|
|
|
@tab CSS
|
|
|
|
```css
|
|
#app {
|
|
font-size: 2em;
|
|
text-align: center;
|
|
}
|
|
```
|
|
|
|
:::
|
|
::::
|
|
|
|
## Markdown Demo
|
|
|
|
Demonstrate markdown source code and rendering results within a page.
|
|
|
|
### Embed Syntax
|
|
|
|
**Input:**
|
|
|
|
```md
|
|
@[demo markdown title="Bulletin Board" desc="Bulletin Board Code Example"](/.vuepress/bulletin.md)
|
|
```
|
|
|
|
::: details Expand to view `/.vuepress/bulletin.md` Code
|
|
@[code](../../../.vuepress/bulletin.md)
|
|
:::
|
|
|
|
**Output:**
|
|
|
|
@[demo markdown title="Bulletin Board" desc="Bulletin Board Code Example"](/.vuepress/bulletin.md)
|
|
|
|
### Container Syntax
|
|
|
|
**Input:**
|
|
|
|
:::::: details Expand to view full code
|
|
|
|
````md
|
|
:::: demo markdown title="Bulletin Board" desc="Bulletin Board Code Example"
|
|
```md
|
|
::: center
|
|
|
|
**QQ Group:** [792882761](https://qm.qq.com/q/FbPPoOIscE)
|
|
|
|
{width="618" height="616" style="width: 200px"}
|
|
|
|
If you encounter any issues during use, please feel free to provide feedback via [issue](https://github.com/pengzhanbo/vuepress-theme-plume/issues/new/choose). You are also welcome to join our QQ group for discussion.
|
|
|
|
:::
|
|
```
|
|
::::
|
|
````
|
|
|
|
::::::
|
|
|
|
**Output:**
|
|
|
|
:::: demo markdown title="Bulletin Board" desc="Bulletin Board Code Example"
|
|
|
|
```md
|
|
::: center
|
|
|
|
**QQ Group:** [792882761](https://qm.qq.com/q/FbPPoOIscE)
|
|
|
|
{width="618" height="616" style="width: 200px"}
|
|
|
|
If you encounter any issues during use, please feel free to provide feedback via [issue](https://github.com/pengzhanbo/vuepress-theme-plume/issues/new/choose). You are also welcome to join our QQ group for discussion.
|
|
|
|
:::
|
|
```
|
|
|
|
::::
|