uni-app 支持在 App 和 小程序 中使用小程序自定义组件
从HBuilderX2.4.7起,H5端也可以运行微信小程序组件。
平台差异说明

平台 支持情况 小程序组件存放目录
H5 支持微信小程序组件(2.4.7+) wxcomponents
App(不含nvue) 支持微信小程序组件 wxcomponents
微信小程序 支持微信小程序组件 wxcomponents
支付宝小程序 支持支付宝小程序组件 mycomponents
百度小程序 支持百度小程序组件 swancomponents
字节跳动小程序 支持字节跳动小程序组件 ttcomponents
QQ小程序 支持QQ小程序组件 wxcomponents

此文档要求开发者对各端小程序的自定义组件有一定了解,没接触过小程序自定义组件的可以参考:

目录结构

  1. ┌─wxcomponents 微信小程序自定义组件存放目录
  2. └──custom 微信小程序自定义组件
  3. ├─index.js
  4. ├─index.wxml
  5. ├─index.json
  6. └─index.wxss
  7. ├─mycomponents 支付宝小程序自定义组件存放目录
  8. └──custom 支付宝小程序自定义组件
  9. ├─index.js
  10. ├─index.axml
  11. ├─index.json
  12. └─index.wxss
  13. ├─swancomponents 百度小程序自定义组件存放目录
  14. └──custom 百度小程序自定义组件
  15. ├─index.js
  16. ├─index.swan
  17. ├─index.json
  18. └─index.wxss
  19. ├─pages
  20. └─index
  21. └─index.vue
  22. ├─static
  23. ├─main.js
  24. ├─App.vue
  25. ├─manifest.json
  26. └─pages.json

使用方式

引入组件

pages.json 对应页面的 style -> usingComponents 引入组件:

  1. {
  2. "pages": [
  3. {
  4. "path": "index/index",
  5. "style": {
  6. "usingComponents": {
  7. // #ifdef APP-PLUS || MP-WEIXIN || MP-QQ
  8. "custom": "/wxcomponents/custom/index"
  9. // #endif
  10. // #ifdef MP-BAIDU
  11. "custom": "/swancomponents/custom/index"
  12. // #endif
  13. // #ifdef MP-ALIPAY
  14. "custom": "/mycomponents/custom/index"
  15. // #endif
  16. }
  17. }
  18. }
  19. ]
  20. }

在页面中使用

  1. <!-- 页面模板 (index.vue) -->
  2. <view>
  3. <!-- 在页面中对自定义组件进行引用 -->
  4. <custom name="uni-app"></custom>
  5. </view>

代码示例

下面以微信小程序官方自定义组件示例 miniprogram-slide-view 为例演示小程序自定义组件的使用方式。 其他组件使用示例见GitHub:wxcomponents-template。 插件市场有一个完整的vant weapp 引用好的示例工程,详见https://ext.dcloud.net.cn/plugin?id=302
目录结构

  1. ┌─components
  2. ├─wxcomponents
  3. └──miniprogram-slide-view
  4. ├─index.js
  5. ├─index.wxml
  6. ├─index.json
  7. └─index.wxss
  8. ├─pages
  9. └─slide-view
  10. └─slide-view.vue
  11. ├─static
  12. ├─main.js
  13. ├─App.vue
  14. ├─manifest.json
  15. └─pages.json

pages.json

  1. {
  2. "pages": [
  3. {
  4. "path": "slide-view/slide-view",
  5. "style": {
  6. "navigationBarTitleText": "slide-view",
  7. "usingComponents": {
  8. "slide-view": "/wxcomponents/miniprogram-slide-view/index"
  9. }
  10. }
  11. }
  12. ]
  13. }

slide-view.vue

  1. <template>
  2. <view class='slide'>
  3. <slide-view width="750" height="110" slide-width="500">
  4. <view slot="left" class="l">
  5. <image src="/static/file_transfer.jpg" class="img"></image>
  6. <view class='text'>
  7. <view class='title'>文件传输助手</view>
  8. <view class='time'>7:00 PM</view>
  9. </view>
  10. </view>
  11. <view slot="right" class="r">
  12. <view class='read'>标为已读</view>
  13. <view class='delete'>删除</view>
  14. </view>
  15. </slide-view>
  16. </view>
  17. </template>
  18. <script>
  19. export default {}
  20. </script>
  21. <style>
  22. .slide {
  23. border-bottom: 1px solid #DEDEDE;
  24. }
  25. .l {
  26. background-color: white;
  27. height: 110rpx;
  28. width: 750rpx;
  29. display: flex;
  30. flex-direction: row;
  31. }
  32. .r {
  33. height: 110rpx;
  34. display: flex;
  35. direction: row;
  36. text-align: center;
  37. vertical-align: middle;
  38. line-height: 110rpx;
  39. }
  40. .read {
  41. background-color: #ccc;
  42. color: #fff;
  43. width: 350rpx;
  44. }
  45. .delete {
  46. background-color: red;
  47. color: #fff;
  48. width: 150rpx;
  49. }
  50. .img {
  51. width: 90rpx;
  52. height: 90rpx;
  53. border-radius: 10rpx;
  54. margin: 10rpx 15rpx;
  55. }
  56. .text {
  57. display: flex;
  58. flex-direction: row;
  59. }
  60. .title {
  61. margin-top: 15rpx;
  62. font-size: 33rpx;
  63. }
  64. .time {
  65. margin-top: 15rpx;
  66. color: #ccc;
  67. font-size: 25rpx;
  68. margin-left: 330rpx;
  69. }
  70. </style>

注意事项

  • 小程序组件需要放在项目特殊文件夹 wxcomponents(或 mycomponents、swancomponents)。HBuilderX 建立的工程 wxcomponents 文件夹在 项目根目录下。vue-cli 建立的工程 wxcomponents 文件夹在 src 目录下。可以在 vue.config.js 中自定义其他目录
  • 小程序组件的性能,不如vue组件。使用小程序组件,需要自己手动setData,很难自动管理差量数据更新。而使用vue组件会自动diff更新差量数据。

所以如无明显必要,建议使用vue组件而不是小程序组件。
比如某些小程序ui组件,完全可以用更高性能的 uni ui替代。

  • 当需要在 vue 组件中使用小程序组件时,注意在 pages.jsonglobalStyle 中配置 usingComponents,而不是页面级配置。
  • 注意数据和事件绑定的差异,使用时应按照**vue**的数据和事件绑定方式
    • 属性绑定从 attr="{{ a }}",改为 :attr="a";从 title="复选框{{ item }}" 改为 :title="'复选框' + item"
    • 事件绑定从 bind:click="toggleActionSheet1" 改为 @click="toggleActionSheet1"
    • 阻止事件冒泡 从 catch:tap="xx" 改为 @tap.native.stop="xx"
    • wx:if 改为 v-if
    • wx:for="{{ list }}" wx:key="{{ index }}" 改为v-for="(item,index) in list"
    • 原事件命名以短横线分隔的需要手动修改小程序组件源码为驼峰命名,比如:this.$emit('left-click') 修改为 this.$emit('leftClick')(HBuilderX 1.9.0+ 不再需要修改此项)

详细的小程序转uni-app语法差异可参考文档https://ask.dcloud.net.cn/article/35786