微信小程序:自定义组件(Component)

微信小程序文档中提供的组件有限,一定程度上限制了开发需求,这里就需要我们自定义一些控件,实现开发需求。自定义控件有两种方式,一种是选择模板的方式,另一种是选择组件的方式来创建。这里我选择了组件方式来创建,这样只需引入组件和外部添加数据,内部展示数据,即可实现重用。


目前微信小程序提供的组件
1、文件目录结构

这里一定要注意我们目录结构,个人喜好把项目中的业务文件放在pages中,图片放在与pages同级的images文件中,第三方的sdk存放在libs文件中,工具类存放在utils文件中,同样把共用的自定义组件存放在同级的component文件中。这样便于管理,查找使用。


组件文件
2、自定义组件

微信小程序中没有select下拉选项框,这里选择组件的方式来自定义创建一个select组件。

在component文件目录下,创建一个select文件夹,随后select文件夹下手动创建:select.js、select.json、select.wxml、select.wxss 四个文件。(注意: 可以在select文件夹下自动创建上面👆四个文件,自动创建的文件会自动配置好代码。只需在引入组件的时候,在引入组件的页面的json文件中配置组件的名称和组件的位置即可。)

2.2、配置组件

select.js、select.json、select.wxml、select.wxss上面四个文件是是我们手动创建的,那就需要我们手动配置代码。在json文件中写入代码:"component": true 表示自定义组件声明,代码如下所示。

{
  "component": true
}

同时,js文件中也需要写成这种格式,其代码如下:

Component({
  /**
 1. 组件的属性列表
   */
  properties: {
    selectArray: {
      type: Array,
    },
     // 初始时要展示的内容
    currentText:{
      type:String,
    }
  },

  /**
 2. 组件的初始数据
   */
  data: {
    isShow: false, // 初始option不显示
    arrowAnimation: {} // 箭头的动画
  },

  /**
 3. 组件的方法列表
   */
  methods: {
    //option的显示与否
    selectToggleAction: function () {
      // 获取当前option显示的状态
      var nowShow = this.data.isShow;
      // 创建动画
      var animation = wx.createAnimation({
        timingFunction: "ease"
      })
      this.animation = animation;
      if (nowShow) {
        animation.rotate(0).step();
        this.setData({
          arrowAnimation: animation.export()
        })
      } else {
        animation.rotate(180).step();
        this.setData({
          arrowAnimation: animation.export()
        })
      }
      this.setData({
        isShow: !nowShow
      })
    },
    //设置内容
    selectItemAction: function (e) {
      // 当前option的数据是引入组件的页面传过来的,所以这里获取数据只有通过this.properties
      var nowData = this.properties.selectArray;
      var index = e.target.dataset.index; // 当前点击的索引
      var current_text = nowData[index].name; // 当前点击的内容
      var current_type = nowData[index].type; // 当前点击的内容
      // 再次执行动画,注意这里一定是this.animation来使用动画!!!!!!
      this.animation.rotate(0).step();
      this.setData({
        isShow: false,
        current_text: current_text,
        arrowAnimation: this.animation.export()
      })
      // 内容更新后,需要把更新的数据传输出去
      var nowDate = {
        id: index,
        name: current_text,
        type: current_type
      }
      // 这里的 getNowData 要和外部的 bind:getNowData ,名称一定要对应
      this.triggerEvent('getNowData', nowDate);
      console.log("选择之后的current_text", current_text);
    }
  }
})
  1. Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性、数据、方法等。
  2. properties是组件的对外属性,是属性名到属性设置的映射表,属性设置中可包含三个字段, type 表示属性类型、 value 表示属性初始值、 observer 表示属性值被更改时的响应函数。
  3. data 和普通页面的data一样,是组件的内部数据,和 properties 一同用于组件的模版渲染。
  4. methods组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用。在这里面获取数据有两种方法:一种是获取data里的数据: this.data.属性名;一种是获取 properties 中的属性值: this.properties.属性名。

注意!!!
如果还需要其他属性、数据、方法等可查看微信小程序官方文档 Component构造器

在wxml文件中,代码如下所示:

<view class='section-select-box'>
  <view class='select-content' bindtap='selectToggleAction'>
    <view class='select-text'>{{currentText}}</view>
    <image class='select-img' src='../../images/icon_arrow_down.png' animation="{{arrowAnimation}}"></image>
  </view>

  <view class='select-list' wx:if="{{isShow}}">
      <view class='select-list-item' wx:for="{{selectArray}}" data-index="{{index}}" wx:key='{{index}}' bindtap='selectItemAction'>{{item.name}}</view>
  </view>
</view>
  1. animation方法是为了获取当前点击元素的索引与内容。这里 animation="{{arrowAnimation}}"是箭头转动的动画效果。
  2. bindtap='selectToggleAction' selectToggleAction 方法是控制下拉选项框隐藏和显示的事件。
  3. bindtap='selectItemAction' selectItemAction 是下拉选项框选择子项之后,设置内容的事件。
  4. wx:if="{{isShow}}" isShow是为了控制 option 选项显示与隐藏。

在wxss文件中,代码如下所示:

.section-select-box {
  margin: 20rpx 30rpx;
  width: 690rpx;
}

.select-content {
  border: 2rpx solid #e2e2e2;
  border-radius: 10rpx;
  background: white;
  font-size: 34rpx;
  position: relative;
  height: 80rpx;
  line-height: 80rpx;
  padding: 0 10px;
}

.select-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 32rpx;
}

.select-img {
  position: absolute;
  right: 30rpx;
  top: 10rpx;
  width: 60rpx;
  height: 60rpx;
  transition: all .3s ease;
}

.select-list {
  background: white;
  width: inherit;
  position: absolute;
  border: 2rpx solid #e2e2e2;
  border-top: none;
  box-sizing: border-box;
  z-index: 3;
  max-height: 160rpx;
  overflow: auto;
}

.select-list-item {
  height: 30px;
  line-height: 30px;
  border-top: 2rpx solid #e2e2e2;
  padding: 0 10px;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
}

.select-list-item:first-child{
  border-top: none;
}
2.3、使用组件
  1. 使用自定义组件前,需要在引入组件的页面的json文件中配置,比如我要在 index.wxml 中引入,那么在 index.json 中我就需要配置:
{
  "usingComponents": {
    "Select": "/component/select/select"
  }
}

注意事项:
Select 是你定义的组件的名称,后面的是组件所在的位置。 / 单斜杠表示根目录,是绝对路径。

如果控制台报错,出现没找到路径的情况,一定是自己填写的路径不对,认真检查路径代码。


你可能出现的报错!!!

配置好后,在wxml引入组件,代码如下:

  <Select class="section-select" select-array='{{selectArray}}'  current-text="{{current_text}}" bind:getNowData='getCurrentTextAction'></Select>
  1. select-array 是我在组件中自定义的属性名,这个是和组件所在的 js 中properties中的属性是对应的。在 properties 定义的属性中,属性名采用驼峰写法例如:selectArray。在引入组件的 wxml 中,指定属性值时则对应使用连字符写法例如:select-array='{{selectArray}},selectArray为select组件中所需展示的数据源
  2. 这里getNowData是自定义的子组件需要触发的事件名,getNowData是引入组件的页面需要获取传过来的数据的自定义的事件名。
      // 内容更新后,需要把更新的数据传输出去
      var nowDate = {
        id: index,
        name: current_text,
        type: current_type
      }
      // 这里的 getNowData 要和外部的 bind:getNowData ,名称一定要对应
      this.triggerEvent('getNowData', nowDate);
      console.log("选择之后的current_text", current_text);

在引入组件的页面的js添加引入组件时,自定义的函数:

  getCurrentTextAction:function(e){
    let item = e.detail;
    this.setData({
      current_text: item.name, 
      current_type: item.type
    });
  }

console.log("打印数据",e.detail),传过来的值就在detail里面。

具体代码实现,稍后我会整理上传到我的GitHub,可以参考我的GitHub 上的代码。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 好吧,突然发现学不完了,一下子,那就分开吧,由于时间太久,直接重新大致复习了一下 微信小程序自定义组件微信小程序支...
    小小小8021阅读 2,597评论 0 9
  • 1.小程序起步 (1)点击https://mp.weixin.qq.com/wxopen/waregister?a...
    GXW_Lyon阅读 3,306评论 0 0
  • 因新工作主要负责微信小程序这一块,最近的重心就移到这一块,该博客是对微信小程序整体的整理归纳以及标明一些细节点,初...
    majun00阅读 7,312评论 0 9
  • HTML结构 Css样式 Js代码 特效展示
    西巴撸阅读 333评论 0 0
  • 过去的我,知识面狭窄,人生阅历肤浅,思维模式单一,在复杂的世界里遨游总是感到力不从心,面对方方面面的压力总是感到无...
    侠骨柔柔情阅读 825评论 0 0