浏览代码

docs(fixednav、rate、tabs、uploader): 增加在线调试功能

richard1015 3 年之前
父节点
当前提交
18eca550af

+ 19 - 9
src/packages/__VUE/fixednav/doc.md

@@ -21,10 +21,14 @@ app.use(FixedNav);
 
 ### 基础用法
 
-``` html
-<nut-fixednav :position="{top:'70px' }" v-model:visible="visible" :nav-list="navList" />
-```
-``` javascript
+:::demo
+```html
+<template>
+  <nut-fixednav :position="{top:'70px' }" v-model:visible="visible" :nav-list="navList" />
+</template>
+<script lang="ts">
+import { ref,reactive } from 'vue';
+export default {
  setup() {
     const visible = ref(false);
     const navList = reactive([
@@ -55,8 +59,9 @@ app.use(FixedNav);
       navList
     };
  }
+}
 ```
-
+:::
 
 ### 左侧效果
 
@@ -81,7 +86,9 @@ app.use(FixedNav);
 
 ### 自定义使用
 
-``` html
+:::demo
+```html
+<template>
 <nut-fixednav :position="{top:'280px' }" type="left" v-model:visible="myActive">
     <template v-slot:list>
         <ul class="nut-fixednav__list">
@@ -98,9 +105,10 @@ app.use(FixedNav);
     <span class="text">{{ myActive ? '自定义开' : '自定义关' }}</span>
 </template>
 </nut-fixednav>
-```
-
-``` javascript
+</template>
+<script lang="ts">
+import { ref,reactive } from 'vue';
+export default {
  setup() {
     const myActive = ref(false);
     const navList = reactive([
@@ -131,7 +139,9 @@ app.use(FixedNav);
       navList
     };
  }
+}
 ```
+:::
 
 
 ### Prop

+ 129 - 27
src/packages/__VUE/rate/doc.md

@@ -22,67 +22,169 @@ app.use(Icon);
 
 ### 基础用法
 
-``` html
-<nut-rate v-model="value" />
+:::demo
+```html
+<template>
+    <nut-rate v-model="value" />
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+    setup() {
+        const value = ref(3);
+        return { value }
+    }
+}
 ```
+:::
 
-``` javascript
+### 半星
+
+:::demo
+```html
+<template>
+    <nut-rate allow-half v-model="value"></nut-rate>
+</template>
+<script lang="ts">
 import { ref } from 'vue';
-setup() {
-    const value = ref(3);
-    return { value }
+export default {
+    setup() {
+        const value = ref(3.5);
+        return { value }
+    }
 }
 ```
+:::
 
 ### 自定义icon
 
-``` html
-<nut-rate checked-icon="heart-fill1" unchecked-icon="heart" v-model="value" />
+:::demo
+```html
+<template>
+    <nut-rate checked-icon="heart-fill1" unchecked-icon="heart" v-model="value" />
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+    setup() {
+        const value = ref(3);
+        return { value }
+    }
+}
 ```
+:::
 
 ### 自定义数量
 
-``` html
-<nut-rate :total="6" v-model="value" />
+:::demo
+```html
+<template>
+    <nut-rate :count="6" v-model="value" />
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+    setup() {
+        const value = ref(3);
+        return { value }
+    }
+}
 ```
+:::
 
 ### 自定义颜色
 
-``` html
-<nut-rate active-color="#FFC800" v-model="value" />
+:::demo
+```html
+<template>
+    <nut-rate active-color="#FFC800" v-model="value" />
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+    setup() {
+        const value = ref(3);
+        return { value }
+    }
+}
 ```
+:::
 
 ### 禁用状态
 
-``` html
-<nut-rate disabled v-model="value" />
+:::demo
+```html
+<template>
+    <nut-rate disabled v-model="value" />
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+    setup() {
+        const value = ref(3);
+        return { value }
+    }
+}
 ```
+:::
 
 ### 只读
 
-``` html
-<nut-rate v-model="value" readOnly />
+:::demo
+```html
+<template>
+    <nut-rate v-model="value" readonly />
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+    setup() {
+        const value = ref(3);
+        return { value }
+    }
+}
 ```
+:::
 ### 绑定事件
 
-``` html
-<nut-rate v-model="value" @change="onChange" />
-```
-``` javascript
+:::demo
+```html
+<template>
+    <nut-rate v-model="value" @change="onChange" />
+</template>
+<script lang="ts">
 import { ref } from 'vue';
-setup() {
-    const value = ref(3);
-    const onChange = (val)=>{
-        Toast.text(val);
+import { Toast } from '@nutui/nutui';
+export default {
+    setup() {
+        const value = ref(3);
+        const onChange = (val)=>{
+            Toast.text(val);
+        }
+    return { value,onChange }
     }
-    return { value }
 }
 ```
+:::
+
 ### 自定义尺寸
 
-``` html
-<nut-rate v-model="value" icon-size="35" />
+:::demo
+```html
+<template>
+    <nut-rate v-model="value" icon-size="35" />
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+import { Toast } from '@nutui/nutui';
+export default {
+    setup() {
+        const value = ref(3);
+        return { value }
+    }
+}
 ```
+:::
 
 
 

+ 151 - 47
src/packages/__VUE/tabs/doc.md

@@ -19,8 +19,9 @@ app.use(TabPane);
 ```
 
 ### 基础用法
-
-``` html
+:::demo
+```html
+<template>
 <nut-tabs v-model="state.tab1value">
   <nut-tabpane title="Tab 1">
     Tab 1
@@ -32,55 +33,24 @@ app.use(TabPane);
     Tab 3
   </nut-tabpane>
 </nut-tabs>
-```
-
-``` javascript
+</template>
+<script lang="ts">
 import { reactive } from 'vue';
 export default {
-  props: {},
   setup() {
     const state = reactive({
       tab1value: '0',
-      tab11value: '0',
-      tab2value: '0',
-      tab3value: '0',
-      tab4value: '0',
-      tab5value: '0',
-      tab6value: '0',
-      tab7value: 'c1',
-      list3: Array.from(new Array(2).keys()),
-      list4: Array.from(new Array(10).keys()),
-      list5: Array.from(new Array(2).keys()),
-      list6: [
-        {
-          title: '自定义 1',
-          paneKey: 'c1',
-          icon: 'dongdong'
-        },
-        {
-          title: '自定义 2',
-          paneKey: 'c2',
-          icon: 'JD'
-        },
-        {
-          title: '自定义 3',
-          paneKey: 'c3'
-        }
-      ]
     });
-    setTimeout(() => {
-      state.list3.push(999);
-      state.tab3value = '2';
-    }, 3000);
-
     return { state };
   }
 };
 ```
+:::
 
 ### 基础用法-微笑曲线
-
-``` html
+:::demo
+```html
+<template>
 <nut-tabs v-model="state.tab11value" type="smile">
   <nut-tabpane title="Tab 1">
     Tab 1
@@ -92,11 +62,25 @@ export default {
     Tab 3
   </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab11value: '0',
+    });
+    return { state };
+  }
+};
 ```
+:::
 
 ### 通过 pane-key 匹配
 
-``` html
+:::demo
+```html
+<template>
 <nut-tabs v-model="state.tab2value">
   <nut-tabpane title="Tab 1" pane-key="0">
     Tab 1
@@ -108,50 +92,128 @@ export default {
     Tab 3
   </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab2value: '0',
+    });
+    return { state };
+  }
+};
 ```
+:::
 
 ### 数据异步渲染 3s
 
-``` html
+:::demo
+```html
+<template>
 <nut-tabs v-model="state.tab3value">
   <nut-tabpane v-for="item in state.list3" :title="'Tab '+ item">
     Tab {{item}}
   </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab3value: '0',
+      list3: Array.from(new Array(2).keys()),
+    });
+    setTimeout(() => {
+      state.list3.push(999);
+      state.tab3value = '2';
+    }, 3000);
+    return { state };
+  }
+};
 ```
+:::
 
 ### 数量多,滚动操作
 
-``` html
+:::demo
+```html
+<template>
 <nut-tabs v-model="state.tab4value" title-scroll title-gutter="10">
   <nut-tabpane v-for="item in state.list4" :title="'Tab '+ item">
     Tab {{item}}
   </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab1value: '0',
+      list4: Array.from(new Array(10).keys()),
+    });
+    return { state };
+  }
+};
 ```
+:::
 
 ### 左右布局
 
-``` html
+:::demo
+```html
+<template>
 <nut-tabs style="height:300px" v-model="state.tab5value" title-scroll direction="vertical">
   <nut-tabpane v-for="item in state.list5" :title="'Tab '+ item">
     Tab {{item}}
   </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab5value: '0',
+      list5: Array.from(new Array(2).keys()),
+    });
+    return { state };
+  }
+};
 ```
+:::
 
 ### 左右布局-微笑曲线
 
-``` html
-<nut-tabs style="height:300px" v-model="state.tab5value" title-scroll direction="vertical">
+:::demo
+```html
+<template>
+<nut-tabs style="height:300px" v-model="state.tab6value" type="smile" title-scroll direction="vertical">
   <nut-tabpane v-for="item in state.list5" :title="'Tab '+ item">
     Tab {{item}}
   </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab6value: '0',
+      list5: Array.from(new Array(2).keys()),
+    });
+    return { state };
+  }
+};
 ```
+:::
 
 ### 标签栏字体尺寸 large normal small
-``` html
+:::demo
+```html
+<template>
 <nut-tabs v-model="state.tab1value" size="large">
   <nut-tabpane title="Tab 1"> Tab 1 </nut-tabpane>
   <nut-tabpane title="Tab 2"> Tab 2 </nut-tabpane>
@@ -167,10 +229,24 @@ export default {
   <nut-tabpane title="Tab 2"> Tab 2 </nut-tabpane>
   <nut-tabpane title="Tab 3"> Tab 3 </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab1value: '0',
+    });
+    return { state };
+  }
+};
 ```
+:::
 
 ### 自定义标签栏
-``` html
+:::demo
+```html
+<template>
 <nut-tabs v-model="state.tab7value">
   <template v-slot:titles>
     <div class="nut-tabs__titles-item" @click="state.tab7value=item.paneKey"
@@ -184,7 +260,35 @@ export default {
     {{item.title}}
   </nut-tabpane>
 </nut-tabs>
+</template>
+<script lang="ts">
+import { reactive } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      tab7value: 'c1',
+       list6: [
+        {
+          title: '自定义 1',
+          paneKey: 'c1',
+          icon: 'dongdong'
+        },
+        {
+          title: '自定义 2',
+          paneKey: 'c2',
+          icon: 'JD'
+        },
+        {
+          title: '自定义 3',
+          paneKey: 'c3'
+        }
+      ]
+    });
+    return { state };
+  }
+};
 ```
+:::
 
 ## API
 

+ 4 - 4
src/packages/__VUE/uploader/demo.vue

@@ -29,9 +29,8 @@
     <nut-uploader :url="uploadUrl" multiple maximum="5"></nut-uploader>
     <h2>限制上传大小(每个文件最大不超过 50kb)</h2>
     <nut-uploader :url="uploadUrl" multiple :maximize="1024 * 50" @oversize="onOversize"></nut-uploader>
-    <h2>限制上传大小(在beforeupload钩子中处理)</h2>
-    <nut-uploader :url="uploadUrl" multiple :before-upload="beforeUpload" :maximize="1024 * 50" @oversize="onOversize">
-    </nut-uploader>
+    <h2>图片压缩(在 beforeupload 钩子中处理)</h2>
+    <nut-uploader :url="uploadUrl" multiple :before-upload="beforeUpload"> </nut-uploader>
     <h2>自定义数据 FormData 、 headers </h2>
     <nut-uploader :url="uploadUrl" :data="formData" :headers="formData" :with-credentials="true"></nut-uploader>
     <h2>选中文件后,通过按钮手动执行上传 </h2>
@@ -106,6 +105,7 @@ export default createDemo({
       console.log('progress 事件触发', percentage);
     };
     const beforeUpload = async (file: File[]) => {
+      let fileName = file[0].name;
       const canvas = document.createElement('canvas');
       const context = canvas.getContext('2d') as CanvasRenderingContext2D;
       const base64 = await fileToDataURL(file[0]);
@@ -117,7 +117,7 @@ export default createDemo({
       context.drawImage(img, 0, 0, img.width, img.height);
 
       let blob = (await canvastoFile(canvas, 'image/jpeg', 0.5)) as Blob; //quality:0.5可根据实际情况计算
-      const f = await new File([blob], file[0].name);
+      const f = await new File([blob], fileName);
       return [f];
     };
     const uploadRef = ref<any>(null);

+ 263 - 128
src/packages/__VUE/uploader/doc.md

@@ -20,168 +20,303 @@ app.use(Progress);
 
 ### 基本用法
 
-``` html
-<nut-uploader :url="uploadUrl"></nut-uploader>
+:::demo
+```html
+<template>
+  <nut-uploader url="https://xxxx"></nut-uploader>
+</template>
 ```
+:::
 ### 上传状态
 
-``` html
-<nut-uploader :url="uploadUrl" v-model:file-list="defaultFileList" maximum="3" multiple></nut-uploader>
+:::demo
+```html
+<template>
+  <nut-uploader :url="uploadUrl" v-model:file-list="defaultFileList" maximum="3" multiple></nut-uploader>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+     const uploadUrl = 'https://xxxxx';
+     const defaultFileList = ref([
+      {
+        name: '文件1.png',
+        url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
+        status: 'success',
+        message: '上传成功',
+        type: 'image'
+      },
+      {
+        name: '文件2.png',
+        url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
+        status: 'error',
+        message: '上传失败',
+        type: 'image'
+      },
+      {
+        name: '文件3.png',
+        url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
+        status: 'uploading',
+        message: '上传中...',
+        type: 'image'
+      }
+    ]);
+     return {
+      uploadUrl,
+      defaultFileList
+    };
+  }
+}
 ```
+:::
 ### 基础用法-上传列表展示
 
-``` html
-<nut-uploader :url="uploadUrl" v-model:file-list="defaultFileList" maximum="10" multiple list-type='list'>
-  <nut-button type="success" size="small">上传文件</nut-button>
-</nut-uploader>
+:::demo
+```html
+<template>
+  <nut-uploader :url="uploadUrl" v-model:file-list="defaultFileList" maximum="10" multiple list-type='list'>
+    <nut-button type="success" size="small">上传文件</nut-button>
+  </nut-uploader>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+     const uploadUrl = 'https://xxxxx';
+     const defaultFileList = ref([
+      {
+        name: '文件1.png',
+        url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
+        status: 'success',
+        message: '上传成功',
+        type: 'image'
+      },
+      {
+        name: '文件2.png',
+        url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
+        status: 'error',
+        message: '上传失败',
+        type: 'image'
+      },
+      {
+        name: '文件3.png',
+        url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
+        status: 'uploading',
+        message: '上传中...',
+        type: 'image'
+      }
+    ]);
+     return {
+      uploadUrl,
+      defaultFileList
+    };
+  }
+}
 ```
+:::
 
 ### 自定义上传样式
 
-``` html
-<nut-uploader :url="uploadUrl">
-  <nut-button type="success" size="small">上传文件</nut-button>
-</nut-uploader>
+:::demo
+```html
+<template>
+  <nut-uploader url="https://xxxx">
+    <nut-button type="success" size="small">上传文件</nut-button>
+  </nut-uploader>
+</template>
 ```
+:::
 ### 自定义上传使用默认进度条
 
-``` html
-<nut-uploader :url="uploadUrl" @progress="onProgress">
-  <nut-button type="success" size="small">上传文件</nut-button>
-</nut-uploader>
-<br />
-<nut-progress :percentage="progressPercentage"
-  stroke-color="linear-gradient(270deg, rgba(18,126,255,1) 0%,rgba(32,147,255,1) 32.815625%,rgba(13,242,204,1) 100%)"
-  :status="progressPercentage==100?'':'active'">
-</nut-progress>
+:::demo
+```html
+<template>
+  <nut-uploader :url="uploadUrl" @progress="onProgress">
+    <nut-button type="success" size="small">上传文件</nut-button>
+  </nut-uploader>
+  <br />
+  <nut-progress :percentage="progressPercentage"
+    stroke-color="linear-gradient(270deg, rgba(18,126,255,1) 0%,rgba(32,147,255,1) 32.815625%,rgba(13,242,204,1) 100%)"
+    :status="progressPercentage==100?'':'active'">
+  </nut-progress>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+     const uploadUrl = 'https://xxxxx';
+     const progressPercentage = ref<string | number>(0);
+     const onProgress = ({ event, options, percentage }: any) => {
+        progressPercentage.value = percentage;
+        console.log('progress 事件触发', percentage);
+     };
+     return {
+      uploadUrl,
+      onProgress,
+      progressPercentage,
+    };
+  }
+}
 ```
+:::
 
 ### 直接调起摄像头(移动端生效)
     
-``` html
-<nut-uploader :url="uploadUrl" capture></nut-uploader>
+:::demo
+```html
+<template>
+  <nut-uploader url="https://xxxx" capture></nut-uploader>
+</template>
 ```
+:::
 ### 限制上传数量5个
 
-``` html
-<nut-uploader :url="uploadUrl" multiple maximum="5"></nut-uploader>
+:::demo
+```html
+<template>
+  <nut-uploader url="https://xxxx" multiple maximum="5"></nut-uploader>
+</template>
 ```
-### 限制上传大小(每个文件最大不超过 50kb,也可以在beforeupload中自行处理文件图片压缩)
+:::
 
-``` html
-<nut-uploader :url="uploadUrl" multiple :maximize="1024 * 50" :before-upload="beforeUpload" @oversize="onOversize"></nut-uploader>
+### 限制上传大小(每个文件最大不超过 50kb)
+
+:::demo
+```html
+<template>
+  <nut-uploader :url="uploadUrl" multiple :maximize="1024 * 50" @oversize="onOversize"></nut-uploader>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+      const uploadUrl = 'https://xxxxx';
+      const onOversize = (files: File[]) => {
+        console.log('oversize 触发 文件大小不能超过 50kb', files);
+      };
+     return {
+      uploadUrl,
+      onOversize,
+    };
+  }
+}
 ```
+:::
+### 图片压缩(在 beforeupload 钩子中处理)
+
+:::demo
+```html
+<template>
+  <nut-uploader :url="uploadUrl" multiple :before-upload="beforeUpload"></nut-uploader>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+      const uploadUrl = 'https://xxxxx';
+      const fileToDataURL = (file: Blob): Promise<any> => {
+        return new Promise((resolve) => {
+          const reader = new FileReader();
+          reader.onloadend = (e) => resolve((e.target as FileReader).result);
+          reader.readAsDataURL(file);
+        });
+      };
+      const dataURLToImage = (dataURL: string): Promise<HTMLImageElement> => {
+        return new Promise((resolve) => {
+          const img = new Image();
+          img.onload = () => resolve(img);
+          img.src = dataURL;
+        });
+      };
+      const canvastoFile = (canvas: HTMLCanvasElement, type: string, quality: number): Promise<Blob | null> => {
+        return new Promise((resolve) => canvas.toBlob((blob) => resolve(blob), type, quality));
+      };
+      const beforeUpload = async (file: File[]) => {
+        let fileName = file[0].name;
+        const canvas = document.createElement('canvas');
+        const context = canvas.getContext('2d') as CanvasRenderingContext2D;
+        const base64 = await fileToDataURL(file[0]);
+        const img = await dataURLToImage(base64);
+        canvas.width = img.width;
+        canvas.height = img.height;
+
+        context.clearRect(0, 0, img.width, img.height);
+        context.drawImage(img, 0, 0, img.width, img.height);
+
+        let blob = (await canvastoFile(canvas, 'image/jpeg', 0.5)) as Blob; //quality:0.5可根据实际情况计算
+        const f = await new File([blob], fileName);
+        return [f];
+      };
+     return {
+      uploadUrl,
+      beforeUpload,
+    };
+  }
+}
+```
+:::
 
 ### 自定义 FormData headers
 
-``` html
-<nut-uploader :url="uploadUrl" :data="formData" :headers="formData" :with-Credentials="true"></nut-uploader>
+:::demo
+```html
+<template>
+  <nut-uploader :url="uploadUrl" :data="formData" :headers="formData" :with-credentials="true"></nut-uploader>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+    const uploadUrl = 'https://xxxxx';
+    const formData = {
+      custom: 'test'
+    };
+    return {
+      uploadUrl,
+      formData
+    };
+  }
+}
 ```
+:::
 ### 选中文件后,通过按钮手动执行上传
     
-``` html 
-<nut-uploader :url="uploadUrl" maximum="5" :auto-upload="false" ref="uploadRef"></nut-uploader>
-<br />
-<nut-button type="success" size="small" @click="submitUpload">执行上传</nut-button>
+:::demo
+```html
+<template>
+  <nut-uploader :url="uploadUrl" maximum="5" :auto-upload="false" ref="uploadRef"></nut-uploader>
+  <br />
+  <nut-button type="success" size="small" @click="submitUpload">执行上传</nut-button>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+    const uploadUrl = 'https://xxxxx';
+    const uploadRef = ref<any>(null);
+    const submitUpload = () => {
+      uploadRef.value.submit();
+    };
+    return {
+      uploadUrl,
+      uploadRef,
+      submitUpload
+    };
+  }
+}
 ```
+:::
 
 ### 禁用状态
 
-``` html
-<nut-uploader disabled></nut-uploader>
-```
-
-``` javascript
-import { ref } from 'vue';
-setup() {
-  const uploadUrl = 'http://服务器地址';
-  const progressPercentage = ref<string | number>(0);
-  const formData = {
-    custom: 'test'
-  };
-  const defaultFileList = ref([
-    {
-      name: '文件1.png',
-      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
-      status: 'success',
-      message: '上传成功',
-      type: 'image'
-    },
-    {
-      name: '文件2.png',
-      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
-      status: 'error',
-      message: '上传失败',
-      type: 'image'
-    },
-    {
-      name: '文件3.png',
-      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
-      status: 'uploading',
-      message: '上传中...',
-      type: 'image'
-    }
-  ]);
-  const fileToDataURL = (file: Blob): Promise<any> => {
-    return new Promise((resolve) => {
-      const reader = new FileReader();
-      reader.onloadend = (e) => resolve((e.target as FileReader).result);
-      reader.readAsDataURL(file);
-    });
-  };
-  const dataURLToImage = (dataURL: string): Promise<HTMLImageElement> => {
-    return new Promise((resolve) => {
-      const img = new Image();
-      img.onload = () => resolve(img);
-      img.src = dataURL;
-    });
-  };
-  const canvastoFile = (canvas: HTMLCanvasElement, type: string, quality: number): Promise<Blob | null> => {
-    return new Promise((resolve) => canvas.toBlob((blob) => resolve(blob), type, quality));
-  };
-  const onOversize = (files: File[]) => {
-    console.log('oversize 触发 文件大小不能超过 50kb', files);
-  };
-  const onDelete = (file: FileItem, fileList: FileItem[]) => {
-    console.log('delete 事件触发', file, fileList);
-  };
-  const onProgress = ({ event, options, percentage }: any) => {
-    progressPercentage.value = percentage;
-    console.log('progress 事件触发', percentage);
-  };
-  const beforeUpload = async (file: File[]) => {
-    const canvas = document.createElement('canvas');
-    const context = canvas.getContext('2d') as CanvasRenderingContext2D;
-    const base64 = await fileToDataURL(file[0]);
-    const img = await dataURLToImage(base64);
-    canvas.width = img.width;
-    canvas.height = img.height;
-
-    context.clearRect(0, 0, img.width, img.height);
-    context.drawImage(img, 0, 0, img.width, img.height);
-
-    let blob = (await canvastoFile(canvas, 'image/jpeg', 0.5)) as Blob; //quality:0.5可根据实际情况计算
-    const f = await new File([blob], file[0].name);
-    return [f];
-  };
-  const uploadRef = ref<any>(null);
-  const submitUpload = () => {
-    uploadRef.value.submit();
-  };
-  return {
-    onOversize,
-    beforeUpload,
-    onDelete,
-    onProgress,
-    progressPercentage,
-    uploadUrl,
-    defaultFileList,
-    formData,
-    uploadRef,
-    submitUpload
-  };
-}
+:::demo
+```html
+<template>
+  <nut-uploader disabled></nut-uploader>
+</template>
 ```
+:::
 
 ### Prop