浏览代码

chore: 增加文档的在线调试功能 (#931)

zhenyulei 3 年之前
父节点
当前提交
52eabc261b

+ 2 - 0
package.json

@@ -92,6 +92,8 @@
     "inquirer": "^8.2.0",
     "jest": "^26.6.3",
     "lint-staged": "^10.5.0",
+    "lzutf8": "^0.6.0",
+    "markdown-it-container": "^3.0.0",
     "prettier": "^2.0.0",
     "standard-version": "^9.3.0",
     "swiper": "6.5.1",

+ 67 - 30
src/packages/__VUE/avatar/doc.md

@@ -5,69 +5,106 @@
 用来代表用户或事物,支持图片、图标或字符展示。
 
 ### 安装
-``` javascript
+
+```javascript
 import { createApp } from 'vue';
 // vue
-import { Avatar,Icon } from '@nutui/nutui';
+import { Avatar, Icon } from '@nutui/nutui';
 // taro
-import { Avatar,Icon } from '@nutui/nutui-taro';
+import { Avatar, Icon } from '@nutui/nutui-taro';
 
 const app = createApp();
 app.use(Avatar);
 app.use(Icon);
 ```
 
-
 ### 基本用法
 
 内置 smal / normal / large 三种尺寸规格
 
-``` html
-<nut-avatar size="large" icon="https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png"
-></nut-avatar>
-<nut-avatar size="normal" icon="https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png"
-></nut-avatar>
-<nut-avatar size="small" icon="https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png"
-></nut-avatar>  
+:::demo
+
+```html
+<template>
+  <nut-avatar
+    size="large"
+    icon="https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png"
+  ></nut-avatar>
+  <nut-avatar
+    size="normal"
+    icon="https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png"
+  ></nut-avatar>
+  <nut-avatar
+    size="small"
+    icon="https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png"
+  ></nut-avatar>
+</template>
 ```
 
+:::
+
 ### 修改形状类型
 
-``` html
-<nut-avatar icon="my" shape="square"></nut-avatar>
-<nut-avatar icon="my" shape="round"></nut-avatar>
+:::demo
+
+```html
+<template>
+  <nut-avatar icon="my" shape="square"></nut-avatar>
+  <nut-avatar icon="my" shape="round"></nut-avatar>
+</template>
 ```
 
+:::
+
 ### 修改背景色
 
-``` html
-<nut-avatar icon="my" bg-color="#FA2C19" />
+:::demo
+
+```html
+<template>
+  <nut-avatar icon="my" bg-color="#FA2C19" />
+</template>
 ```
 
-### 修改背景icon
+:::
+
+### 修改背景 icon
+
+:::demo
 
-``` html
-<nut-avatar icon="https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png" />
+```html
+<template>
+  <nut-avatar
+    icon="https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png"
+  />
+</template>
 ```
 
+:::
+
 ### 设置头像的文本内容
 
-``` html
-<nut-avatar>N</nut-avatar>
+:::demo
+
+```html
+<template>
+  <nut-avatar>N</nut-avatar>
+</template>
 ```
 
+:::
 
 ### Prop
 
-| 字段     | 说明                                                                     | 类型   | 默认值 |
-|----------|--------------------------------------------------------------------------|--------|--------|
-| bg-color | 设置头像背景色                                                           | String | #eee   |
-| size     | 设置头像的大小,提供三种:large/normal/small,支持直接输入数字           | String | normal |
-| shape    | 设置头像的形状,默认是圆形,可以设置为square方形                         | String | round  |
-| icon     | 设置头像的icon图标, 类似Icon组件的name属性,支持名称和链接 | String | ''     |
+| 字段     | 说明                                                             | 类型   | 默认值 |
+| -------- | ---------------------------------------------------------------- | ------ | ------ |
+| bg-color | 设置头像背景色                                                   | String | #eee   |
+| size     | 设置头像的大小,提供三种:large/normal/small,支持直接输入数字   | String | normal |
+| shape    | 设置头像的形状,默认是圆形,可以设置为 square 方形               | String | round  |
+| icon     | 设置头像的 icon 图标, 类似 Icon 组件的 name 属性,支持名称和链接 | String | ''     |
 
 ### Events
 
-| 字段     | 说明                 | 类型     | 回调参数 |
-|----------|----------------------|----------|----------|
-| active-avatarror | 点击触发事件 | Function | event    |
+| 字段             | 说明         | 类型     | 回调参数 |
+| ---------------- | ------------ | -------- | -------- |
+| active-avatarror | 点击触发事件 | Function | event    |

+ 112 - 56
src/packages/__VUE/button/doc.md

@@ -6,7 +6,7 @@
 
 ### 安装
 
-``` javascript
+```javascript
 import { createApp } from 'vue';
 // vue
 import { Button } from '@nutui/nutui';
@@ -23,121 +23,177 @@ app.use(Button);
 
 按钮支持 `default`、`primary`、`info`、`warning`、`danger`、`success` 六种类型,默认为 `default`。
 
+:::demo
+
 ```html
-<nut-button type="primary">主要按钮</nut-button>
-<nut-button type="info">信息按钮</nut-button>
-<nut-button type="default">默认按钮</nut-button>
-<nut-button type="danger">危险按钮</nut-button>
-<nut-button type="warning">警告按钮</nut-button>
-<nut-button type="success">成功按钮</nut-button>
+<template>
+  <nut-button type="primary">主要按钮</nut-button>
+  <nut-button type="info">信息按钮</nut-button>
+  <nut-button type="default">默认按钮</nut-button>
+  <nut-button type="danger">危险按钮</nut-button>
+  <nut-button type="warning">警告按钮</nut-button>
+  <nut-button type="success">成功按钮</nut-button>
+</template>
 ```
 
+:::
+
 ### 朴素按钮
 
 通过 `plain` 属性将按钮设置为朴素按钮,朴素按钮的文字为按钮颜色,背景为白色。
 
+:::demo
+
 ```html
-<nut-button plain type="primary">朴素按钮</nut-button>
-<nut-button plain type="info">朴素按钮</nut-button>
+<template>
+  <nut-button plain type="primary">朴素按钮</nut-button>
+  <nut-button plain type="info">朴素按钮</nut-button>
+</template>
 ```
 
+:::
+
 ### 禁用状态
 
 通过 `disabled` 属性来禁用按钮,禁用状态下按钮不可点击。
 
+:::demo
+
 ```html
-<nut-button disabled type="primary">禁用状态</nut-button>
-<nut-button plain disabled type="info">禁用状态</nut-button>
-<nut-button plain disabled type="primary">禁用状态</nut-button>
+<template>
+  <nut-button disabled type="primary">禁用状态</nut-button>
+  <nut-button plain disabled type="info">禁用状态</nut-button>
+  <nut-button plain disabled type="primary">禁用状态</nut-button>
+</template>
 ```
 
+:::
+
 ### 按钮形状
 
 通过 `shape` 属性设置按钮形状,支持圆形、方形按钮,默认为圆形。
 
+:::demo
+
 ```html
-<nut-button shape="square" type="primary">方形按钮</nut-button>
-<nut-button type="info">圆形按钮</nut-button>
+<template>
+  <nut-button shape="square" type="primary">方形按钮</nut-button>
+  <nut-button type="info">圆形按钮</nut-button>
+</template>
 ```
 
+:::
+
 ### 加载状态
 
-```html
-<nut-button loading type="info"></nut-button>
-<nut-button loading type="warning">加载中...</nut-button>
-<nut-button :loading="isLoading" type="success" @click="changeLoading">Click me!</nut-button>
-```
-``` javascript
-  // ...
-  let isLoading = ref(false);
-  const changeLoading = () => {
-    isLoading.value = true;
-    setTimeout(() => {
-      isLoading.value = false;
-    }, 3000);
-  };
+:::demo
 
-  return {
-    isLoading,
-    changeLoading
+```html
+<template>
+  <nut-button loading type="info"></nut-button>
+  <nut-button loading type="warning">加载中...</nut-button>
+  <nut-button :loading="isLoading" type="success" @click="changeLoading">Click me!</nut-button>
+</template>
+
+<script>
+  import { ref } from 'vue';
+  export default {
+    setup(props) {
+      let isLoading = ref(false);
+      const changeLoading = () => {
+        isLoading.value = true;
+        setTimeout(() => {
+          isLoading.value = false;
+        }, 3000);
+      };
+      return {
+        isLoading,
+        changeLoading
+      };
+    }
   };
-  // ...
+</script>
 ```
 
+:::
+
 ### 图标按钮
 
+:::demo
+
 ```html
+<template>
   <nut-button shape="square" plain type="primary" icon="star-fill"></nut-button>
   <nut-button shape="square" type="primary" icon="star">收藏</nut-button>
+</template>
 ```
 
+:::
+
 ### 按钮尺寸
 
 支持 `large`、`normal`、`small`、`mini` 四种尺寸,默认为 `normal`。
 
+:::demo
+
 ```html
-<nut-button size="large" type="primary">大号按钮</nut-button>
-<nut-button type="primary">普通按钮</nut-button>
-<nut-button size="small" type="primary">小型按钮</nut-button>
-<nut-button size="mini" type="primary">小型按钮</nut-button>
+<template>
+  <nut-button size="large" type="primary">大号按钮</nut-button>
+  <nut-button type="primary">普通按钮</nut-button>
+  <nut-button size="small" type="primary">小型按钮</nut-button>
+  <nut-button size="mini" type="primary">小型按钮</nut-button>
+</template>
 ```
 
+:::
+
 ### 块级元素
 
 按钮在默认情况下为行内块级元素,通过 `block` 属性可以将按钮的元素类型设置为块级元素,常用来实现通栏按钮。
 
+:::demo
+
 ```html
-<nut-button block type="primary">块级元素</nut-button>
+<template>
+  <nut-button block type="primary">块级元素</nut-button>
+</template>
 ```
 
+:::
+
 ### 自定义颜色
+
 通过 color 属性可以自定义按钮的颜色。
+:::demo
+
 ```html
-<nut-button color="#7232dd">单色按钮</nut-button>
-<nut-button color="#7232dd" plain>单色按钮</nut-button>
-<nut-button color="linear-gradient(to right, #ff6034, #ee0a24)">
-  渐变色按钮
-</nut-button>
+<template>
+  <nut-button color="#7232dd">单色按钮</nut-button>
+  <nut-button color="#7232dd" plain>单色按钮</nut-button>
+  <nut-button color="linear-gradient(to right, #ff6034, #ee0a24)"> 渐变色按钮 </nut-button>
+</template>
 ```
+
+:::
+
 ## API
 
 ### Props
 
-| 参数         | 说明                             | 类型   | 默认值           |
-|--------------|----------------------------------|--------|------------------|
-| type         | 类型,可选值为 `primary` `info` `warning` `danger` `success` | String |`default`         |
-| size        | 尺寸,可选值为 `large` `small` `mini`  | String | `normal`      |
-| shape         | 形状,可选值为 `square` | String | `round`             |
-| color | 按钮颜色,支持传入 linear-gradient 渐变色     | String | - |
-| plain          | 	是否为朴素按钮                       | Boolean | `false`             |
-| disabled          | 	是否禁用按钮                       | Boolean | `false`              |
-| block          | 是否为块级元素                        | Boolean | `false`               |
-| icon          | 按钮图标,同Icon组件name属性                        | String | -     |
-| loading          | 按钮loading状态                        | Boolean | `false`               |
+| 参数     | 说明                                                         | 类型    | 默认值    |
+| -------- | ------------------------------------------------------------ | ------- | --------- |
+| type     | 类型,可选值为 `primary` `info` `warning` `danger` `success` | String  | `default` |
+| size     | 尺寸,可选值为 `large` `small` `mini`                        | String  | `normal`  |
+| shape    | 形状,可选值为 `square`                                      | String  | `round`   |
+| color    | 按钮颜色,支持传入 linear-gradient 渐变色                    | String  | -         |
+| plain    | 是否为朴素按钮                                               | Boolean | `false`   |
+| disabled | 是否禁用按钮                                                 | Boolean | `false`   |
+| block    | 是否为块级元素                                               | Boolean | `false`   |
+| icon     | 按钮图标,同 Icon 组件 name 属性                             | String  | -         |
+| loading  | 按钮 loading 状态                                            | Boolean | `false`   |
 
 ### Events
 
-| 事件名 | 说明           | 回调参数     |
-|--------|----------------|--------------|
+| 事件名 | 说明           | 回调参数          |
+| ------ | -------------- | ----------------- |
 | click  | 点击按钮时触发 | event: MouseEvent |
-

+ 124 - 69
src/packages/__VUE/cell/doc.md

@@ -6,133 +6,188 @@
 
 ### 安装
 
-``` javascript
+```javascript
 import { createApp } from 'vue';
-import { Cell,Icon } from '@nutui/nutui';
+import { Cell, Icon } from '@nutui/nutui';
 
 const app = createApp();
 app.use(Cell).use(Icon);
 ```
 
-
 ### 基本用法
 
-``` html
-<nut-cell title="我是标题" desc="描述文字"></nut-cell>
-<nut-cell title="我是标题" sub-title="副标题描述" desc="描述文字"></nut-cell>
-<nut-cell title="点击测试" @click="testClick"></nut-cell>
-<nut-cell title="圆角设置 0" round-radius="0"></nut-cell>
-```
-
-``` javascript
-// ...
-import { ref } from 'vue';
-import { Toast } from '@nutui/nutui';
-export default {
-  setup() {
+:::demo
+
+```html
+<template>
+  <nut-cell title="我是标题" desc="描述文字"></nut-cell>
+  <nut-cell title="我是标题" sub-title="副标题描述" desc="描述文字"></nut-cell>
+  <nut-cell title="点击测试" @click="testClick"></nut-cell>
+  <nut-cell title="圆角设置 0" round-radius="0"></nut-cell>
+</template>
+<script>
+  import { ref } from 'vue';
+  import { Toast } from '@nutui/nutui';
+  export default {
+    setup() {
       const switchChecked = ref(true);
       const testClick = (event) => {
-        Toast.text('点击事件')
+        Toast.text('点击事件');
       };
-      return { testClick,switchChecked };
-  }
-}
-// ...
+      return { testClick, switchChecked };
+    }
+  };
+</script>
 ```
 
+:::
+
 ### 直接使用插槽
 
-``` html
- <nut-cell title="我是标题" desc="描述文字">
-  <div>自定义内容</div>
- </nut-cell>  
+:::demo
+
+```html
+<template>
+  <nut-cell title="我是标题" desc="描述文字">
+    <div>自定义内容</div>
+  </nut-cell>
+</template>
 ```
 
+:::
+
 ### 链接 | 分组用法
 
-``` html
-<nut-cell-group title="链接 | 分组用法" desc="使用 nut-cell-group 支持 title desc slots">
-  <nut-cell title="链接" is-link></nut-cell>
-  <nut-cell title="URL 跳转" desc="https://jd.com" is-link url="https://jd.com"></nut-cell>
-  <nut-cell title="路由跳转 ’/‘ " to="/"></nut-cell>
-</nut-cell-group>
+:::demo
+
+```html
+<template>
+  <nut-cell-group title="链接 | 分组用法" desc="使用 nut-cell-group 支持 title desc slots">
+    <nut-cell title="链接" is-link></nut-cell>
+    <nut-cell title="URL 跳转" desc="https://m.jd.com" is-link url="https://m.jd.com"></nut-cell>
+    <nut-cell title="路由跳转 ’/‘ " to="/"></nut-cell>
+  </nut-cell-group>
+</template>
 ```
 
+:::
+
 ### 自定义右侧箭头区域
 
-``` html
-<nut-cell-group title="自定义右侧箭头区域">
-  <nut-cell title="Switch">
-    <template v-slot:link>
-      <nut-switch v-model="switchChecked" />
-    </template>
-  </nut-cell>
-</nut-cell-group>
+:::demo
+
+```html
+<template>
+  <nut-cell-group title="自定义右侧箭头区域">
+    <nut-cell title="Switch">
+      <template v-slot:link>
+        <nut-switch v-model="switchChecked" />
+      </template>
+    </nut-cell>
+  </nut-cell-group>
+</template>
+<script lang="ts">
+  import { ref } from 'vue';
+  export default {
+    setup() {
+      const testClick = (event: Event) => {
+        console.log('点击事件');
+      };
+      const switchChecked = ref(true);
+      return { testClick, switchChecked };
+    }
+  };
+</script>
 ```
+
+:::
+
 ### 自定义左侧 Icon 区域
 
-``` html
-<nut-cell-group title="自定义左侧 Icon 区域">
-  <nut-cell title="图片">
-    <template v-slot:icon>
-      <img class="nut-icon" src="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png" />
-    </template>
-  </nut-cell>
-</nut-cell-group>
+:::demo
+
+```html
+<template>
+  <nut-cell-group title="自定义左侧 Icon 区域">
+    <nut-cell title="图片">
+      <template v-slot:icon>
+        <img
+          class="nut-icon"
+          src="https://img11.360buyimg.com/imagetools/jfs/t1/137646/13/7132/1648/5f4c748bE43da8ddd/a3f06d51dcae7b60.png"
+        />
+      </template>
+    </nut-cell>
+  </nut-cell-group>
+</template>
 ```
 
+:::
+
 ### 单元格展示图标
 
-``` html
-<nut-cell title="姓名" icon="my" desc="张三"></nut-cell>
+:::demo
+
+```html
+<template>
+  <nut-cell title="姓名" icon="my" desc="张三"></nut-cell>
+</template>
 ```
+
+:::
+
 ### 只展示 desc ,可通过 desc-text-align 调整内容位置
 
-``` html
-<nut-cell desc-text-align="left" desc="张三"></nut-cell>
+:::demo
+
+```html
+<template>
+  <nut-cell desc-text-align="left" desc="张三"></nut-cell>
+</template>
 ```
 
+:::
+
 ## API
 
 ### CellGroup Prop
 
 | 字段  | 说明     | 类型   | 默认值 |
-|-------|----------|--------|--------|
+| ----- | -------- | ------ | ------ |
 | title | 分组标题 | String | -      |
 | desc  | 分组描述 | String | -      |
 
 ### Cell Prop
 
-| 字段                   | 说明                                                                                           | 类型           | 默认值 |
-|------------------------|------------------------------------------------------------------------------------------------|----------------|--------|
-| title                  | 标题名称                                                                                       | String         | -      |
-| sub-title              | 左侧副标题                                                                                     | String         | -      |
-| desc                   | 右侧描述                                                                                       | String         | -      |
-| desc-text-align        | 右侧描述文本对齐方式 [text-align](https://www.w3school.com.cn/cssref/pr_text_text-align.asp)   | String         | right  |
-| is-link                | 是否展示右侧箭头并开启点击反馈                                                                 | Boolean        | false  |
-| icon                   | 左侧 [图标名称](#/icon) 或图片链接                                                             | String         | -      |
-| round-radius           | 圆角半径                                                                                       | Number         | 6px    |
-| url `小程序不支持`     | 点击后跳转的链接地址                                                                           | String         | -      |
-| to   `小程序不支持`    | 点击后跳转的目标路由对象,同 vue-router 的 [to 属性](https://router.vuejs.org/zh/api/#to) 属性 | String|Object | -      |
-| replace `小程序不支持` | 是否在跳转时替换当前页面历史                                                                   | Boolean        | false  |
+| 字段                   | 说明                                                                                           | 类型             | 默认值 |
+| ---------------------- | ---------------------------------------------------------------------------------------------- | ---------------- | ------ |
+| title                  | 标题名称                                                                                       | String           | -      |
+| sub-title              | 左侧副标题                                                                                     | String           | -      |
+| desc                   | 右侧描述                                                                                       | String           | -      |
+| desc-text-align        | 右侧描述文本对齐方式 [text-align](https://www.w3school.com.cn/cssref/pr_text_text-align.asp)   | String           | right  |
+| is-link                | 是否展示右侧箭头并开启点击反馈                                                                 | Boolean          | false  |
+| icon                   | 左侧 [图标名称](#/icon) 或图片链接                                                             | String           | -      |
+| round-radius           | 圆角半径                                                                                       | Number           | 6px    |
+| url `小程序不支持`     | 点击后跳转的链接地址                                                                           | String           | -      |
+| to `小程序不支持`      | 点击后跳转的目标路由对象,同 vue-router 的 [to 属性](https://router.vuejs.org/zh/api/#to) 属性 | String  Object | -      |
+| replace `小程序不支持` | 是否在跳转时替换当前页面历史                                                                   | Boolean          | false  |
 
 ### Cell Event
 
 | 名称  | 说明     | 回调参数    |
-|-------|----------|-------------|
+| ----- | -------- | ----------- |
 | click | 点击事件 | event:Event |
 
-
 ## Cell Slots
 
 | 名称          | 说明                 |
-|---------------|----------------------|
+| ------------- | -------------------- |
 | icon `v3.1.4` | 自定义左侧`icon`区域 |
 | default       | 自定义内容           |
 | link          | 自定义右侧`link`区域 |
 
 ## CellGroup Slots
-| 名称            | 说明                |
-|-----------------|---------------------|
+
+| 名称            | 说明                  |
+| --------------- | --------------------- |
 | title `v3.1.10` | 自定义`title`标题区域 |
 | desc `v3.1.12`  | 自定义`desc`描述区域  |

+ 30 - 0
src/sites/doc/components/demo-block/basedUtil.ts

@@ -0,0 +1,30 @@
+import * as LZUTF8 from 'lzutf8';
+function encodeBase64(str: Uint8Array): any {
+  // @ts-ignore
+  return LZUTF8.encodeBase64(str);
+}
+function decodeBase64(str: string): any {
+  // @ts-ignore
+  return LZUTF8.decodeBase64(str);
+}
+
+export function compressText(str: string): any {
+  // @ts-ignore
+  return encodeBase64(LZUTF8.compress(str, { outputEncoding: 'ByteArray' }));
+}
+export function decompressText(str: string): any {
+  // @ts-ignore
+  return LZUTF8.decompress(decodeBase64(str));
+}
+
+export function copyCodeHtml(code: string, callback: any): void {
+  const oInput = document.createElement('input');
+  oInput.value = code;
+  document.body.appendChild(oInput);
+  oInput.select(); // 选择对象
+  document.execCommand('Copy'); // 执行浏览器复制命令
+  oInput.className = 'oInput';
+  oInput.style.display = 'none';
+  oInput.setSelectionRange(0, 9999);
+  callback();
+}

+ 47 - 0
src/sites/doc/components/demo-block/demoBlock.scss

@@ -0,0 +1,47 @@
+.online-part {
+  display: flex;
+  justify-content: center;
+  margin-top: 0px;
+  border: 1px solid #eee;
+  border-top: 0px;
+  width: 100%;
+  height: 35px;
+  .list {
+    list-style-type: none;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex: 0.5;
+    border-top: 1px dashed #eee;
+    border-right: 1px solid #eee;
+    position: relative;
+    &:last-child {
+      border-right: 0px;
+      border-left: 0px;
+    }
+    &:hover {
+      background-color: #eee;
+      cursor: pointer;
+      & .online-tips {
+        display: block;
+      }
+    }
+    .online-icon {
+      width: 20px;
+      height: 20px;
+    }
+    .online-tips {
+      display: none;
+      position: absolute;
+      top: 0px;
+      left: 53%;
+      padding: 2px 6px;
+      background-color: #333;
+      color: #fff;
+      font-size: 12px;
+      border-top-right-radius: 10px;
+      border-bottom-right-radius: 10px;
+      border-top-left-radius: 10px;
+    }
+  }
+}

+ 64 - 22
src/sites/doc/components/demo-block/demoBlock.vue

@@ -1,33 +1,75 @@
 <template>
-  <div>
-    <slot name="highlight"></slot>
+  <div class="online-code" ref="onlineCode">
     <slot></slot>
-    <p class="online-part">
-      <a href="//gitpod.io/#https://github.com/jdf2e/nutui.git" target="_blank" class="online-btn">在线运行</a>
-    </p>
+    <div class="online-part">
+      <a class="list" :href="jumpHref" target="_blank">
+        <img
+          class="online-icon"
+          src="https://img12.360buyimg.com/imagetools/jfs/t1/214225/34/8715/7002/61c31bf1E69324ee9/7a452063eba88be4.png"
+        />
+        <div class="online-tips">在线调试</div>
+      </a>
+      <div class="list" @click="copyCode">
+        <img
+          class="online-icon"
+          src="https://img10.360buyimg.com/imagetools/jfs/t1/142615/10/25537/3671/61c31e6eE3ba7fb90/d1953e2b47e40e86.png"
+        />
+        <div class="online-tips">复制代码</div>
+      </div>
+    </div>
   </div>
 </template>
 <script>
+import { ref, getCurrentInstance, onMounted, computed } from 'vue';
+import { compressText, copyCodeHtml, decompressText } from './basedUtil';
 export default {
-  setup() {
-    function onlineFun() {
-      alert('hello');
-    }
+  setup(props, ctx) {
+    const sourceMainReactJsStr = `//import VConsole from "vconsole";
+//var vConsole = new VConsole();
+import React from "react";
+import ReactDOM from "react-dom";
+import '@nutui/nutui-react/dist/style.css'
+import App from "./app.jsx";
+import "./app.scss";
+ReactDOM.render(
+  <App/>,
+  document.getElementById("app")
+);`;
+    const sourceMainJsStr = `//import VConsole from "vconsole";
+//var vConsole = new VConsole();
+import { createApp } from "vue";
+import App from "./app.vue";
+import NutUI from "@nutui/nutui";
+import "./app.scss";
+import "@nutui/nutui/dist/style.css";
+createApp(App).use(NutUI).mount("#app");`;
+
+    const onlineCode = ref(null);
+    const sourceMainJs = compressText(sourceMainJsStr);
+    const mainJs = ref(sourceMainJs);
+
+    const sourceMainReactJs = compressText(sourceMainReactJsStr);
+    const mainReactJs = ref(sourceMainReactJs);
+
+    const jumpHref = ref(``);
+    onMounted(() => {
+      if (onlineCode.value.dataset.type === 'react') {
+        jumpHref.value = `https://codehouse.jd.com/?source=share&type=react&mainJs=${mainReactJs.value}&appValue=${onlineCode.value.dataset.value}&scssValue=`;
+      } else {
+        jumpHref.value = `https://codehouse.jd.com/?source=share&type=vue&mainJs=${mainJs.value}&appValue=${onlineCode.value.dataset.value}&scssValue=`;
+      }
+    });
+    const copyCode = () => {
+      const sourceValue = decompressText(onlineCode.value.dataset.value);
+      copyCodeHtml(sourceValue, () => {
+        alert('复制成功');
+      });
+    };
     return {
-      onlineFun
+      jumpHref,
+      onlineCode,
+      copyCode
     };
   }
 };
 </script>
-<style lang="scss" scoped>
-.online-part {
-  display: flex;
-  justify-content: flex-end;
-  .online-btn {
-    display: block;
-    padding: 10px;
-    background: #eee;
-    cursor: pointer;
-  }
-}
-</style>

+ 1 - 0
src/sites/doc/components/demo-block/index.ts

@@ -1,2 +1,3 @@
 import DemoBlock from './demoBlock.vue';
+import './demoBlock.scss';
 export default DemoBlock;

+ 20 - 0
vite.config.ts

@@ -5,6 +5,7 @@ import Markdown from 'vite-plugin-md';
 import path from 'path';
 import config from './package.json';
 const hljs = require('highlight.js'); // https://highlightjs.org/
+import { compressText } from './src/sites/doc/components/demo-block/basedUtil';
 const resolve = path.resolve;
 // https://vitejs.dev/config/
 export default defineConfig({
@@ -56,6 +57,25 @@ export default defineConfig({
 
           return ''; // 使用额外的默认转义
         }
+      },
+      markdownItSetup(md) {
+        md.use(require('markdown-it-container'), 'demo', {
+          validate: function (params) {
+            return params.match(/^demo\s*(.*)$/);
+          },
+
+          render: function (tokens, idx) {
+            const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
+            if (tokens[idx].nesting === 1) {
+              // opening tag
+              const contentHtml = compressText(tokens[idx + 1].content);
+              return `<demo-block data-type="vue" data-value="${contentHtml}">` + md.utils.escapeHtml(m[1]) + '\n';
+            } else {
+              // closing tag
+              return '</demo-block>\n';
+            }
+          }
+        });
       }
     })
     // legacy({