技术栈

主页 > 前端开发 >

微信小程序填坑之---自定义组件

技术栈 - 中国领先的IT技术门户

自定义组件从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

前言

从去年开始接触了vue以后,就一发不可收拾,尤其是vue的一切皆组件的思想,通过数据的分离,将各功能模块组件化,也将代码再次解耦,写代码的效率提高了,思路也更清晰了,到了2017年,开始负责公司的小程序开发,在踩了无数的坑以后,也接连发布了两个项目,小程序也引用了vue的思路,数据绑定,页面模块分离,但是又不像vue那样能够自由的分离拆解各个组件,终于,就在半个月前,小程序开始了自定义组件的公测,我也在开发的新项目中第一时间引入了自定义组件,和以前一样,看着超级减配摸索版的官方文档,开始了小程序的又一个填坑之旅。

开始组件化

众所周知,小程序的页面都是采用了模块化的管理方式,每个页面都对应着四个文件,分别负责结构,逻辑,样式和基础配置,同样,自定义组件也保持着这样的结构,一个自定义组件由wxml,wxss,js,json,4个文件组成,如果想要在页面中引入相应的组件,首先,需要在该页面的json文件里写入一下配置:

{
  "component": true,
  "usingComponents":  {
    "component-Name":  "Path",
    ......
  }
}

同样,如果组件也是由更加细分的组件组成的话,配置是一样的,对应的,在上层的wxml里直接以标签的形式载入组件:

<component-Name></component-Name>

这样,一个自定义的组件就完成了,这个标签对应的内容就是该组件,以下面的这个页面为例:

产品展示的区域都是由组件构成的,分为三个组件,展示区域 > 标题 > 列表,列表还可以继续再分为两个组件,列表 > 列表内容,对于这种高复用性的内容,组件化可以极大的减少代码量和优化代码结构,例如,点开更多后的页面,就可以复用 列表 + 列表内容的组件,如果产品下方的区域还有动态展示,成交记录等等,都可以复用以上组件,但是,组件之间的数据传递时怎么进行的呢?

组件数据的传递

组件之间的数据传递分为很多种,例如,在上级组件传递数据、事件给下级页面,上级页面监听下级页面的事件回调,跨级的数据传递,例如,在首页将获取的产品列表数据传递给产品列表组件:

上级组件:

<component-list list-data="{{ListData}}"></component-list>

下级组件:

wxml:
  <view wx:for="{{ListData}}">
    <view class="item">{{item.data}}</view>
    ......
  </view>

js:
  Component({
    properties: {
    ListData: {
      type: Array,
      value: [],
      observer: function(newData, oldData){
        ......
      }
    }
  },
  data: {
    someData: {}
  },
  methods: {
    customMethod: function(){}
  }
})

可以看到,组件的写法和页面基本一样,只是Page变成了Component,这里要注意,只要是由上层组件传递过来的数据,都应该在properties里声明,数据类型是必须值,而observer则是监听数据变化后产生的事件,例如,上级页面的传递的值产生变化了,就可以在observer里捕获到两个值newData, oldData,在observer里可以调用该组件的methods,去做不同的操作。同样,组件也有生命周期,这点和page略有区别,文档里对这一点写的还是很详细的。可是,如果遇到跨组件的数据该怎么传递呢?

根据官方的说法,组件的事件是逐层传递的,并没有广播机制,这样的话就有些麻烦了,以上图为例,如果主页想要把数据传递给产品展示组件的列表组件的详情组件(有些绕),就要在每一层组件中都声明,然后把时间和数据进行逐层传递。

根据多组件数据传递的特性,可以将数据的标识,或者api向下传递,在组件中请求、渲染,这样对于复用率较高的组件来说比较便于管理,以此为例,home-show为下层组件,home-show里又包含了组件home-show-titlehome-list,只用传入相应的标识,即可将不同的数据在不同的组件里请求和渲染:

<home-show showTitle="产品展示" more="product" detailApi="{{ProductDetailApi}}" showList="{{info.EntProductModelList}}"></home-show>
<list loadApi="{{api}}" root="{{root}}" detailApi="{{detailApi}}" isRefresh="{{isRefresh}}"></list>
<view class="show_container">
  <home-show-title title="{{showTitle}}" more="{{more}}"></home-show-title>
  <home-list list="{{showList}}" detailApi="{{detailApi}}" isNews="{{isNews}}"></home-list>
</view>

组件事件

根据官方文档,引用组件的页面可以监听到组件中触发的任意事件,如下写法:

<!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />

可是在实际使用中发现,第一种方法貌似兼容性并不好,可以用如下的方式代替:

<component-tag-name bind:myevent="onMyEvent" />

在组件中触发事件时,可以使用triggerEvent方法,这个在文档里写的还算是清楚,就直接照搬了:

<!-- 在自定义组件中 -->
<button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>
Component({
  properties: {}
  methods: {
    onTap: function(){
      var myEventDetail = {} // detail对象,提供给事件监听函数
      var myEventOption = {} // 触发事件的选项
      this.triggerEvent('myevent', myEventDetail, myEventOption)
    }
  }
})

behaviors

behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的“mixins”或“traits”。
每个 behavior 可以包含一组属性、数据、生命周期函数和方法,组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。每个组件可以引用多个 behavior 。 behavior 也可以引用其他 behavior 。

关于behaviors,刚刚接触的时候还是云里雾里,通过在实际的使用中发现,它其实就是把不同的组件中需要单独定义的内容提取出来,可以在组件的js文件开头引用,就像引用任何一个库或者文件一样,import *** from ***,如果组件中有同名的属性或方法,会进行覆盖,后面的覆盖前面的,而数据则会进行合并,这点具体可参考文档字段的覆盖和组合规则,有了behaviors,自定义的组件的可能性又被延伸,可以根据业务需要进行不同的搭配

end

总的来说,微信开放了自定义组件,也再次开放了小程度,开发者可以更高效率和自由的进行开发,但是现在还在公测阶段,开发中要注意的问题还是挺多的,例如,通过组件里的wxss文件,可以定义组件的样式,但是自定义组件的样式还有一些规则,这点可以参考文档的组件模版和样式;在引用组件页面的json文件里,如果添加了usingComponents还会导致页面不正常,而且引用组件的路径也偶尔会不一致发生错误。。。

填坑持续进行中。。。

责任编辑:admin  二维码分享:
本文标签: 组件页面自定义homelistcomponent