• 微信小程序4


    自定义组件应用

    1.介绍

    微信小程序自定义组件是指开发者可以自定义组件,将一些常用的 UI 元素封装成一个自定义组件,然后在多个页面中复用该组件,实现代码复用和页面性能优化的效果。

    2.自定义组件分为两种类型 

    1. 组件模板类型:组件调用方式类似于标签,使用时需要通过属性传参,组件内部通过 slot 来渲染内容。
    2. 组件 Behavior 类型:组件调用方式类似于混入,使用时需要 mixins 引入,组件内部通过 this 来访问引入的属性和方法。

     3.自定义组件的开发流程如下:

    1. 在 components 文件夹内创建自定义组件文件夹和文件,组件文件夹下需要包含一个 .js 文件、一个 .wxml 文件,以及一个 .wxss 文件。
    2. 在自定义组件 .js 文件内注册自定义组件,定义属性和事件。
    3. 在需要使用自定义组件的页面 .json 文件内注册自定义组件。
    4. 在需要使用自定义组件的 .wxml 文件内调用自定义组件,并传递所需属性和事件。

     注意事项:

    1. 自定义组件命名要求必须是小写字母和 - 的组合,且不能以 - 开头。
    2. 自定义组件的默认样式和命名规则与页面样式不同,具体规则可以参考官方文档。
    3. 自定义组件的事件需要在 .js 文件内通过 this.triggerEvent() 触发,事件名称必须以小写字母和 - 的组合命名。
    4. 自定义组件的使用方式和传参方式与普通组件有所不同,具体详情可以参考官方文档。

    4.案例演示

    4.1创建自定义组件

    类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成。要编写一个自定义组件,首先需要在 json 文件中进行自定义组件声明(将 component 字段设为 true 可将这一组文件设为自定义组件):

    1. {
    2. "component": true
    3. }

     同时,还要在 wxml 文件中编写组件模板,在 wxss 文件中加入组件样式,它们的写法与页面的写法类似。具体细节和注意事项参见 组件模板和样式 。

     在项目中创建一个components/tabs文件夹,新建Component文件

     

    注意: 在新的版本里面我们会出现报错,但是在win7的一些旧版本里面是不会出现这些问题的,我们需要在project.config.json文件里面添加以下代码:

    1. "ignoreDevUnusedFiles": false,
    2. "ignoreUploadUnusedFiles": false,

    同时,还要在 wxml 文件中编写组件模板,在 wxss 文件中加入组件样式,它们的写法与页面的写法类似。具体细节和注意事项参见 组件模板和样式 。

     代码示例:

    1. <view class="inner">
    2. {{innerText}}
    3. </view>
    4. <slot></slot>
    1. /* 这里的样式只应用于这个自定义组件 */
    2. .inner {
    3. color: red;
    4. }

     注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

    在自定义组件的 js 文件中,需要使用 Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法。

    组件的属性值和内部数据将被用于组件 wxml 的渲染,其中,属性值是可由组件外部传入的。更多细节参见 Component构造器 。

    代码示例:

    1. Component({
    2. properties: {
    3. // 这里定义了innerText属性,属性值可以在组件使用时指定
    4. innerText: {
    5. type: String,
    6. value: 'default value',
    7. }
    8. },
    9. data: {
    10. // 这里是一些组件内部数据
    11. someData: {}
    12. },
    13. methods: {
    14. // 这里是一个自定义方法
    15. customMethod: function(){}
    16. }
    17. })

     4.2使用自定义组件

    使用已注册的自定义组件前,首先要在页面的 json 文件中进行引用声明。此时需要提供每个自定义组件的标签名和对应的自定义组件文件路径:

    1. {
    2. "usingComponents": {
    3. "tabs": "/components/tabs/tabs"
    4. }
    5. }

    这样,在页面的 wxml 中就可以像使用基础组件一样使用自定义组件。节点名即自定义组件的标签名,节点属性即传递给组件的属性值。

    在wxml里面使用自定义标签

    <tabs inner-text='6666'></tabs>

    4.3 案例---头部导航

     tabs.wxml

    1. <view class="tabs">
    2. <view class="tabs_title">
    3. <view wx:for="{{tabList}}" wx:key="id" class="title_item {{index==tabIndex?'item_active':''}}" bindtap="handleItemTap" data-index="{{index}}">
    4. <view style="margin-bottom:5rpx">{{item}}</view>
    5. <view style="width:30px" class="{{index==tabIndex?'item_active1':''}}"></view>
    6. </view>
    7. </view>
    8. <view class="tabs_content">
    9. <slot></slot>
    10. </view>
    11. </view>

    tabs.js

    1. // components/tabs/tabs.js
    2. Component({
    3. /**
    4. * 组件的属性列表
    5. */
    6. properties: {//定义了组件所需要的属性值
    7. tabList:Object
    8. },
    9. /**
    10. * 组件的初始数据
    11. */
    12. data: {
    13. },
    14. /**
    15. * 组件的方法列表
    16. */
    17. methods: {
    18. }
    19. })

    wxss

    1. /* components/tabs/tabs.wxss */
    2. .inner {
    3. color: red;
    4. }
    5. .tabs {
    6. position: fixed;
    7. top: 0;
    8. width: 100%;
    9. background-color: #fff;
    10. z-index: 99;
    11. border-bottom: 1px solid #efefef;
    12. padding-bottom: 20rpx;
    13. }
    14. .tabs_title {
    15. /* width: 400rpx; */
    16. width: 90%;
    17. display: flex;
    18. font-size: 9pt;
    19. padding: 0 20rpx;
    20. }
    21. .title_item {
    22. color: #999;
    23. padding: 15rpx 0;
    24. display: flex;
    25. flex: 1;
    26. flex-flow: column nowrap;
    27. justify-content: center;
    28. align-items: center;
    29. }
    30. .item_active {
    31. /* color:#ED8137; */
    32. color: #000000;
    33. font-size: 11pt;
    34. font-weight: 800;
    35. }
    36. .item_active1 {
    37. /* color:#ED8137; */
    38. color: #000000;
    39. font-size: 11pt;
    40. font-weight: 800;
    41. border-bottom: 6rpx solid #333;
    42. border-radius: 2px;
    43. }

    我们在指定的页面调用自定义好的组件

    在json文件里面设置调用组件

    1. {
    2. "usingComponents": {
    3. "tabs" : "/components/tabs/tabs"
    4. }
    5. }

    wxml文件里面添加自定义的组件

    1. <tabs tabList="{{tabs}}" bindtabsItemChange="tabsItemChange">
    2. </tabs>

    在js文件里面设置值

    1. // pages/meeting/list/list.js
    2. Page({
    3. /**
    4. * 页面的初始数据
    5. */
    6. data: {
    7. tabs: ['会议中', '已完成', '已取消', '全部会议']
    8. },
    9. /**
    10. * 生命周期函数--监听页面加载
    11. */
    12. onLoad(options) {
    13. },
    14. /**
    15. * 生命周期函数--监听页面初次渲染完成
    16. */
    17. onReady() {
    18. },
    19. /**
    20. * 生命周期函数--监听页面显示
    21. */
    22. onShow() {
    23. },
    24. /**
    25. * 生命周期函数--监听页面隐藏
    26. */
    27. onHide() {
    28. },
    29. /**
    30. * 生命周期函数--监听页面卸载
    31. */
    32. onUnload() {
    33. },
    34. /**
    35. * 页面相关事件处理函数--监听用户下拉动作
    36. */
    37. onPullDownRefresh() {
    38. },
    39. /**
    40. * 页面上拉触底事件的处理函数
    41. */
    42. onReachBottom() {
    43. },
    44. /**
    45. * 用户点击右上角分享
    46. */
    47. onShareAppMessage() {
    48. }
    49. })

    二、案例界面设置 

    完成会议、个人中心页面的设计

    1、会议

    在上面已经拥有的基础上进行一个点击数据的展示

     在自定义组件的js文件里面进行方法的编写

    1. /**
    2. * 组件的方法列表
    3. */
    4. methods: {
    5. handleItemTap(e){
    6. // 获取索引
    7. const {index} = e.currentTarget.dataset;
    8. // 触发 父组件的事件
    9. this.triggerEvent("tabsItemChange",{index})
    10. this.setData({
    11. tabIndex:index
    12. })
    13. }
    14. }

    在会议的页面的wxml文件里面进行页面的编写

    1. <tabs tabList="{{tabs}}" bindtabsItemChange="tabsItemChange">
    2. </tabs>
    3. <view style="height: 100rpx;"></view>
    4. <block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id">
    5. <view class="list" data-id="{{item.id}}">
    6. <view class="list-img al-center">
    7. <image class="video-img" mode="scaleToFill" src="{{item.image}}"></image>
    8. </view>
    9. <view class="list-detail">
    10. <view class="list-title"><text>{{item.title}}</text></view>
    11. <view class="list-tag">
    12. <view class="state al-center">{{item.state}}</view>
    13. <view class="join al-center"><text class="list-num">{{item.num}}</text>人报名</view>
    14. </view>
    15. <view class="list-info"><text>{{item.address}}</text>|<text>{{item.time}}</text></view>
    16. </view>
    17. </view>
    18. </block>
    19. <view class="section">
    20. <text>到底啦</text>
    21. </view>

     在js文件的里面模拟假的数据

    1. /**
    2. * 页面的初始数据
    3. */
    4. data: {
    5. tabs: ['会议中', '已完成', '已取消', '全部会议'],
    6. lists: [
    7. {
    8. 'id': '1',
    9. 'image': '/static/persons/1.jpg',
    10. 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】',
    11. 'num': '304',
    12. 'state': '进行中',
    13. 'time': '10月09日 17:59',
    14. 'address': '深圳市·南山区'
    15. },
    16. {
    17. 'id': '1',
    18. 'image': '/static/persons/2.jpg',
    19. 'title': 'AI WORLD 2016世界人工智能大会',
    20. 'num': '380',
    21. 'state': '进行中',
    22. 'time': '10月09日 17:39',
    23. 'address': '北京市·朝阳区'
    24. },
    25. {
    26. 'id': '1',
    27. 'image': '/static/persons/3.jpg',
    28. 'title': 'H100太空商业大会',
    29. 'num': '500',
    30. 'state': '进行中',
    31. 'time': '10月09日 17:31',
    32. 'address': '大连市'
    33. },
    34. {
    35. 'id': '1',
    36. 'image': '/static/persons/4.jpg',
    37. 'title': '报名年度盛事,大咖云集!2016凤凰国际论坛邀您“与世界对话”',
    38. 'num': '150',
    39. 'state': '进行中',
    40. 'time': '10月09日 17:21',
    41. 'address': '北京市·朝阳区'
    42. },
    43. {
    44. 'id': '1',
    45. 'image': '/static/persons/5.jpg',
    46. 'title': '新质生活 · 品质时代 2016消费升级创新大会',
    47. 'num': '217',
    48. 'state': '进行中',
    49. 'time': '10月09日 16:59',
    50. 'address': '北京市·朝阳区'
    51. }
    52. ],
    53. lists1: [
    54. {
    55. 'id': '1',
    56. 'image': '/static/persons/1.jpg',
    57. 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】',
    58. 'num': '304',
    59. 'state': '已结束',
    60. 'time': '10月09日 17:59',
    61. 'address': '深圳市·南山区'
    62. },
    63. {
    64. 'id': '1',
    65. 'image': '/static/persons/2.jpg',
    66. 'title': 'AI WORLD 2016世界人工智能大会',
    67. 'num': '380',
    68. 'state': '已结束',
    69. 'time': '10月09日 17:39',
    70. 'address': '北京市·朝阳区'
    71. },
    72. {
    73. 'id': '1',
    74. 'image': '/static/persons/3.jpg',
    75. 'title': 'H100太空商业大会',
    76. 'num': '500',
    77. 'state': '已结束',
    78. 'time': '10月09日 17:31',
    79. 'address': '大连市'
    80. }
    81. ],
    82. lists2: [
    83. {
    84. 'id': '1',
    85. 'image': '/static/persons/1.jpg',
    86. 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】',
    87. 'num': '304',
    88. 'state': '已取消',
    89. 'time': '10月09日 17:59',
    90. 'address': '深圳市·南山区'
    91. },
    92. {
    93. 'id': '1',
    94. 'image': '/static/persons/2.jpg',
    95. 'title': 'AI WORLD 2016世界人工智能大会',
    96. 'num': '380',
    97. 'state': '已取消',
    98. 'time': '10月09日 17:39',
    99. 'address': '北京市·朝阳区'
    100. }
    101. ],
    102. lists3: [
    103. {
    104. 'id': '1',
    105. 'image': '/static/persons/1.jpg',
    106. 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】',
    107. 'num': '304',
    108. 'state': '进行中',
    109. 'time': '10月09日 17:59',
    110. 'address': '深圳市·南山区'
    111. },
    112. {
    113. 'id': '1',
    114. 'image': '/static/persons/2.jpg',
    115. 'title': 'AI WORLD 2016世界人工智能大会',
    116. 'num': '380',
    117. 'state': '已结束',
    118. 'time': '10月09日 17:39',
    119. 'address': '北京市·朝阳区'
    120. },
    121. {
    122. 'id': '1',
    123. 'image': '/static/persons/3.jpg',
    124. 'title': 'H100太空商业大会',
    125. 'num': '500',
    126. 'state': '进行中',
    127. 'time': '10月09日 17:31',
    128. 'address': '大连市'
    129. },
    130. {
    131. 'id': '1',
    132. 'image': '/static/persons/4.jpg',
    133. 'title': '报名年度盛事,大咖云集!2016凤凰国际论坛邀您“与世界对话”',
    134. 'num': '150',
    135. 'state': '已结束',
    136. 'time': '10月09日 17:21',
    137. 'address': '北京市·朝阳区'
    138. },
    139. {
    140. 'id': '1',
    141. 'image': '/static/persons/5.jpg',
    142. 'title': '新质生活 · 品质时代 2016消费升级创新大会',
    143. 'num': '217',
    144. 'state': '进行中',
    145. 'time': '10月09日 16:59',
    146. 'address': '北京市·朝阳区'
    147. }
    148. ]
    149. }

    在下面编写一个方法,用来获取对应的数据 

    1. tabsItemChange(e) {
    2. console.log(e)
    3. let tolists;
    4. if (e.detail.index == 0) {
    5. tolists = this.data.lists;
    6. } else if (e.detail.index == 1) {
    7. tolists = this.data.lists1;
    8. } else if (e.detail.index == 2) {
    9. tolists = this.data.lists2;
    10. } else {
    11. tolists = this.data.lists3;
    12. }
    13. this.setData({
    14. lists: tolists
    15. })
    16. }

     效果

    2、个人中心

    wxml

    1. <!--pages/ucenter/index/index.wxml-->
    2. <!-- <text>个人中心</text> -->
    3. <view class="user">
    4. <image class="user-img" src="/static/persons/1.jpg"></image>
    5. <view class="user-name">现在是</view>
    6. <text class="user-state">状态:😊</text>
    7. <text class="user-up">修改></text>
    8. </view>
    9. <view class="cells">
    10. <view class="cell-items">
    11. <image src="/static/tabBar/coding-active.png" class="cell-items-icon"></image>
    12. <text class="cell-items-title">我主持的会议</text>
    13. <text class="cell-items-num">99+</text>
    14. <text class="cell-items-detail">🆗</text>
    15. </view>
    16. <view style="height: 5rpx;background-color: rgba(135, 206, 250, 0.075);"></view>
    17. <view class="cell-items">
    18. <image src="/static/tabBar/sdk.png" class="cell-items-icon"></image>
    19. <text class="cell-items-title">我参与的会议</text>
    20. <text class="cell-items-num">99+</text>
    21. <text class="cell-items-detail"></text>
    22. </view>
    23. </view>
    24. <view style="height: 27rpx;background-color: rgba(135, 206, 250, 0.075);"></view>
    25. <view class="cells">
    26. <view class="cell-items">
    27. <image src="/static/tabBar/sdk.png" class="cell-items-icon"></image>
    28. <text class="cell-items-title">我发布的投票</text>
    29. <text class="cell-items-num">89</text>
    30. <text class="cell-items-detail">👍</text>
    31. </view>
    32. <view style="height: 5rpx;background-color: rgba(135, 206, 250, 0.075);"></view>
    33. <view class="cell-items">
    34. <image src="/static/tabBar/coding-active.png" class="cell-items-icon"></image>
    35. <text class="cell-items-title">我参与的投票</text>
    36. <text class="cell-items-num">8</text>
    37. <text class="cell-items-detail"></text>
    38. </view>
    39. </view>
    40. <view style="height: 27rpx;background-color: rgba(135, 206, 250, 0.075);"></view>
    41. <view class="cells">
    42. <view class="cell-items">
    43. <image src="/static/tabBar/template.png" class="cell-items-icon"></image>
    44. <text class="cell-items-title">信息</text>
    45. <text class="cell-items-ion"></text>
    46. </view>
    47. <view style="height: 5rpx;background-color: rgba(135, 206, 250, 0.075);"></view>
    48. <view class="cell-items">
    49. <image src="/static/tabBar/component.png" class="cell-items-icon"></image>
    50. <text class="cell-items-title">设置</text>
    51. <text class="cell-items-ion"></text>
    52. </view>
    53. </view>

     wxss

    1. /* pages/ucenter/index/index.wxss */
    2. Page {
    3. background-color: rgba(135, 206, 250, 0.075);
    4. }
    5. .user {
    6. display: flex;
    7. width: 100%;
    8. align-items: center;
    9. background-color: white;
    10. margin-bottom: 28rpx;
    11. }
    12. .user-img {
    13. height: 170rpx;
    14. width: 170rpx;
    15. margin: 30rpx;
    16. border: 1px solid #cdd7ee;
    17. border-radius: 6px;
    18. }
    19. .user-name {
    20. width: 380rpx;
    21. margin-left: 20rpx;
    22. font-weight: 550;
    23. }
    24. .user-state {
    25. color: rgb(136, 133, 133);
    26. }
    27. .user-up {
    28. color: rgb(136, 133, 133);
    29. }
    30. .cells {
    31. background-color: white;
    32. }
    33. .cell-items {
    34. display: flex;
    35. align-items: center;
    36. height: 110rpx;
    37. }
    38. .cell-items-title {
    39. width: 290rpx;
    40. }
    41. .cell-items-icon {
    42. width: 50rpx;
    43. height: 50rpx;
    44. margin: 20rpx;
    45. }
    46. .cell-items-num {
    47. padding-left: 30rpx;
    48. margin-left: 200rpx;
    49. width: 70rpx;
    50. }
    51. .cell-items-ion {
    52. margin-left: 295rpx;
    53. }

     效果

  • 相关阅读:
    Java面试题总结2023
    RKE2 config containerd private registry (rke2配置私有仓库地址)
    LuatOS-SOC接口文档(air780E)--dac - 数模转换
    【Linux】Linux下基本指令(一)
    SAP 电商云 Spartacus UI 的 Product Category Navigation UI 实现
    我的创作纪念日
    nginx.4——正向代理和反向代理(七层代理和四层代理)
    c语言练习41:深入理解字符串函数strlen strcpy strcat
    Linux—文件编程
    LeetCode155:最小栈,最简单的中等难度题,时间击败100%,内存也低于官方
  • 原文地址:https://blog.csdn.net/weixin_72997875/article/details/133903058