小程序学习笔记(二)——自定义组件

创建自定义组件

  1. 类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成。
  2. 在 json 文件中进行自定义组件声明(将 component 字段设为 true)。
  3. 在 wxss 中不应使用 ID 选择器、属性选择器和标签名选择器。
  4. 在 js 文件中,需要使用 Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法。组件的属性值和内部数据将被用于组件 wxml 的渲染,其中,属性值是可由组件外部传入的,需要声明类型和初始值。
  5. 组件的属性可以用于接收页面的参数,如访问页面/pages/index/index?paramA=123&paramB=xyz,如果声明有属性 paramAparamB ,则它们会被赋值为 123 或 xyz 。
自定义组件 JS 文件
Component({
  properties: {
    // 这里定义了innerText属性,属性值可以在组件使用时指定
    innerText: {
      type: String,
      value: 'default value',
    }
  },
  data: {
    // 这里是一些组件内部数据
    someData: {}
  },
  methods: {
    // 这里是一个自定义方法
    customMethod: function(){}
  }
})

使用自定义组件

  1. 需要在引用页面的 json 文件中进行引用声明,此时需要提供每个自定义组件的标签名和对应的自定义组件文件路径。
  2. 因为 WXML 节点标签名只能是小写字母、中划线和下划线的组合,所以自定义组件的标签名也只能包含这些字符。
  3. 自定义组件和页面所在项目根目录名不能以“wx-”为前缀,否则会报错。
使用自定义组件
// 引用页面json
{
  "usingComponents": {
    "component-tag-name": "path/to/the/custom/component"
  }
}

// 引用页面wxml
<view>
  <!-- 以下是对一个自定义组件的引用 -->
  <component-tag-name inner-text="Some text"></component-tag-name>
</view>

组件模板

  1. 可以使用数据绑定,向子组件的属性传递动态数据。
给子组件传值
<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name prop-a="{{dataFieldA}}" prop-b="{{dataFieldB}}">
    <!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
    <view>这里是插入到组件slot中的内容</view>
  </component-tag-name>
</view>
  1. 在组件模板中可以提供一个 节点,用于承载组件引用时提供的子节点。
slot 使用
<!-- 组件模板 -->
<view class="wrapper">
  <view>这里是组件的内部节点</view>
  <slot></slot>
</view>

<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
    <view>这里是插入到组件slot中的内容</view>
  </component-tag-name>
</view>
  1. 需要使用多 slot 时,可以在组件 js 中声明启用。在组件的 wxml 中使用多个 slot ,以不同的 name 来区分。
多个 slot
// 组件 JS
Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: { /* ... */ },
  methods: { /* ... */ }
})

<!-- 组件模板 -->
<view class="wrapper">
  <slot name="before"></slot>
  <view>这里是组件的内部细节</view>
  <slot name="after"></slot>
</view>

<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 -->
    <view slot="before">这里是插入到组件slot name="before"中的内容</view>
    <!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 -->
    <view slot="after">这里是插入到组件slot name="after"中的内容</view>
  </component-tag-name>
</view>

组件样式

  1. 组件对应 wxss 文件的样式,只对组件wxml内的节点生效。
  2. 组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。
  3. 组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
  4. 子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
  5. 除继承样式外(如 fontcolor), app.wxss 中的样式、组件所在页面的的样式、以及引入 iconfont 对自定义组件无效(除非更改组件样式隔离选项)。
  6. 引用父组件的样式:在组件中可以使用 ^ 来引用父组件类的样式。可以连续使用多个 ^ 来引用祖先组件中的样式。
    <view class="^red-text"> 这段文本是红色的 </view>

组件间通信

  1. WXML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据。
  2. 事件:用于子组件向父组件传递数据,可以传递任意数据。
  • 什么是事件?
    (1)事件是视图层到逻辑层的通讯方式。
    (2)事件可以将用户的行为反馈到逻辑层进行处理。
    (3)事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
    (4)事件对象可以携带额外信息,如 id, dataset, touches。

  • 监听事件:自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。

    监听事件
    <!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 -->
    <component-tag-name bindmyevent="onMyEvent" />
    <!-- 或者可以写成 -->
    <component-tag-name bind:myevent="onMyEvent" />
    
    Page({
      onMyEvent: function(e){
        e.detail // 自定义组件触发事件时提供的detail对象
      }
    })
    
    
  • 触发事件:自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项。

    触发事件
    <!-- 在自定义组件中 -->
    <button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>
    
    Component({
      properties: {},
      methods: {
        onTap: function(){
          var myEventDetail = {} // detail对象,提供给事件监听函数
          var myEventOption = {} // 触发事件的选项:bubbles,composed,capturePhase
          this.triggerEvent('myevent', myEventDetail, myEventOption)
        }
      }
    })
    
  1. 父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。
  • 调用时需要传入一个匹配选择器 selector,如:this.selectComponent(".my-component")。

    使用 selectComponent
    // 父组件
    Page({
      data: {},
      getChildComponent: function () {
        const child = this.selectComponent('.my-component');
        console.log(child)
      }
    })
    
    
posted @ 2022-03-15 17:19  shellon  阅读(143)  评论(0编辑  收藏  举报