wx小程序(3) - 自定义组件及参数传输

组件化的项目开发中,组件应当划分为三个层次:组件、模块、页面
微信小程序已经为开发者封装好了基础组件,页面文件(pages)也有了详细的规定
而模块就需要自行开发,并且要和页面文件区分开,这就涉及到自定义组件

开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

一、基本用法

在根目录下创建一个 component 目录,用于存放自定义组件
组件也是由 json、wxml、wxss、js 四个文件组成

其中 wxml 部分没有什么特殊的地方,和页面的写法一致
wxss 也是只对组件生效,而且 app.wxss 中的样式也不会对自定义组件生效

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

#a { } /* 在组件中不能使用 */
[a] { } /* 在组件中不能使用 */
button { } /* 在组件中不能使用 */
.a > .b { } /* 除非 .a 是 view 组件节点,否则不一定会生效 */

最关键的地方在于,需要在 json 中添加配置项:将 component 字段设为 true,这样才能注册这个自定义组件

{
  "component": true, 
  "usingComponents": {}
}

usingComponents字段组件里面可以引入其他组件,在页面引用组件同样也需要在json设置这个字段

{
  "navigationBarTitleText": "登录",
  "usingComponents": {
    "toast": "../component/Toast/toast"
  }
}

然后就能在登录页面的 wxml 中直接使用该组件

二、组件间的参数传递

  • 组件的属性列表
    小程序的页面 pages 需要使用 Page() 来注册,而组件则需要 Component() 构造器

如果组件需要接受一个外部数据,比如一个列表组件的数据源 data,可以这么配置:

这里的** properties** 类似于 vue 中的 props,表示该对象下的属性将从外部传入
properties 可设置 type、value、observer 三个属性

其中 type 用于指定字段类型(Number,String,Array,Object,Function)
value 表示字段的默认值,observer 用于定义该字段的监听函数

在页面上调用组件的时候,直接给 data 赋值就好:<toast text="登录成功"></toast>

PS:开发中应当避免使用 data 为前缀的属性名(如 data-text),这会被识别为 dataset 中的参数

  • 组件事件触发回调
// toast.wxml
<view class="toast" style="{{ pos }}: 60rpx">
  <view class='text' catchtap='_tapEvent'>{{text}}</view>
</view>
// toast.js
methods: {
    // 私有方法:以下划线为前缀命名
    _tapEvent() {
      //触发tap回调(子组件调用父组件的方法)
      this.triggerEvent("tapEvent")
    }
}

// 然后在login调用组件的时候用tapEvent绑定_tapEvent方法
// login.wxml
<toast text="登录成功" pos="top" bind:tapEvent="_tapEvent"></toast>
// login.js
methods: {
    //tab事件
    _tapEvent() {
      console.log('你点击了一下');
    }
}

整个的流程是
我们在点击toast组件的时候,执行了catchtap='_tapEvent'方法,这个方法用了this.triggerEvent("tapEvent"),这种是类似广播或者是说自定义事件,触发了在login调用toast组件里面绑定的事件bind:tapEvent并执行了login.js里面定义的方法_tapEvent

  • 组件插槽(具名插槽)
    小程序的组件也可以使用 <slot> 来扩展内容
    然后父组件引入这个组件的时候,可以在组件中插入节点,节点内容会渲染到 <slot> 节点的位置

组件默认只能有一个 <slot>,如果需要添加多个插槽,首先需要在组件 js 中声明,这就是具名插槽。比较建议使用这个,因为很容易辨识你加入的节点会渲染指到那个<slot>里面

<view class='wx_dialog_container' hidden="{{!isShow}}">
    <view class='wx-mask'></view>
    <view class='wx-dialog'>
        <slot name="title"></slot>
        <view class='wx-dialog-content'>{{ content }}</view>
        <view class='wx-dialog-footer'>
          <view class='wx-dialog-btn' catchtap='_cancelEvent'>{{ cancelText }}</view>
          <view class='wx-dialog-btn' catchtap='_confirmEvent'>{{ confirmText }}</view>
        </view>
    </view>
</view>

<dialog id="dialog" title='提示' content="{{quickData}}" bind:cancelEvent="_cancelEvent"
   bind:confirmEvent="_confirmEvent">
    <view class='wx-dialog-title' slot="title">温馨提示</view>
  </dialog>

这样使用插槽之后title就可以随意在父组件进行修改,甚至设置其他元素,输入框、按钮、icon都是可以的

三、事件传参

在view中 ,我们用bindtap绑定了showDia方法,并且自定义data-name属性(使用过JQ的人会知道这种方法跟JQ的自定义属性取值是一样的)

<view class="float-item" wx:for="{{quick}}" wx:key="*this" data-name="{{item}}" bindtap='showDia'>
        <view class="icon"></view>
        {{ item }}
</view>
// 然后通过e.currentTarget.dataset可以拿到自定义的值
showDia(e) {
    console.log(e.currentTarget.dataset.name)
 },

这时候大家就可以看到上面说的,避免使用data作为前缀的属性名的原因了,
,data作为前缀的属性名会被dataset识别,混搅到自定义属性取值的使用

这里还有注意两点:
1、data-名称 不能有大写字母,如果需要,可以通过 - (中划线)来连接单词,编译的时候小程序会将第二个单词首字母自动大写。data-* 属性中不可以存放对象。
2、注意打印结果中target和currentTarget的区别。
- target 触发事件的源组件。
- currentTarget 事件绑定的当前组件。

四、URL 传参

如果需要页面跳转,那么就可以使用 navigateTo() 方法或者使用navigator标签的url属性 跳转页面,这样可以在 url 后面接 query 参数

wx.navigateTo({
   url: '../login/login?source=index'
})
// 或者
<navigator url="{{item.url + '?name=' + item.name}}"></navigator>

然后在 Page 页面的生命周期函数 onLoad 中可以接收到这些参数

onLoad: function (options) {
    console.log(options)
 }

这种方式只能通过 navigateTo方法或者navigator 标签发送,onLoad 接收
所以只能用于跳转到非 tabbar 的页面

五、简易动画

因为做组件的时候需要一下动画效果,所以顺便说下小程序封装好的动画函数wx.createAnimation()的使用
它创建一个动画实例animation,调用实例的方法来描述动画,最后通过动画实例的export方法导出动画数据传递给组件的animation属性。
注意: export 方法每次调用后会清掉之前的动画操作

// 首先我们需要在data里面定义一个参数来存放动画
data: {
    animationData: {}
 },
// 然后把参数用animation属性绑定到组件上,在哪使用就绑定在哪
<view class="toast" animation="{{animationData}}"></view>
methods: {
    // 公有方法
    show: function() {
      // 创建一个动画实例,可配置参数(持续时间,运动曲线,延时,设置transform-origin)
      var animation = wx.createAnimation({
        duration: 500,
        timingFunction: 'ease-out',
        // delay: 1000,
        // transformOrigin: 50% 50%
      })
      // animation有rotate旋转、scale缩放、translate偏移、skew倾斜等方法
      animation.translateY(100).rotate(360).scale(2, 2).step()
      this.setData({
        // 清掉前面动画操作
        animationData: animation.export()
      })
    }
}

然后可以在父组件调用toast里面的方法

// 调用前需要用获取toast,才可以使用toast组件里面的方法
onReady: function () {
      this.toast = this.selectComponent("#toast");
},
// 然后定义showToast
showToast() {
      this.toast.show()
},

今天写的涉及的一些api
自定义组件:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
事件传参:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
url传参:https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html
https://developers.weixin.qq.com/miniprogram/dev/api/ui-navigate.html#wxnavigatetoobject
动画函数:
https://developers.weixin.qq.com/miniprogram/dev/api/api-animation.html#wxcreateanimationobject

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

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,973评论 3 119
  • 22岁的圣诞平安夜,此时下午5点只觉蛋疼~理性思维~快速反应,内心平静~
    威尼斯雾阅读 143评论 0 0
  • 纸:巴比松300g 颜料:吴竹颜彩36色、开明白墨液 笔:黑天鹅圆头2号,温莎牛顿圆头4号,达芬奇3373 6号,...
    李小千阅读 1,372评论 14 29
  • 天堂里的人 你还好吗 小时候最爱的便是蜷缩在你的臂弯下 仿佛是这世上最安全的地方 呼吸着你的气息 酣酣睡去 天堂里...
    玉儿梵蒂冈阅读 464评论 0 3
  • 我做了一个决定,今天刚好是来上海的第四个月,我决定离开这里了,仿佛又开始了一段新的旅程,真的是一段全新的旅程,我要...
    骆驼小姐阅读 116评论 0 0