Browse Source

Merge branches 'v4' and 'v4' of https://github.com/jdf2e/nutui into v4

suzigang 3 years ago
parent
commit
d2e2f1d258
31 changed files with 384 additions and 328 deletions
  1. 8 4
      src/packages/__VUE/address/demo.vue
  2. 53 49
      src/packages/__VUE/address/doc.en-US.md
  3. 52 58
      src/packages/__VUE/address/doc.md
  4. 3 3
      src/packages/__VUE/address/index.scss
  5. 20 61
      src/packages/__VUE/address/index.vue
  6. 0 3
      src/packages/__VUE/audio/__tests__/audio.spec.ts
  7. 32 12
      src/packages/__VUE/audio/demo.vue
  8. 42 17
      src/packages/__VUE/audio/doc.en-US.md
  9. 37 12
      src/packages/__VUE/audio/doc.md
  10. 5 3
      src/packages/__VUE/audio/index.vue
  11. 5 5
      src/packages/__VUE/comment/components/CmtBottom.vue
  12. 3 2
      src/packages/__VUE/comment/components/CmtImages.vue
  13. 5 2
      src/packages/__VUE/comment/demo.vue
  14. 4 4
      src/packages/__VUE/comment/doc.en-US.md
  15. 4 4
      src/packages/__VUE/comment/doc.md
  16. 1 3
      src/packages/__VUE/comment/index.scss
  17. 7 6
      src/packages/__VUE/comment/index.vue
  18. 14 12
      src/packages/__VUE/image/__tests__/image.spec.ts
  19. 9 2
      src/packages/__VUE/image/demo.vue
  20. 4 2
      src/packages/__VUE/image/doc.en-US.md
  21. 4 2
      src/packages/__VUE/image/doc.md
  22. 7 3
      src/packages/__VUE/image/index.vue
  23. 38 32
      src/packages/__VUE/infiniteloading/demo.vue
  24. 3 3
      src/packages/__VUE/infiniteloading/doc.en-US.md
  25. 3 3
      src/packages/__VUE/infiniteloading/doc.md
  26. 5 2
      src/packages/__VUE/infiniteloading/index.scss
  27. 5 6
      src/packages/__VUE/infiniteloading/index.vue
  28. 3 2
      src/packages/__VUE/sidenavbar/__tests__/index.spec.ts
  29. 1 4
      src/packages/__VUE/sidenavbar/demo.vue
  30. 1 1
      src/packages/__VUE/sidenavbar/index.vue
  31. 6 6
      src/packages/__VUE/subsidenavbar/index.vue

+ 8 - 4
src/packages/__VUE/address/demo.vue

@@ -69,10 +69,13 @@
       @close="close3"
       :is-show-custom-address="false"
       @selected="selected"
-      :default-icon="defaultIcon"
-      :selected-icon="selectedIcon"
-      :close-btn-icon="closeBtnIcon"
     >
+      <template #unselectedIcon>
+        <Heart1 style="margin-right: 8px"></Heart1>
+      </template>
+      <template #icon>
+        <HeartFill style="margin-right: 8px" color="#f00"></HeartFill>
+      </template>
       <template #bottom>
         <div class="nut-address-custom-buttom">
           <div class="btn">自定义按钮</div>
@@ -91,7 +94,6 @@
       :city="city"
       :country="country"
       :town="town"
-      :back-btn-icon="backBtnIcon"
       @change="(cal) => onChange(cal, 'other')"
       @close="close4"
       @selected="selected"
@@ -106,6 +108,7 @@ import { createComponent } from '@/packages/utils/create';
 import { onMounted, reactive, ref, toRefs } from 'vue';
 import { useTranslate } from '@/sites/assets/util/useTranslate';
 const { createDemo, translate } = createComponent('address');
+import { HeartFill, Heart1, Close } from '@nutui/icons-vue';
 
 const initTranslate = () =>
   useTranslate({
@@ -165,6 +168,7 @@ interface AddressResult extends AddressList {
 }
 export default createDemo({
   props: {},
+  components: { HeartFill, Heart1, Close },
   setup() {
     initTranslate();
     const address = reactive({

+ 53 - 49
src/packages/__VUE/address/doc.en-US.md

@@ -2,7 +2,7 @@
 
 ### Intro
 
-Load on demand Load the  Icon、Popup、Elevator dependent component
+Load on demand Load the Popup、Elevator dependent component
 
 ### Install
 
@@ -327,22 +327,27 @@ If you want to select a province, you need to set the region ID in the order of
       @close="close"
       :is-show-custom-address="false"
       @selected="selected3"
-      :default-icon="defaultIcon"
-      :selected-icon="selectedIcon"
-      :close-btn-icon="closeBtnIcon"
-  ></nut-address>
+  >
+    <template #unselectedIcon>
+      <Heart1 style="margin-right:8px"></Heart1>
+    </template>
+    <template #icon>
+      <HeartFill style="margin-right:8px" color="#f00"></HeartFill>
+    </template>
+    <template #bottom>
+        <div class="nut-address-custom-buttom">
+          <div class="btn">自定义按钮</div>
+        </div>
+    </template>
+  </nut-address>
 </template>
 <script>
   import { ref,reactive,toRefs } from 'vue';
+  import { HeartFill, Heart1} from '@nutui/icons-vue';
   export default {
+    components:{HeartFill, Heart1 },
     setup() {
         const showPopupCustomImg = ref(false);
-        const icon = reactive({
-          selectedIcon: 'heart-fill',
-          defaultIcon: 'heart1',
-          closeBtnIcon: 'close',
-          backBtnIcon: 'left'
-        });
         const existAddress = ref([
           {
             id: 1,
@@ -418,7 +423,6 @@ If you want to select a province, you need to set the region ID in the order of
       :city="city"
       :country="country"
       :town="town"
-      :back-btn-icon="backBtnIcon"
       @close="close"
       @selected="selected"
       custom-and-exist-title="Choose Other Address"
@@ -528,60 +532,60 @@ If you want to select a province, you need to set the region ID in the order of
 # API
 
 | Attribute            | Description               | Type   | Default  |
-|----- | ----- | ----- | ----- 
-| v-model:visible | Whether to open address | String | ''
-| type | Choose type: exist/custom/custom2  | String | 'custom'
-| province | Province data| Array | []
-| city | City data | Array | []
-| country | Country data | Array | []
-| town | Town dta | Array | []
-| height | Popup height | String、Number | '200px'
-| exist-address | Exist address list data | Array | []
-| default-icon | Exist address default icon | String | ''
-| selected-icon | Exist address selected icon | String | ''
-| close-btn-icon | Custom close button icon | string | -
-| back-btn-icon | Custom back button icon | String | -
-| is-show-custom-address | Whether to change custom address | Boolean | true
-| custom-address-title  | Custom address title | String | 'Select Region'
-| exist-address-title|  Exist address title | String | 'Delivery To'
-| custom-and-exist-title| Custom address and existing address switch button copywriting | String | 'Choose Another Address'
-| columns-placeholder | Columns placeholder text | String|Array | 'Select'
-| lock-scroll   | Whether the background is locked   | Boolean        | `true`       
+|----- | ----- | ----- | ----- |
+| v-model:visible | Whether to open address | String | ''|
+| type | Choose type: exist/custom/custom2  | String | 'custom'|
+| province | Province data| Array | []|
+| city | City data | Array | []|
+| country | Country data | Array | []|
+| town | Town dta | Array | []|
+| height | Popup height | String、Number | '200px'|
+| exist-address | Exist address list data | Array | []|
+| is-show-custom-address | Whether to change custom address | Boolean | true|
+| custom-address-title  | Custom address title | String | 'Select Region'|
+| exist-address-title|  Exist address title | String | 'Delivery To'|
+| custom-and-exist-title| Custom address and existing address switch button copywriting | String | 'Choose Another Address'|
+| columns-placeholder | Columns placeholder text | String|Array | 'Select'|
+| lock-scroll   | Whether the background is locked   | Boolean        | `true`       |
 
 
 ## Event
 | Attribute            | Description               | Arguments   |
-|----- | ----- | ----- 
-| change |  Emitted when to selected custom address |  reference onChange
-| selected |  Emitted when to selected exist address  | reference selected
-| close |  Emitted when to close  | reference close
-| close-mask | Emitted when to close mask | {closeWay:'mask'/'cross'}
-| switch-module | Click to select another address or custom address to select the upper left corner of the return button triggered | {type:'exist'/'custom'/'custom2'}
+|----- | ----- | ----- |
+| change |  Emitted when to selected custom address |  reference onChange |
+| selected |  Emitted when to selected exist address  | reference selected |
+| close |  Emitted when to close  | reference close |
+| close-mask | Emitted when to close mask | {closeWay:'mask'/'cross'} |
+| switch-module | Click to select another address or custom address to select the upper left corner of the return button  triggered | {type:'exist'/'custom'/'custom2'} |
 
 
 ## change 
 | Attribute            | Description               | Options   |
-|----- | ----- | ----- 
-| custom | The administrative region currently clicked  |  province / city / country / town
-| next | The next level of the administrative region currently clicked | province / city / country / town
-| value | The value of the currently clicked administrative region | {}
+|----- | ----- | ----- |
+| custom | The administrative region currently clicked  |  province / city / country / town|
+| next | The next level of the administrative region currently clicked | province / city / country / town|
+| value | The value of the currently clicked administrative region | {}|
 
 ## selected 
 | Attribute            | Description               | Options   |
-|----- | ----- | ----- 
-| First Option(prevExistAdd) |  Select the previously selected address |  {}
-| Second Option(nowExistAdd) |  Currently selected address |  {}
-| Third Option(arr) |  After selecting the existing address list |  {}
+|----- | ----- | ----- |
+| First Option(prevExistAdd) |  Select the previously selected address |  {}|
+| Second Option(nowExistAdd) |  Currently selected address |  {}|
+| Third Option(arr) |  After selecting the existing address list |  {}|
 
 ## close 
 | Attribute            | Description               | Options   |
-|----- | ----- | ----- 
-| type | Selected Type  |  exist/custom/custom2
-| data | Selected Data | {} 
+|----- | ----- | ----- |
+| type | Selected Type  |  exist/custom/custom2|
+| data | Selected Data | {} |
 
 
 ## Slot
 | Attribute | Description | 
 |----- | ----- |  
-| bottom `3.1.23` | Bottom slot |  
+| bottom | Bottom slot |  
+| icon | Selected icon slot |  
+| unselectedIcon | Unselected icon slot |  
+| closeIcon | Close icon slot |  
+| backIcon | Change icon slot |  
     

+ 52 - 58
src/packages/__VUE/address/doc.md

@@ -2,7 +2,7 @@
 
 ### 介绍
 
-请加载对应依赖组件 Icon Popup Elevator
+请加载对应依赖组件 Popup Elevator
 
 ### 安装
 
@@ -77,7 +77,6 @@ app.use(Elevator);
           }
         };
         const close = val => {
-          console.log(val);
           text.value = val.data.addressStr;
         };
 
@@ -150,7 +149,6 @@ app.use(Elevator);
           }
         };
         const close = val => {
-          console.log(val);
           text.value = val.data.addressStr;
           value.value = [val.data.province.id, val.data.city.id, val.data.country.id];
         };
@@ -222,7 +220,6 @@ app.use(Elevator);
           }
         };
         const close = val => {
-          console.log(val);
           text.value = val.data.addressStr;
         };
 
@@ -328,10 +325,13 @@ app.use(Elevator);
       @close="close"
       :is-show-custom-address="false"
       @selected="selected3"
-      :default-icon="defaultIcon"
-      :selected-icon="selectedIcon"
-      :close-btn-icon="closeBtnIcon"
   >
+    <template #unselectedIcon>
+      <Heart1 style="margin-right:8px"></Heart1>
+    </template>
+    <template #icon>
+      <HeartFill style="margin-right:8px" color="#f00"></HeartFill>
+    </template>
     <template #bottom>
         <div class="nut-address-custom-buttom">
           <div class="btn">自定义按钮</div>
@@ -341,15 +341,11 @@ app.use(Elevator);
 </template>
 <script>
   import { ref,reactive,toRefs } from 'vue';
+  import { HeartFill, Heart1} from '@nutui/icons-vue';
   export default {
+    components:{HeartFill, Heart1 },
     setup() {
         const showPopupCustomImg = ref(false);
-        const icon = reactive({
-          selectedIcon: 'heart-fill',
-          defaultIcon: 'heart1',
-          closeBtnIcon: 'close',
-          backBtnIcon: 'left'
-        });
         const existAddress = ref([
           {
             id: 1,
@@ -406,7 +402,7 @@ app.use(Elevator);
           console.log(nowExistAdd);
         };
 
-        return { showPopupCustomImg, existAddress, text, showCustomImg, close, selected, ...toRefs(icon) };
+        return { showPopupCustomImg, existAddress, text, showCustomImg, close, selected };
     }
   }
 </script>
@@ -444,7 +440,6 @@ app.use(Elevator);
       :city="city"
       :country="country"
       :town="town"
-      :back-btn-icon="backBtnIcon"
       @close="close"
       @selected="selected"
       custom-and-exist-title="选择其他地址"
@@ -554,27 +549,22 @@ app.use(Elevator);
 ## API
 ### Props
 
-| 字段 | 说明 | 类型 | 默认值
-|----- | ----- | ----- | ----- 
-| v-model:visible | 是否打开地址选择 | String | ''
-| type | 地址选择类型 exist/custom/custom2  | String | 'custom'
-| province | 省,每个省的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | []
-| city | 市,每个市的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | []
-| country | 县,每个县的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | []
-| town | 乡/镇,每个乡/镇的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | []
-| height | 弹层中内容容器的高度,仅在type="custom2"时有效 | String、Number | '200px'
-| exist-address | 已存在地址列表,每个地址对象中,必传值provinceName、cityName、countyName、townName、addressDetail、selectedAddress(字段解释见下) | Array | []
-| default-icon | 已有地址列表默认图标,type=‘exist’ 时生效 | String | ''
-| selected-icon | 已有地址列表选中图标,type=‘exist’ 时生效 | String | ''
-| close-btn-icon | 自定义关闭弹框按钮图标 | string | -
-| back-btn-icon | 自定义地址与已有地址切换时,自定义返回的按钮图标 | String | -
-| is-show-custom-address | 是否可以切换自定义地址选择,type=‘exist’ 时生效 | Boolean | true
-| custom-address-title  | 自定义地址选择文案,type='custom' 时生效 | String | '请选择所在地区'
-| exist-address-title| 已有地址文案 ,type=‘exist’ 时生效| String | '配送至'
-| custom-and-exist-title| 自定义地址与已有地址切换按钮文案 ,type=‘exist’ 时生效| String | '选择其他地址'
-| columns-placeholder | 列提示文字 | String|Array | '请选择'
-| lock-scroll  | 背景是否锁定      | Boolean        | `true`       
-
+| 字段 | 说明 | 类型 | 默认值 |
+|----- | ----- | ----- | ----- |
+| v-model:visible | 是否打开地址选择 | String | '' |
+| type | 地址选择类型 exist/custom/custom2  | String | 'custom' |
+| province | 省,每个省的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | [] |
+| city | 市,每个市的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | [] |
+| country | 县,每个县的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | [] |
+| town | 乡/镇,每个乡/镇的对象中,必须有 name 字段,如果类型选择 custom2,必须指定 title 字段为首字母 | Array | [] |
+| height | 弹层中内容容器的高度,仅在type="custom2"时有效 | String、Number | '200px' |
+| exist-address | 已存在地址列表,每个地址对象中,必传值provinceName、cityName、countyName、townName、addressDetail、selectedAddress(字段解释见下) | Array | [] |
+| is-show-custom-address | 是否可以切换自定义地址选择,type=‘exist’ 时生效 | Boolean | true |
+| custom-address-title  | 自定义地址选择文案,type='custom' 时生效 | String | '请选择所在地区' |
+| exist-address-title| 已有地址文案 ,type=‘exist’ 时生效| String | '配送至' |
+| custom-and-exist-title| 自定义地址与已有地址切换按钮文案 ,type=‘exist’ 时生效| String | '选择其他地址' |
+| columns-placeholder | 列提示文字 | String|Array | '请选择' |
+| lock-scroll  | 背景是否锁定      | Boolean        | `true`  |
 
   * provinceName 省的名字
   * cityName 市的名字
@@ -584,36 +574,40 @@ app.use(Elevator);
   * selectedAddress 字段用于判断当前地址列表的选中项。
 
 ### Events
-| 字段 | 说明 | 回调参数 
-|----- | ----- | ----- 
-| change | 自定义选择地址时,选择地区时触发 |  参考 onChange
-| selected | 选择已有地址列表时触发 | 参考 selected
-| close | 地址选择弹框关闭时触发 | 参考 close
-| close-mask |点击遮罩层或点击右上角叉号关闭时触发 | {closeWay:'mask'/'cross'}
-| switch-module | 点击‘选择其他地址’或自定义地址选择左上角返回按钮触发 | {type:'exist'/'custom'/'custom2'}
+| 字段 | 说明 | 回调参数  |
+|----- | ----- | ----- |
+| change | 自定义选择地址时,选择地区时触发 |  参考 onChange |
+| selected | 选择已有地址列表时触发 | 参考 selected |
+| close | 地址选择弹框关闭时触发 | 参考 close |
+| close-mask |点击遮罩层或点击右上角叉号关闭时触发 | {closeWay:'mask'/'cross'} |
+| switch-module | 点击‘选择其他地址’或自定义地址选择左上角返回按钮触发 | {type:'exist'/'custom'/'custom2'} |
 
 
 ### change 回调参数
-| 参数 | 说明 | 可能值 
-|----- | ----- | ----- 
-| custom | 当前点击的行政区域  |  province(省) / city(市) / country(县) / town(乡)
-| next | 当前点击的行政区域的下一级 | province(省) / city(市) / country(县) / town(乡)
-| value | 当前点击的行政区域的值(返回传入的值) | {}
+| 参数 | 说明 | 可选值 |
+|----- | ----- | ----- |
+| custom | 当前点击的行政区域  |  province(省) / city(市) / country(县) / town(乡) |
+| next | 当前点击的行政区域的下一级 | province(省) / city(市) / country(县) / town(乡) |
+| value | 当前点击的行政区域的值(返回传入的值) | {} |
 
 ### selected 回调参数
-| 参数 | 说明 | 可能值 
-|----- | ----- | ----- 
-| 第一个参数(prevExistAdd) |  选择前选中的地址 |  {}
-| 第二个参数(nowExistAdd) |  当前选中的地址 |  {}
-| 第三个参数(arr) |  选择完之后的已有地址列表(selectedAddress 值发生改变) |  {}
+| 参数 | 说明 | 可能值 |
+|----- | ----- | ----- |
+| 第一个参数(prevExistAdd) |  选择前选中的地址 |  {} |
+| 第二个参数(nowExistAdd) |  当前选中的地址 |  {} |
+| 第三个参数(arr) |  选择完之后的已有地址列表(selectedAddress 值发生改变) |  {} |
 
 ### close 回调参数
-| 参数 | 说明 | 可能值 
-|----- | ----- | ----- 
-| type | 地址选择类型 exist/custom/custom2  |  exist/custom/custom2
-| data | 选择地址的值,custom 时,addressStr 为选择的地址组合 | {} 
+| 参数 | 说明 | 可能值 |
+|----- | ----- | ----- |
+| type | 地址选择类型 exist/custom/custom2  |  exist/custom/custom2 |
+| data | 选择地址的值,custom 时,addressStr 为选择的地址组合 | {}  |
 
 ### Slots
 | 字段 | 说明 | 
 |----- | ----- |  
-| bottom `3.1.23` | 可自定义底部 |  
+| bottom | 可自定义底部 |  
+| icon | 自定义选中项的图标 |  
+| unselectedIcon | 未选中地址时的图标 |  
+| closeIcon | 关闭弹层的图标 |  
+| backIcon | 自定义地址与已有地址切换时返回的图标 |  

+ 3 - 3
src/packages/__VUE/address/index.scss

@@ -46,13 +46,11 @@
     display: flex;
     justify-content: space-between;
     align-items: center;
-    margin-top: 24px;
-    margin-bottom: 17px;
+    height: 68px;
     padding: 0 20px;
     text-align: center;
     font-weight: bold;
     color: #333;
-    line-height: 20px;
     &__title {
       display: block;
       color: $address-header-title-color;
@@ -147,6 +145,8 @@
             font-weight: bold;
           }
           > div {
+            display: flex;
+            align-items: center;
             margin: 10px 0;
           }
         }

+ 20 - 61
src/packages/__VUE/address/index.vue

@@ -12,12 +12,9 @@
     <view class="nut-address">
       <view class="nut-address__header">
         <view class="nut-address__header-back" @click="switchModule">
-          <nut-icon
-            v-bind="$attrs"
-            :name="backBtnIcon"
-            color="#cccccc"
-            v-show="type == 'exist' && privateType == 'custom' && backBtnIcon"
-          ></nut-icon>
+          <slot name="backIcon">
+            <Left v-show="type == 'exist' && privateType == 'custom'"></Left>
+          </slot>
         </view>
 
         <view class="nut-address__header__title">
@@ -29,7 +26,9 @@
         </view>
 
         <view class="nut-address__header-close" @click="handClose('cross')">
-          <nut-icon v-bind="$attrs" v-if="closeBtnIcon" :name="closeBtnIcon" color="#cccccc" size="18px"></nut-icon>
+          <slot name="closeIcon">
+            <Close color="#cccccc" size="18px"></Close>
+          </slot>
         </view>
       </view>
 
@@ -60,12 +59,9 @@
               @click="nextAreaList(item)"
             >
               <div>
-                <component
-                  :is="renderIcon(selectedIcon)"
-                  v-bind="$attrs"
-                  v-if="selectedRegion[tabIndex]?.id == item.id"
-                ></component>
-                {{ item.name }}
+                <slot name="icon" v-if="selectedRegion[tabIndex]?.id == item.id">
+                  <Check class="nut-address-select-icon" width="13px"></Check> </slot
+                >{{ item.name }}
               </div>
             </li>
           </ul>
@@ -90,10 +86,14 @@
               :key="index"
               @click="selectedExist(item)"
             >
-              <component
-                :is="renderIcon(item.selectedAddress ? selectedIcon : defaultIcon)"
-                v-bind="$attrs"
-              ></component>
+              <slot name="unselectedIcon" v-if="!item.selectedAddress">
+                <Location2 class="nut-address-select-icon" width="13px"></Location2>
+              </slot>
+
+              <slot name="icon" v-if="item.selectedAddress">
+                <Check class="nut-address-select-icon" width="13px"></Check>
+              </slot>
+
               <div class="nut-address__exist-item-info">
                 <div class="nut-address__exist-item-info-name" v-if="item.name">{{ item.name }}</div>
                 <div class="nut-address__exist-item-info-phone" v-if="item.phone">{{ item.phone }}</div>
@@ -123,25 +123,11 @@ import { reactive, ref, toRefs, watch, nextTick, computed, Ref, h, PropType } fr
 import { createComponent } from '@/packages/utils/create';
 import { RegionData, CustomRegionData, existRegionData } from './type';
 import { popupProps } from '../popup/props';
-import Icon from '../icon/index.vue';
-import Popup from '../popup/index.vue';
-import Elevator from '../elevator/index.vue';
 const { componentName, create, translate } = createComponent('address');
+import { Location, Location2, Check, Close, Left } from '@nutui/icons-vue';
 
-interface AddressList {
-  id?: string | number;
-  provinceName: string;
-  cityName: string;
-  countyName: string;
-  townName: string;
-  addressDetail: string;
-  selectedAddress: boolean;
-}
 export default create({
-  components: {
-    [Popup.name]: Popup,
-    [Elevator.name]: Elevator
-  },
+  components: { Location, Location2, Check, Close, Left },
   inheritAttrs: false,
   props: {
     ...popupProps,
@@ -189,22 +175,6 @@ export default create({
       type: String,
       default: ''
     },
-    defaultIcon: {
-      type: String,
-      default: 'location2'
-    },
-    selectedIcon: {
-      type: String,
-      default: 'Check'
-    },
-    closeBtnIcon: {
-      type: String,
-      default: 'circle-close'
-    },
-    backBtnIcon: {
-      type: String,
-      default: 'left'
-    },
     height: {
       type: [String, Number],
       default: '200px'
@@ -237,15 +207,6 @@ export default create({
       }
     });
 
-    const renderIcon = (n: string) => {
-      return h(Icon, {
-        class: `${componentName}-select-icon`,
-        type: 'self',
-        size: '13px',
-        name: n
-      });
-    };
-
     const transformData = (data: RegionData[]) => {
       if (!Array.isArray(data)) throw new TypeError('params muse be array.');
 
@@ -399,7 +360,6 @@ export default create({
 
     // 手动关闭 点击叉号(cross),或者蒙层(mask)
     const handClose = (type = 'self') => {
-      if (!props.closeBtnIcon) return;
       closeWay.value = type == 'cross' ? 'cross' : 'self';
       showPopup.value = false;
     };
@@ -497,8 +457,7 @@ export default create({
       ...toRefs(props),
       translate,
       regionList,
-      transformData,
-      renderIcon
+      transformData
     };
   }
 });

+ 0 - 3
src/packages/__VUE/audio/__tests__/audio.spec.ts

@@ -1,6 +1,5 @@
 import { config, mount } from '@vue/test-utils';
 import { nextTick, ref, toRefs, reactive, onMounted } from 'vue';
-import NutIcon from '../../icon/index.vue';
 import NutRange from '../../range/index.vue';
 import Audio from '../index.vue';
 import AudioOperate from '../../audiooperate/index.vue';
@@ -14,7 +13,6 @@ function sleep(delay = 0): Promise<void> {
 
 beforeAll(() => {
   config.global.components = {
-    NutIcon,
     NutRange,
     AudioOperate,
     NutButton
@@ -40,7 +38,6 @@ test('audio init render', async () => {
   const wrapper = mount({
     components: {
       'nut-audio': Audio,
-      'nut-icon': NutIcon,
       'nut-range': NutRange,
       'nut-audio-operate': AudioOperate,
       'nut-button': NutButton

+ 32 - 12
src/packages/__VUE/audio/demo.vue

@@ -22,7 +22,7 @@
       ref="audioDemo"
     >
       <div class="nut-voice">
-        <div><nut-icon name="voice"></nut-icon></div>
+        <div><Voice></Voice></div>
         <div>{{ duration }}"</div>
       </div>
     </nut-audio>
@@ -59,11 +59,16 @@
       @changeProgress="changeProgress"
     >
       <div class="nut-audio-operate-group">
-        <nut-audio-operate type="back"><nut-icon name="play-double-back" size="35"></nut-icon></nut-audio-operate>
-        <nut-audio-operate type="play"
-          ><nut-icon :name="!playing ? 'play-start' : 'play-stop'" size="35"></nut-icon
-        ></nut-audio-operate>
-        <nut-audio-operate type="forward"><nut-icon name="play-double-forward" size="35"></nut-icon></nut-audio-operate>
+        <nut-audio-operate type="back">
+          <PlayDoubleBack width="35px" height="35px"></PlayDoubleBack>
+        </nut-audio-operate>
+        <nut-audio-operate type="play">
+          <PlayStart v-if="!playing" width="35px" height="35px"></PlayStart>
+          <PlayStop v-else width="35px" height="35px"></PlayStop>
+        </nut-audio-operate>
+        <nut-audio-operate type="forward">
+          <PlayDoubleForward width="35px" height="35px"></PlayDoubleForward>
+        </nut-audio-operate>
       </div>
     </nut-audio>
   </div>
@@ -74,7 +79,7 @@ import { reactive, toRefs, ref, onMounted } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { createDemo, translate } = createComponent('audio');
 import { useTranslate } from '@/sites/assets/util/useTranslate';
-
+import { PlayDoubleBack, PlayDoubleForward, PlayStart, PlayStop, Voice } from '@nutui/icons-vue';
 const initTranslate = () =>
   useTranslate({
     'zh-CN': {
@@ -93,11 +98,20 @@ const initTranslate = () =>
 
 export default createDemo({
   props: {},
+  components: {
+    Voice,
+    PlayDoubleBack,
+    PlayDoubleForward,
+    PlayStart,
+    PlayStop
+  },
   setup() {
     initTranslate();
-    const audioDemo = ref(null);
+    const audioDemo = ref({
+      second: 0
+    });
     const playing = ref(false);
-    const duration = ref(0);
+    const duration = ref<string>('');
     const data = reactive({
       muted: false,
       autoplay: false
@@ -107,11 +121,11 @@ export default createDemo({
       console.log('倒退');
     };
 
-    const forward = (progress) => {
+    const forward = (progress: number) => {
       console.log('快进', '当前时间' + progress);
     };
 
-    const changeStatus = (status) => {
+    const changeStatus = (status: boolean) => {
       console.log('当前播放状态', status);
       playing.value = status;
     };
@@ -120,12 +134,13 @@ export default createDemo({
       console.log('播放结束');
     };
 
-    const changeProgress = (val) => {
+    const changeProgress = (val: number) => {
       console.log('改变进度条', val);
     };
 
     const onCanplay = (e: Event) => {
       duration.value = audioDemo.value.second.toFixed();
+      console.log(e, duration.value);
     };
 
     onMounted(() => {
@@ -172,5 +187,10 @@ export default createDemo({
     border: 1px solid rgba(0, 0, 0, 0.6);
     border-radius: 18px;
   }
+
+  :deep(svg.nut-icon-am-rotate) {
+    --animate-duration: 1s !important;
+    --animate-delay: 0s;
+  }
 }
 </style>

+ 42 - 17
src/packages/__VUE/audio/doc.en-US.md

@@ -51,7 +51,7 @@ export default {
 
 :::demo
 
-```html
+```vue
 <template>
     <nut-audio
       url="//storage.360buyimg.com/jdcdkh/SMB/VCG231024564.wav"
@@ -62,14 +62,18 @@ export default {
       ref="audioDemo"
     >
       <div class="nut-voice">
-        <div><nut-icon name="voice"></nut-icon></div>
+        <div><Voice></Voice></div>
         <div>{{ duration }}"</div>
       </div>
     </nut-audio>
 </template>
 <script lang="ts">
 import { reactive, toRefs, onMounted } from 'vue';
+import { Voice } from '@nutui/icons-vue'
 export default {
+  components: {
+    Voice
+  },
   setup() {
     const audioDemo = ref(null);
     const data = reactive({
@@ -148,7 +152,7 @@ export default {
 
 :::demo
 
-```html
+```vue
 <template>
     <nut-audio
       url="//storage.360buyimg.com/jdcdkh/SMB/VCG231024564.wav"
@@ -163,17 +167,29 @@ export default {
       @changeProgress="changeProgress"
     >
       <div class="nut-audio-operate-group">
-        <nut-audio-operate type="back"><nut-icon name="play-double-back" size="35"></nut-icon></nut-audio-operate>
-        <nut-audio-operate type="play"
-          ><nut-icon :name="!playing ? 'play-start' : 'play-stop'" size="35"></nut-icon
-        ></nut-audio-operate>
-        <nut-audio-operate type="forward"><nut-icon name="play-double-forward" size="35"></nut-icon></nut-audio-operate>
+        <nut-audio-operate type="back">
+          <PlayDoubleBack width="35px" height="35px"></PlayDoubleBack>
+        </nut-audio-operate>
+        <nut-audio-operate type="play">
+          <PlayStart v-if="!playing" width="35px" height="35px"></PlayStart>
+          <PlayStop v-else width="35px" height="35px"></PlayStop>
+        </nut-audio-operate>
+        <nut-audio-operate type="forward">
+          <PlayDoubleForward width="35px" height="35px"></PlayDoubleForward>
+        </nut-audio-operate>
       </div>
     </nut-audio>
 </template>
 <script lang="ts">
 import { reactive, toRefs } from 'vue';
+import { PlayDoubleBack, PlayDoubleForward, PlayStart, PlayStop } from '@nutui/icons-vue'
 export default {
+  components: {
+    PlayDoubleBack,
+    PlayDoubleForward,
+    PlayStart, 
+    PlayStop
+  },
   setup() {
     const data = reactive({
       muted: false,
@@ -182,27 +198,36 @@ export default {
     const playing = ref(false);
 
     const fastBack = () => {
-      console.log('倒退');
+      console.log('Backwards');
     };
 
-    const forward = (progress) => {
-      console.log('快进', '当前时间' + progress);
+    const forward = (progress: number) => {
+      console.log('Fast forward', 'Current Time' + progress);
     };
 
-    const changeStatus = (status) => {
-      console.log('当前播放状态', status);
+    const changeStatus = (status: boolean) => {
+      console.log('Current play status', status);
       playing.value = status;
     };
 
     const ended = () => {
-      console.log('播放结束');
+      console.log('Playing ended');
     };
 
-    const changeProgress = (val) => {
-      console.log('改变进度条', val);
+    const changeProgress = (val: number) => {
+      console.log('Change progress', val);
     };
+
     return {
-      ...toRefs(data),playing, fastBack, forward, changeStatus, audioDemo, ended, duration, changeProgress
+      ...toRefs(data),
+      playing, 
+      fastBack, 
+      forward, 
+      changeStatus, 
+      audioDemo, 
+      ended, 
+      duration, 
+      changeProgress
     };
   }
 };

+ 37 - 12
src/packages/__VUE/audio/doc.md

@@ -51,7 +51,7 @@ export default {
 
 :::demo
 
-```html
+```vue
 <template>
     <nut-audio
       url="//storage.360buyimg.com/jdcdkh/SMB/VCG231024564.wav"
@@ -62,14 +62,18 @@ export default {
       ref="audioDemo"
     >
       <div class="nut-voice">
-        <div><nut-icon name="voice"></nut-icon></div>
+        <div><Voice></Voice></div>
         <div>{{ duration }}"</div>
       </div>
     </nut-audio>
 </template>
 <script lang="ts">
 import { reactive, toRefs, onMounted } from 'vue';
+import { Voice } from '@nutui/icons-vue'
 export default {
+  components: {
+    Voice
+  },
   setup() {
     const audioDemo = ref(null);
     const data = reactive({
@@ -148,7 +152,7 @@ export default {
 
 :::demo
 
-```html
+```vue
 <template>
     <nut-audio
       url="//storage.360buyimg.com/jdcdkh/SMB/VCG231024564.wav"
@@ -163,17 +167,29 @@ export default {
       @changeProgress="changeProgress"
     >
       <div class="nut-audio-operate-group">
-        <nut-audio-operate type="back"><nut-icon name="play-double-back" size="35"></nut-icon></nut-audio-operate>
-        <nut-audio-operate type="play"
-          ><nut-icon :name="!playing ? 'play-start' : 'play-stop'" size="35"></nut-icon
-        ></nut-audio-operate>
-        <nut-audio-operate type="forward"><nut-icon name="play-double-forward" size="35"></nut-icon></nut-audio-operate>
+        <nut-audio-operate type="back">
+          <PlayDoubleBack width="35px" height="35px"></PlayDoubleBack>
+        </nut-audio-operate>
+        <nut-audio-operate type="play">
+          <PlayStart v-if="!playing" width="35px" height="35px"></PlayStart>
+          <PlayStop v-else width="35px" height="35px"></PlayStop>
+        </nut-audio-operate>
+        <nut-audio-operate type="forward">
+          <PlayDoubleForward width="35px" height="35px"></PlayDoubleForward>
+        </nut-audio-operate>
       </div>
     </nut-audio>
 </template>
 <script lang="ts">
 import { reactive, toRefs } from 'vue';
+import { PlayDoubleBack, PlayDoubleForward, PlayStart, PlayStop } from '@nutui/icons-vue'
 export default {
+  components: {
+    PlayDoubleBack,
+    PlayDoubleForward,
+    PlayStart, 
+    PlayStop
+  },
   setup() {
     const data = reactive({
       muted: false,
@@ -185,11 +201,11 @@ export default {
       console.log('倒退');
     };
 
-    const forward = (progress) => {
+    const forward = (progress: number) => {
       console.log('快进', '当前时间' + progress);
     };
 
-    const changeStatus = (status) => {
+    const changeStatus = (status: boolean) => {
       console.log('当前播放状态', status);
       playing.value = status;
     };
@@ -198,11 +214,20 @@ export default {
       console.log('播放结束');
     };
 
-    const changeProgress = (val) => {
+    const changeProgress = (val: number) => {
       console.log('改变进度条', val);
     };
+
     return {
-      ...toRefs(data),playing, fastBack, forward, changeStatus, audioDemo, ended, duration, changeProgress
+      ...toRefs(data),
+      playing, 
+      fastBack, 
+      forward, 
+      changeStatus, 
+      audioDemo, 
+      ended, 
+      duration, 
+      changeProgress
     };
   }
 };

+ 5 - 3
src/packages/__VUE/audio/index.vue

@@ -29,8 +29,8 @@
         :class="['nut-audio__icon--box', playing ? 'nut-audio__icon--play' : 'nut-audio__icon--stop']"
         @click="changeStatus"
       >
-        <nut-icon v-if="playing" name="service" class="nut-icon-am-rotate nut-icon-am-infinite"></nut-icon>
-        <nut-icon v-if="!playing" name="service"></nut-icon>
+        <Service v-if="playing" class="nut-icon-am-rotate nut-icon-am-infinite"></Service>
+        <Service v-else></Service>
       </div>
     </div>
 
@@ -63,6 +63,7 @@
 import { toRefs, ref, onMounted, reactive, watch, provide } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import Range from '../range/index.vue';
+import { Service } from '@nutui/icons-vue';
 const { componentName, create } = createComponent('audio');
 
 export default create({
@@ -106,7 +107,8 @@ export default create({
     }
   },
   components: {
-    [Range.name]: Range
+    [Range.name]: Range,
+    Service
   },
   emits: ['fastBack', 'play', 'forward', 'ended', 'changeProgress', 'mute', 'can-play'],
 

+ 5 - 5
src/packages/__VUE/comment/components/CmtBottom.vue

@@ -9,10 +9,11 @@
         <view :class="['nut-comment-bottom__cpx-item', `nut-comment-bottom__cpx-item--${name}`]" @click="operate(name)">
           <template v-if="name != 'more'">
             <span>{{ info[name] }}</span>
-            <nut-icon :name="name == 'like' ? 'fabulous' : 'comment'"></nut-icon>
+            <Fabulous v-if="name == 'like'"></Fabulous>
+            <Comment v-else></Comment>
           </template>
           <template v-if="name == 'more'">
-            <nut-icon name="more-x"></nut-icon>
+            <MoreX></MoreX>
             <view class="nut-comment-bottom__cpx-item-popover" v-if="showPopver" @click="operate('popover')">{{
               translate('complaintsText')
             }}</view>
@@ -24,9 +25,9 @@
 </template>
 <script lang="ts">
 import { ref, watch, onMounted, PropType } from 'vue';
-
 import { createComponent } from '@/packages/utils/create';
 const { componentName, create, translate } = createComponent('comment-bottom');
+import { Fabulous, Comment, MoreX } from '@nutui/icons-vue';
 
 export default create({
   props: {
@@ -44,9 +45,8 @@ export default create({
       default: ['replay', 'like', 'more']
     }
   },
-  components: {},
+  components: { Fabulous, Comment, MoreX },
   emits: ['clickOperate', 'handleClick'],
-
   setup(props, { emit }) {
     const showPopver = ref(false);
 

+ 3 - 2
src/packages/__VUE/comment/components/CmtImages.vue

@@ -24,7 +24,7 @@
           v-if="type == 'multi' && totalImages.length > 9 && videos.length + index > 7"
         >
           <span>共 {{ totalImages.length }} 张</span>
-          <nut-icon name="right" size="12"></nut-icon>
+          <Right style="width: 12px"></Right>
         </view>
       </view>
     </template>
@@ -35,6 +35,7 @@ import { ref, watch, onMounted, PropType } from 'vue';
 
 import { createComponent } from '@/packages/utils/create';
 const { componentName, create } = createComponent('comment-images');
+import { Right } from '@nutui/icons-vue';
 
 interface VideosType {
   id: number | string;
@@ -61,7 +62,7 @@ export default create({
       default: () => []
     }
   },
-  components: {},
+  components: { Right },
   emits: ['click', 'clickImages'],
 
   setup(props, { emit }) {

+ 5 - 2
src/packages/__VUE/comment/demo.vue

@@ -66,7 +66,7 @@ import { onMounted, ref } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import { useTranslate } from '@/sites/assets/util/useTranslate';
 const { createDemo, translate } = createComponent('comment');
-
+import { Dongdong } from '@nutui/icons-vue';
 const initTranslate = () =>
   useTranslate({
     'zh-CN': {
@@ -85,11 +85,12 @@ const initTranslate = () =>
 
 export default createDemo({
   props: {},
+  components: { Dongdong },
   setup() {
     initTranslate();
     let cmt = ref({});
     const labels = () => {
-      return '<nut-icon name="dongdong" color="#fa2c19"></nut-icon>';
+      return '<Dongdong color="#fa2c19">';
     };
 
     const handleclick = (info: any) => {
@@ -104,6 +105,8 @@ export default createDemo({
       fetch('//storage.360buyimg.com/nutui/3x/comment_data.json')
         .then((response) => response.json())
         .then((res) => {
+          res.Comment.info.avatar =
+            'https://img14.360buyimg.com/imagetools/jfs/t1/167902/2/8762/791358/603742d7E9b4275e3/e09d8f9a8bf4c0ef.png';
           cmt.value = res.Comment;
         }) //执行结果是 resolve就调用then方法
         .catch((err) => console.log('Oh, error', err)); //执行结果是 reject就调用catch方法

+ 4 - 4
src/packages/__VUE/comment/doc.en-US.md

@@ -10,13 +10,12 @@ Used to display the comment list
 
 import { createApp } from 'vue';
 // vue
-import { Comment,Icon,Rate } from '@nutui/nutui';
+import { Comment,Rate } from '@nutui/nutui';
 // taro
-import { Comment,Icon,Rate } from '@nutui/nutui-taro';
+import { Comment,Rate } from '@nutui/nutui-taro';
 
 const app = createApp();
 app.use(Comment);
-app.use(Icon);
 app.use(Rate);
 
 ```
@@ -47,11 +46,12 @@ By default, images of reviews for individual items are displayed in a single sli
 </template>
 <script>
 import { reactive, ref,onMounted } from 'vue';
+import { Dongdong } from '@nutui/icons-vue';
 export default {
   setup() {
     let cmt = ref({});
     const labels = () => {
-      return '<nut-icon name="dongdong" color="#fa2c19"></nut-icon>';
+      return '<Dongdong/>';
     };
     onMounted(()=>{
       fetch('//storage.360buyimg.com/nutui/3x/comment_data.json')

+ 4 - 4
src/packages/__VUE/comment/doc.md

@@ -10,13 +10,12 @@
 
 import { createApp } from 'vue';
 // vue
-import { Comment,Icon,Rate } from '@nutui/nutui';
+import { Comment,Rate } from '@nutui/nutui';
 // taro
-import { Comment,Icon,Rate } from '@nutui/nutui-taro';
+import { Comment,Rate } from '@nutui/nutui-taro';
 
 const app = createApp();
 app.use(Comment);
-app.use(Icon);
 app.use(Rate);
 
 ```
@@ -47,11 +46,12 @@ app.use(Rate);
 </template>
 <script>
 import { reactive, ref,onMounted } from 'vue';
+import { Dongdong } from '@nutui/icons-vue';
 export default {
   setup() {
     let cmt = ref({});
     const labels = () => {
-      return '<nut-icon name="dongdong" color="#fa2c19"></nut-icon>';
+      return '<Dongdong/>';
     };
     onMounted(()=>{
       fetch('//storage.360buyimg.com/nutui/3x/comment_data.json')

+ 1 - 3
src/packages/__VUE/comment/index.scss

@@ -255,14 +255,12 @@
   &__follow {
     &-title {
       position: relative;
-      // display: flex;
-      // align-items: center;
       font-size: 14px;
       font-weight: bold;
       color: $black;
       padding-left: 8px;
 
-      i {
+      svg {
         position: absolute;
         left: 0;
         top: 13%;

+ 7 - 6
src/packages/__VUE/comment/index.vue

@@ -19,13 +19,11 @@
     <comment-images :images="images" :videos="videos" :type="imagesRows" @clickImages="clickImages"></comment-images>
 
     <view class="nut-comment__follow" v-if="follow && follow.days > 0" @click="handleClick">
-      <view class="nut-comment__follow-title"
-        ><nut-icon size="14" name="joy-smile" />{{ translate('additionalReview', follow.days) }}</view
-      >
+      <view class="nut-comment__follow-title">{{ translate('additionalReview', follow.days) }}</view>
       <view class="nut-comment__follow-com">{{ follow.content }}</view>
       <view class="nut-comment__follow-img" v-if="follow.images && follow.images.length > 0"
-        >{{ translate('additionalImages', follow.images.length) }} <nut-icon size="12" name="right"
-      /></view>
+        >{{ translate('additionalImages', follow.images.length) }} <Right width="12px"></Right
+      ></view>
     </view>
 
     <comment-bottom
@@ -43,6 +41,7 @@
 import { ref, onMounted, computed, PropType } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { componentName, create, translate } = createComponent('comment');
+import { JoySmile, Right } from '@nutui/icons-vue';
 
 import CommentHeader from './components/CmtHeader.vue';
 import CommentImages from './components/CmtImages.vue';
@@ -108,7 +107,9 @@ export default create({
   components: {
     CommentHeader,
     CommentImages,
-    CommentBottom
+    CommentBottom,
+    Right,
+    JoySmile
   },
   emits: ['click', 'clickImages', 'clickOperate'],
 

+ 14 - 12
src/packages/__VUE/image/__tests__/image.spec.ts

@@ -1,11 +1,13 @@
 import { config, mount } from '@vue/test-utils';
 import { h, nextTick } from 'vue';
-import Image from '../index.vue';
-import NutIcon from '../../icon/index.vue';
-
+import ImagePage from '../index.vue';
+import { Loading, CircleClose, Image, ImageError } from '@nutui/icons-vue';
 beforeAll(() => {
   config.global.components = {
-    NutIcon
+    Loading,
+    CircleClose,
+    Image,
+    ImageError
   };
 });
 
@@ -13,8 +15,8 @@ afterAll(() => {
   config.global.components = {};
 });
 
-test('image render', async () => {
-  const wrapper = mount(Image, {
+test('ImagePage render', async () => {
+  const wrapper = mount(ImagePage, {
     props: {
       src: '//img10.360buyimg.com/ling/jfs/t1/181258/24/10385/53029/60d04978Ef21f2d42/92baeb21f907cd24.jpg',
       width: '100',
@@ -26,8 +28,8 @@ test('image render', async () => {
   expect(wrapper.html()).toMatchSnapshot();
 });
 
-test('image load error', async () => {
-  const wrapper = mount(Image, {
+test('ImagePage load error', async () => {
+  const wrapper = mount(ImagePage, {
     props: {
       src: 'https://x',
       width: '100',
@@ -40,8 +42,8 @@ test('image load error', async () => {
   expect(wrapper.html()).toMatchSnapshot();
 });
 
-test('image loading', async () => {
-  const wrapper = mount(Image, {
+test('ImagePage loading', async () => {
+  const wrapper = mount(ImagePage, {
     props: {
       src: '',
       width: '100',
@@ -54,8 +56,8 @@ test('image loading', async () => {
   expect(wrapper.html()).toMatchSnapshot();
 });
 
-test('image render Round', async () => {
-  const wrapper = mount(Image, {
+test('ImagePage render Round', async () => {
+  const wrapper = mount(ImagePage, {
     props: {
       src: '//img10.360buyimg.com/ling/jfs/t1/181258/24/10385/53029/60d04978Ef21f2d42/92baeb21f907cd24.jpg',
       width: '100',

+ 9 - 2
src/packages/__VUE/image/demo.vue

@@ -52,7 +52,7 @@
         <nut-col :span="8">
           <nut-image width="100" height="100" showLoading>
             <template #loading>
-              <nut-icon name="loading"></nut-icon>
+              <Loading width="16px" height="16px" name="loading"></Loading>
             </template>
           </nut-image>
           <div class="text">自定义</div>
@@ -69,7 +69,9 @@
         </nut-col>
         <nut-col :span="8">
           <nut-image src="https://x" width="100" height="100" showLoading>
-            <nut-icon name="circle-close"></nut-icon>
+            <template #error>
+              <CircleClose width="16px" height="16px" name="circleClose"></CircleClose>
+            </template>
           </nut-image>
           <div class="text">自定义</div>
         </nut-col>
@@ -80,6 +82,7 @@
 <script lang="ts">
 import { ref } from 'vue';
 import { createComponent } from '@/packages/utils/create';
+import { Loading, CircleClose } from '@nutui/icons-vue';
 const { createDemo, translate } = createComponent('image');
 import { useTranslate } from '@/sites/assets/util/useTranslate';
 const initTranslate = () =>
@@ -103,6 +106,10 @@ const initTranslate = () =>
   });
 export default createDemo({
   props: {},
+  components: {
+    Loading,
+    CircleClose
+  },
   setup() {
     initTranslate();
     const src = ref('//img10.360buyimg.com/ling/jfs/t1/181258/24/10385/53029/60d04978Ef21f2d42/92baeb21f907cd24.jpg');

+ 4 - 2
src/packages/__VUE/image/doc.en-US.md

@@ -96,7 +96,7 @@ The Image component provides a default loading prompt and supports custom conten
 <template>
   <nut-image width="100" height="100" showLoading>
     <template #loading>
-      <nut-icon name="loading"></nut-icon>
+      <Loading width="16px" height="16px" name="loading"></Loading>
     </template>
   </nut-image>
 </template>
@@ -113,7 +113,9 @@ The Image component provides a default loading failure warning and supports cust
 ```html
 <template>
   <nut-image src="https://x" width="100" height="100" showLoading>
-    <template #error> <nut-icon name="circle-close"></nut-icon> </template>
+    <template #error>
+      <CircleClose width="16px" height="16px" name="circleClose"></CircleClose>
+    </template>
   </nut-image>
 </template>
 ```

+ 4 - 2
src/packages/__VUE/image/doc.md

@@ -95,7 +95,7 @@ app.use();
 <template>
   <nut-image width="100" height="100" showLoading>
     <template #loading>
-      <nut-icon name="loading"></nut-icon>
+      <Loading width="16px" height="16px" name="loading"></Loading>
     </template>
   </nut-image>
 </template>
@@ -112,7 +112,9 @@ app.use();
 ```html
 <template>
   <nut-image src="https://x" width="100" height="100" showError>
-    <template #error> 加载失败 </template>
+    <template #error> 
+      <CircleClose width="16px" height="16px" name="circleClose"></CircleClose>
+    </template>
   </nut-image>
 </template>
 ```

+ 7 - 3
src/packages/__VUE/image/index.vue

@@ -3,12 +3,11 @@
     <img class="nut-img" :src="src" :alt="alt" @load="load" @error="error" :style="styles" />
 
     <view class="nut-img-loading" v-if="loading">
-      <nut-icon name="image" v-if="!slotLoding"></nut-icon>
+      <Image v-if="!slotLoding" width="16px" height="20px" name="image"></Image>
       <slot name="loading"></slot>
     </view>
-
     <view class="nut-img-error" v-if="isError && !loading">
-      <nut-icon name="image-error" v-if="!slotError"></nut-icon>
+      <ImageError v-if="!slotError" width="16px" height="20px" name="imageError"></ImageError>
       <slot name="error"></slot>
     </view>
   </view>
@@ -17,6 +16,7 @@
 import { reactive, toRefs, computed, PropType, useSlots, watch, CSSProperties } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import { pxCheck } from '../../utils/pxCheck';
+import { Image, ImageError } from '@nutui/icons-vue';
 const { componentName, create } = createComponent('image');
 export default create({
   props: {
@@ -55,6 +55,10 @@ export default create({
       default: true
     }
   },
+  components: {
+    Image,
+    ImageError
+  },
   emits: ['click', 'load', 'error'],
 
   setup(props, { emit }) {

+ 38 - 32
src/packages/__VUE/infiniteloading/demo.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="demo">
+  <div class="demo nut-infiniteloading-demo">
     <nut-tabs v-model="tabsValue" animatedTime="0" @change="chagetabs">
       <nut-tab-pane :title="translate('basic')">
         <ul class="infiniteUl">
@@ -145,39 +145,45 @@ export default createDemo({
 });
 </script>
 
-<style lang="scss" scoped>
-.demo {
-  padding-left: 0px !important;
-  padding-right: 0px !important;
-}
-.nut-theme-dark {
-  .infiniteLi {
-    color: $dark-color;
+<style lang="scss">
+.nut-infiniteloading-demo {
+  .nut-theme-dark {
+    .infiniteLi {
+      color: $dark-color;
+    }
   }
-}
 
-.nut-tab-pane {
-  padding: 0 !important;
-  padding-left: 16px !important;
-}
-.infiniteUl {
-  width: 100%;
-  height: calc(100vh - 120px);
-  padding: 0;
-  margin: 0;
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-.infiniteLi {
-  font-size: 14px;
-  color: #333;
-  padding: 12px 0;
-  border-bottom: 1px solid #eee;
-}
+  .nut-tabs__titles {
+    background: #fff !important;
+    box-shadow: 0px 4px 10px 0px rgb(0 0 0 / 7%);
+    margin-top: 10px;
+    margin-bottom: 3px;
+    z-index: 99;
+  }
 
-.loading {
-  display: block;
-  width: 100%;
-  text-align: center;
+  .nut-tab-pane {
+    padding: 0 !important;
+    padding-left: 16px !important;
+  }
+  .infiniteUl {
+    width: 100%;
+    height: calc(100vh - 120px);
+    padding: 0;
+    margin: 0;
+    overflow-y: auto;
+    overflow-x: hidden;
+  }
+  .infiniteLi {
+    font-size: 14px;
+    color: #333;
+    padding: 12px 0;
+    border-bottom: 1px solid #eee;
+  }
+
+  .loading {
+    display: block;
+    width: 100%;
+    text-align: center;
+  }
 }
 </style>

+ 3 - 3
src/packages/__VUE/infiniteloading/doc.en-US.md

@@ -8,11 +8,10 @@ Scrolling to the bottom of the list automatically loads more data.
 
 ```javascript
   import { createApp } from 'vue';
-  import { InfiniteLoading,Icon } from '@nutui/nutui';
+  import { InfiniteLoading } from '@nutui/nutui';
 
   const app = createApp();
   app.use(InfiniteLoading);
-  app.use(Icon);
 ```
 
 ### Basic Usage
@@ -108,7 +107,6 @@ Scrolling to the bottom of the list automatically loads more data.
 | threshold        | The loadMore event will be Emitted when the distance between the scrollbar and the bottom is less than threshold   | Number  | `200`            |
 | use-capture      | Whether to use capture mode                                                                                        | Boolean | `false`          |
 | load-more-txt    | "No more" text                                                                                                     | String  | 'Oops, this is the bottom'|
-| load-icon        | Pull on loading[图标名称](#/zh-CN/component/icon)                                                                                    | String | ''    |
 | load-txt         | Pull on loading text                                                                                                | String  | `Loading...`      |
 
 ### Events
@@ -122,5 +120,7 @@ Scrolling to the bottom of the list automatically loads more data.
 
 | Attribute | Description  | 
 |--------|----------------|
+| default  | Custom content |
 | loading  | Loading text |
+| loadingIcon  | Custom loading icon |
 | finished  | Finished text |

+ 3 - 3
src/packages/__VUE/infiniteloading/doc.md

@@ -8,11 +8,10 @@
 
 ```javascript
   import { createApp } from 'vue';
-  import { InfiniteLoading,Icon } from '@nutui/nutui';
+  import { InfiniteLoading } from '@nutui/nutui';
 
   const app = createApp();
   app.use(InfiniteLoading);
-  app.use(Icon);
 
 ```
 
@@ -110,7 +109,6 @@
 | threshold         | 滚动条与底部距离小于 threshold 时触发 loadMore 事件 | Number | `200`               |
 | use-capture          | 是否使用捕获模式 true 捕获 false 冒泡                        | Boolean | `false`            |
 | load-more-txt          | “没有更多数”据展示文案                        | String | `'哎呀,这里是底部了啦'`            |
-| load-icon        | 上拉加载[图标名称](#/zh-CN/component/icon)                       | String | ''             |
 | load-txt        | 上拉加载提示文案                         | String | `加载中...`                |
 
 ### Events
@@ -124,5 +122,7 @@
 
 | 名称 | 说明           | 
 |--------|----------------|
+| default  | 自定义加载内容 |
 | loading  | 自定义底部加载中提示 |
+| loadingIcon  | 自定义底部加载中图标 |
 | finished  | 自定义加载完成后的提示文案 |

+ 5 - 2
src/packages/__VUE/infiniteloading/index.scss

@@ -24,10 +24,13 @@
     text-align: center;
 
     .nut-infinite__bottom-box {
+      display: flex;
+      align-items: center;
+      justify-content: center;
       &__img {
         margin-right: 5px;
-        width: 28px;
-        height: 24px;
+        width: 15px;
+        height: 15px;
       }
       &__text {
         font-size: 12px;

+ 5 - 6
src/packages/__VUE/infiniteloading/index.vue

@@ -8,7 +8,7 @@
       <template v-if="isInfiniting">
         <view class="nut-infinite__bottom-box">
           <slot name="loading">
-            <nut-icon v-if="loadIcon" class="nut-infinite__bottom-box__img" v-bind="$attrs" :name="loadIcon"></nut-icon>
+            <slot name="loadIcon"><Loading class="nut-icon-loading nut-infinite__bottom-box__img"></Loading></slot>
             <view class="nut-infinite__bottom-box__text">{{ loadTxt || translate('loading') }}</view>
           </slot>
         </view>
@@ -39,6 +39,7 @@ const { componentName, create, translate } = createComponent('infinite-loading')
 import { useScrollParent } from '@/packages/utils/useScrollParent';
 import requestAniFrame from '@/packages/utils/raf';
 import { getScrollTopRoot } from '@/packages/utils/util';
+import { Loading } from '@nutui/icons-vue';
 
 export default create({
   props: {
@@ -54,10 +55,6 @@ export default create({
       type: Number,
       default: 200
     },
-    loadIcon: {
-      type: String,
-      default: ''
-    },
     loadTxt: {
       type: String,
       default: ''
@@ -80,7 +77,9 @@ export default create({
     }
   },
   emits: ['scroll-change', 'load-more', 'update:modelValue'],
-
+  components: {
+    Loading
+  },
   setup(props, { emit, slots }) {
     const scroller = ref<HTMLElement>();
     const scrollParent = useScrollParent(scroller);

+ 3 - 2
src/packages/__VUE/sidenavbar/__tests__/index.spec.ts

@@ -3,7 +3,7 @@ import SideNavBar from '../index.vue';
 import SideNavBarItem from '../../sidenavbaritem/index.vue';
 import SubSideNavBar from '../../subsidenavbar/index.vue';
 import { nextTick } from 'vue';
-import NutIcon from '../../icon/index.vue';
+import { ArrowDown2, ArrowUp2 } from '@nutui/icons-vue';
 
 function sleep(delay = 0): Promise<void> {
   return new Promise((resolve) => {
@@ -13,7 +13,8 @@ function sleep(delay = 0): Promise<void> {
 
 beforeAll(() => {
   config.global.components = {
-    NutIcon
+    ArrowDown2,
+    ArrowUp2
   };
 });
 

+ 1 - 4
src/packages/__VUE/sidenavbar/demo.vue

@@ -186,7 +186,4 @@ export default createDemo({
 });
 </script>
 
-<style lang="scss" scoped>
-.demo {
-}
-</style>
+<style lang="scss" scoped></style>

+ 1 - 1
src/packages/__VUE/sidenavbar/index.vue

@@ -8,7 +8,7 @@
   </view>
 </template>
 <script lang="ts">
-import { computed, onMounted, reactive, ref, toRefs, Ref, watch } from 'vue';
+import { computed, onMounted, reactive, ref, toRefs, Ref } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { componentName, create } = createComponent('side-navbar');
 export default create({

+ 6 - 6
src/packages/__VUE/subsidenavbar/index.vue

@@ -2,7 +2,10 @@
   <view :class="classes" :ikey="ikey">
     <view class="nut-sub-side-navbar__title" @click.stop="handleClick">
       <span class="nut-sub-side-navbar__title__text">{{ title }}</span>
-      <span class="nut-sub-side-navbar__title__icon"><nut-icon name="down-arrow" :class="direction"></nut-icon></span>
+      <span class="nut-sub-side-navbar__title__icon">
+        <ArrowDown2 v-if="!direction"></ArrowDown2>
+        <ArrowUp2 v-else></ArrowUp2>
+      </span>
     </view>
     <view class="nut-sub-side-navbar__list" :class="!direction ? 'nutFadeIn' : 'nutFadeOut'" :style="style">
       <slot></slot>
@@ -12,6 +15,7 @@
 <script lang="ts">
 import { computed, onMounted, reactive, toRefs } from 'vue';
 import { createComponent } from '@/packages/utils/create';
+import { ArrowDown2, ArrowUp2 } from '@nutui/icons-vue';
 const { componentName, create } = createComponent('sub-side-navbar');
 export default create({
   props: {
@@ -28,34 +32,30 @@ export default create({
       default: true
     }
   },
+  components: { ArrowDown2, ArrowUp2 },
   emits: ['title-click'],
   setup: (props: any, context: any) => {
     const state = reactive({
       direction: ''
     });
-
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
         [prefixCls]: true
       };
     });
-
     const style = computed(() => {
       return {
         height: !state.direction ? 'auto' : '0px'
       };
     });
-
     const handleClick = () => {
       context.emit('title-click');
       state.direction = !state.direction ? 'up' : '';
     };
-
     onMounted(() => {
       state.direction = props.open ? '' : 'up';
     });
-
     return {
       ...toRefs(state),
       classes,