微信小程序自定义组件,自定义组件

作者:计算机知识

组件化的档案的次序支付中,组件应当划分为多个等级次序:组件、模块、页面

零件的概念

  • 配备文件
    • 要编写三个自定义组件,首先须求在json文件中张开自定义组件表明(将 component 字段设为true )。
    • 运用用已登记的自定义组件前,首先要在页面包车型地铁json文本中举办引用评释。此时急需提供各样自定义组件的标签名和呼应的自定义组件文件路径(标签名称只好是小写字母、中划线和下划线的结缘,组件根目录名无法以“wx-”为前缀)。
//自定义组件component.json
{
  "component": true
}

//引用自定义组件的页面 page.json
{
  "usingComponents": {
    "component-tag-name": "../component/component"
  }
}
  • wxml文件
    在组件模板中得以提供一个 <slot> 节点,用于承载组件引用时提供的子节点。默许情况下,一个组件的wxml中只好有2个slot。需求采取多slot时,能够在组件js中申明启用options: {multipleSlots: true },以差别的 name 来区分。
<!-- 这是自定义组件的内部WXML结构(component.wxml)-->
<view class='wapper'>
  <text>this is component</text>
  <slot name="slot1"></slot>
  我在中间
  <slot name="slot2"></slot>
</view>

<!-- 以下是对一个自定义组件的引用 (page.wxml)-->
<view>
  <text>This is Page</text>
  <component-tag-name inner-text="Some text" class="page-component">
    <view slot="slot1" class="slot">来自page页面,通过slot标签</view>
    <view slot="slot2"></view>
  </component-tag-name>
</view>
  • wxss文件
//component.wxss
.wapper{
  background-color:#ccc;
  width: 100%;
  height:auto;
}
.slot{
  color:red;
}

//page.wxss
.page-component{
  color:#fff;//有效,继承样式
  padding:10px;//无效
}
.slot{
  color:green;
}
  • js文件
//component.js
Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: {
    // 这里定义了innerText属性,属性值可以在组件使用时指定
    innerText: {
      type: String,
      value: 'default value', //不存在此属性时
    }
  },
  data: {
    // 这里是一些组件内部数据
    someData: {}
  },
  methods: {
    // 这里是一个自定义方法
    customMethod: function(){}
  }
})

Component构造器API

图片 1

微信小程序自定义组件,自定义组件。零件的定义

通过下面的代码和呈现结果能够观察:

  1. slot样式受page.wxss里的.slot潜移默化显示黑褐,不受component.wxss.slot影响展现黄色。
  2. 继续样式,如 font 、 color ,会从组件外继续到零部件内。除继续样式外, app.wxss 中的样式、组件所在页面包车型客车的体制对自定义组件无效。例子中.page-componentcolor:#fff能生效,而padding则不奏效。

前言

壹伊始看官方网站,看的一脸茫然,后来看了下外人的,才总算知道微信小程序的零件怎么支付了

微信小程序已经为开辟者封装好了基础零部件,页面文件(pages)也会有了详实的鲜明

Page与Component数据交互

Tip:page代指导用组件页面,component代指自定义组件

  • page > component
  1. page在引用组件时能通过属性值设置,component.js在properties获取。
  2. page在引用组件时通data-xxx设置,component.js在this.dataset获取。
<!-- page.wxml -->
<component-tag-name fromPage="来自Page" data-other="from dataset"></component-tag-name>

Component({
  properties: {
    formPage: String  //简写
    /*
    myProperty: { // 属性名
      type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
      value: '', // 属性初始值(可选),如果未指定则会根据类型选择一个
      observer: function(newVal, oldVal){} // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange'
    }
    */
  },
  attached:function(){
    console.log(this.properties.fromPage);
    console.log(this.data.fromPage); //用data也能访问properties
    //设置properties值用setData()
    this.setData({
      fromPage: '改变了'
    });
    console.log(this.properties.fromPage);
    //通过dataset获取data-other的值
    console.log(this.dataset.other);
  }
})

调整台打字与印刷如下

来自Page
来自Page
改变了
from dataset
  • component > page
    零件中的变量要传递到page页面能够因而事件触发this.triggerEvent();来实行
<!-- page.wxml -->
<!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />

<!--component.wxml -->
<!-- 在自定义组件中 -->
<button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>

//page.js
Page({
  onMyEvent: function(e){
    console.log(e.detail.msg);
  }
})

//component.js
Component({
  methods: {
    onTap: function () {
      var myEventDetail = {msg:'来自component的信息'} // detail对象,提供给事件监听函数
      var myEventOption = {} // 触发事件的选项
      this.triggerEvent('myevent', myEventDetail, myEventOption)
    }
  }
})

点击component组件,调节台出口入下

来自component的信息

前不久接触微信小程序,再度在此以前公司用的前端框架是vue ,然后比较开掘,开辟小程序是种种限制,对于开垦者特别不友善。各类槽点太多,完全嘲弄可是来,所以在此不多说,筹划下一次特意写1篇小说嘲笑一下。这一次重大分享下小程序自定义组件的一点思路,小程序合法提供的框架比较简陋,原始,可复用较差,未有落到实处自定义组件的功用,那让无数应用vue ,react前端开发非常相当的慢。网络存在各个嘲讽,也可能有分享完结自定义组件的办法,然而还是过于复杂,要么是微信小程序升级之后就不包容,反正是各类坑你没斟酌。在那分享下本身在类型中是怎么样兑现的,迎接指正商议,互相学习。

效果图

图片 2

blue.jpg

图片 3

red.jpg

新建一个component文件夹,在文件夹下创设rowBox文件夹,再各自创立wxml,wxss,json,js八个文件。

图片 4

目录

而模块就供给活动开拓,并且要和页面文件分别开,那就提到到自定义组件

behaviors

behaviors 是用于组件间代码共享的性状。种种 behavior 可以分包1组属性、数据、生命周期函数和格局,组件引用它时,它的特性、数据和方法会被统一到零部件中,生命周期函数也会在对应时机被调用。各种组件能够引用多个behavior 。 behavior 也能够引用别的 behavior 。
behavior 必要使用 Behavior() 构造器定义。

// my-behavior.js
module.exports = Behavior({
  behaviors: [],
  properties: {
    myBehaviorProperty: {
      type: String
    }
  },
  data: {
    myBehaviorData: {}
  },
  attached: function(){},
  methods: {
    myBehaviorMethod: function(){}
  }
})

组件引用时,在behaviors定义段中校它们每一个列出就可以。

// my-component.js
var myBehavior = require('my-behavior')
Component({
  behaviors: [myBehavior],
  properties: {
    myProperty: {
      type: String
    }
  },
  data: {
    myData: {}
  },
  attached: function(){},
  methods: {
    myMethod: function(){}
  }
})

在上例中,my-component中最终包含myBehaviorPropertymyProperty三个性子,myBehaviorDatamyData四个数据字段,和myBehaviorMethodmyMethod三个办法。当组件触发attached生命周期时,会相继触发my-behavior中的attached生命周期函数和my-component中的attached生命周期函数。

组件和它引用的 behavior 中得以分包同名的字段,对那么些字段的管理办法如下:

  • 如若有同名的本性或措施,组件自个儿的属性或方法会覆盖 behavior 中的属性或艺术,借使引用了多少个 behavior ,在概念段中靠后 behavior 中的属性或方法会覆盖靠前的性质或措施;
  • 举个例子有同名的数目字段,即便数额是目的类型,会进展对象合并,假使是非对象类型则会开始展览互动覆盖;
  • 生命周期函数不会相互覆盖,而是在相应触发时机被逐一调用。若是同一个behavior 被3个零部件数次引用,它定义的生命周期函数只会被执行3回。

toast自定义组件完结

rowBox


wxss

.bg_red{
  background: #ff5d68;
}
.bg_blue{
  background: #cbd1f5;
}
.bg_purple{
  background: #cfb3e3;
}
.bg_pink{
  background: #fcd6c6;
}

/* 头部 start*/
.row-box .headline_box{
  font-size: 36rpx;
  width:94%;
  height:90rpx;
  line-height: 100rpx;
  border-radius: 5rpx;
  margin: 30rpx 3% 0;
  color: #ffffff;
  box-shadow: 0 4rpx 10rpx 0 rgba(0, 0, 0, 0.2), 0 6rpx 15rpx 0 rgba(0, 0, 0, 0.19); 
    animation:headline_box 1s 0.5s linear 1;
  -webkit-animation:headline_box 1s 0.5s  linear 1;
}
@keyframes headline_box{
    from{transform:rotateX(180)}
    to{transform:rotateX(360deg)}
}
@-webkit-keyframes headline_box{
    from{transform:rotateX(180)}
    to{transform:rotateX(360deg)}
}
.row-box .headline_box .headline_img{
  width:100rpx;
  height:90rpx;
  margin:0 20rpx;
}
.row-box .headline_box .tilte{
  font-weight: 600;
}
.row-box .morebtn{
  float: right;
  margin-right: 3%;
  height: 90rpx;
  line-height: 115rpx;
  font-size:26rpx;
}
/* 头部 end*/

/* 列表1 start */
.row-box .flex_row1{
   width:97%;
   padding-right: 4%;
   background: #ffffff;
   overflow-y: auto;
   padding-bottom: 20rpx;
}
.row-box .flex_row1 .flex-item{
  float: left;
  width: 42.2%;
  height: 330rpx;
  margin: 20rpx 2% 10rpx 5%;
  border-radius:10rpx;
  background: #ffffff;
  border: 1rpx solid #dcdcdc;
    animation:flex-item 0.5s  linear 1;
  -webkit-animation:flex-item 0.5s  linear 1;
}
@keyframes flex-item{
    from{opacity: 0; transform:scale(0)}
    to{opacity: 0.8;transform:scale(1)}
}
@-webkit-keyframes flex-item{
    from{opacity: 0; transform:scale(0)}
    to{opacity: 0.8;transform:scale(1)}
}
.row-box .flex_row1 .flex-item image{
  width: 100%;
  height: 200rpx;
  border-radius: 10rpx 10rpx 0 0;
}
.row-box .flex_row1 .theme{
  width: 92%;
  height: 70rpx;
  font-size: 28rpx;
  margin: 5rpx 4%;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.row-box .flex_row1 .tag{
  color: #888;
  font-size: 22rpx;
  padding: 0 5%;
}
/* 列表1 end */

/* 列表2 start*/
.row-box .flex_row2{
   width:100%;
   background: #ffffff;
   overflow-y: auto;
   padding-bottom:20rpx;
}
.row-box .flex_row2 .flex-item{
  width: 90%;
  height: 150rpx;
  margin: 20rpx 5% 10rpx;
  background: #ffffff;
  border-radius: 10rpx 10rpx 0 0;
    animation:flex-item 0.5s  linear 1;
  -webkit-animation:flex-item 0.5s  linear 1;
}
@keyframes flex-item{
    from{opacity: 0; transform:scaleX(0)}
    to{opacity: 0.8;transform:scaleX(1)}
}
@-webkit-keyframes flex-item{
    from{opacity: 0; transform:scaleX(0)}
    to{opacity: 0.8;transform:scaleX(1)}
}
.row-box .flex_row2 .flex-item image{
  width: 45%;
  height: 150rpx;
  border-radius:10rpx;
}
.row-box .flex_row2 .item-right{
  float: right;
  width: 49%;
  padding:0 2% 0 3%;
}
.row-box .flex_row2 .theme{
  width: 100%;
  height: 55rpx;
  font-size: 30rpx;
  overflow: hidden;
  white-space: nowrap; 
  text-overflow:  ellipsis; 
}
.row-box .flex_row2 .state{
  color: #888;
  font-size: 22rpx;
  padding: 0 2%;
  height: 86rpx;  
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}
/* 列表2 end*/

wxml

<view class='row-box'>
<block wx:if="{{type == 'red'}}">
   <view class='headline_box bg_red'>
    <image src='../../img/red.jpg' class='headline_img' bindtap='addCityEvent'></image>
    <text class='tilte'>{{title}}</text>
    <navigator class="morebtn" url="{{url}}">查看全部></navigator>  
   </view>
    <view class="flex_row1">
      <view class="flex-item" wx:for="{{items}}" wx:key="index" >
        <navigator url="{{item.url}}">
          <image src='{{item.img}}'></image>
          <view class='theme'>{{item.theme}}</view>
          <text class='tag'>{{item.tag}}</text>
        </navigator>
      </view>
    </view>
</block>

<block wx:else>
  <view class='headline_box bg_blue'  wx:if="{{type == 'blue'}}"> 
    <image src='../../img/blue.jpg' class='headline_img'></image>
    <text  class='tilte'>{{title}}</text>
    <navigator class="morebtn" url="{{url}}">查看全部></navigator>  
  </view>
  <view class='headline_box bg_purple' wx:if="{{type == 'purple'}}"> 
    <image src='../../img/purple.jpg' class='headline_img'></image>
    <text  class='tilte'>{{title}}</text>
    <navigator class="morebtn" url="{{url}}">查看全部></navigator>  
  </view>
  <view class='headline_box bg_pink' wx:if="{{type == 'pink'}}"> 
    <image src='../../img/pink.jpg' class='headline_img'></image>
    <text  class='tilte'>{{title}}</text>
    <navigator class="morebtn" url="{{url}}">查看全部></navigator>  
  </view>

  <!-- 列表 -->
  <view class="flex_row2">
    <view class="flex-item" wx:for="{{items}}"  wx:key="index">
      <image src='{{item.img}}'></image>
      <view class='item-right'>
        <view class='theme'>{{item.theme}}</view>
        <view class='state'>{{item.state}}</view>
      </view>
    </view> 
  </view>

</block>
</view>

js

Component({
  options:{
    multipleSlots: true
  },
  properties:{
    type: {
      type: String,
      value: '类型',
    },
    title: {
      type: String,
      value: '标题',
    },
    url: {
      type: String,
      value: '地址',
    },
    items: {
      type: Array,
      value: '标题',
    },
  },
  data: {
  },
  methods: {
  }
})

 

组件间关系

多少个自定义组件间的嵌套关系(parent父 / child 子/ ancestor祖先 / descendant子孙),通过relations 定义段来互相间的通信(必须在多个零件定义中都加盟relations定义,不然不会生效)。

<!-- page.wxml -->
<custom-ul>
  <custom-li> item 1 </custom-li>
  <custom-li> item 2 </custom-li>
</custom-ul>

<!-- component.wxml -->
<view class='wapper'>
  <text>custom-ul</text>
  <slot></slot>
</view>


<!-- children-component.wxml -->
<view>
  <text>li-item</text>
  <slot></slot>
</view>

//page.json
{
  "usingComponents": {
    "custom-ul": "../component/component",
    "custom-li": "../component/children-component"
  }
}

//component.json
{
  "component": true
}

//children-component.json
{
  "component": true
}

//component.js
Component({
  relations:{
    'children-component': {  //子组件相对路径
      type: 'child', // 关联的目标节点应为子节点
      linked: function (target) {
        // 每次有custom-li被插入时执行,target是该节点实例对象,触发在该节点attached生命周期之后
        console.log('--linked--');
        console.log(target);
      },
      linkChanged: function (target) {
        // 每次有custom-li被移动后执行,target是该节点实例对象,触发在该节点moved生命周期之后
      },
      unlinked: function (target) {
        // 每次有custom-li被移除时执行,target是该节点实例对象,触发在该节点detached生命周期之后
      }
    }
  },
  methods: {
    _getAllLi: function () {
      // 使用getRelationNodes可以获得nodes数组,包含所有已关联的custom-li,且是有序的
      var nodes = this.getRelationNodes('children-component');
      console.log('--getAllLi--');
      console.log(nodes);
    }
  },
  ready: function () {
    this._getAllLi()
  }
})


//children-component.js
Component({
  data:{
    name: 'name'
  },
  relations: {
    'component': {  //父组件相对路径
      type: 'parent', // 关联的目标节点应为父节点
      linked: function (target) {
        // 每次被插入到custom-ul时执行,target是custom-ul节点实例对象,触发在attached生命周期之后
      },
      linkChanged: function (target) {
        // 每次被移动后执行,target是custom-ul节点实例对象,触发在moved生命周期之后
      },
      unlinked: function (target) {
        // 每次被移除时执行,target是custom-ul节点实例对象,触发在detached生命周期之后
      }
    }
  }
})

图片 5

页面彰显

图片 6

console

  • 此处用最简便的toast组件为例子
  • 法定框架只提供了 页面模板成效 : WXML提供模板(template),能够在模板中定义代码片段,然后在差异的地点调用。
  • 可是这一个效率不 帮助js,样式封装,要求在对应的页面做管理,且模板还有团结的功用域,须求使用data传入。
  • 把成效封装成独立的机件,须求和页面独立,在应用时将零件挂载到对应的页面,所以组件须求传入页面this(Page)对象 ,完成代码如下

index (注:要引用组件的文本)


wxml

<rowBox id="rowBox" title='推荐' type='red' url='#' items='{{recommends}}'></rowBox>
<rowBox id="rowBox" title='游戏' type='blue' url='#' items='{{games}}'></rowBox>

json

{
  "usingComponents": {
    "rowBox": "/component/rowBox/rowBox"     
  }
}

 

官网API

图片 7

说了那样多,官方网站基本都有

微信小程序-自定义组件

目录结构

1、基本用法

|------components
        |------toast
                |------toast.js
                |------toast.wxml
                |------toast.wxss

在根目录下创设3个 components 目录,用于存放自定义组件

代码

组件也是由 json、wxml、wxss、js 多少个文件组成

toast.wxml

图片 8

<template name='toast'>
  <view class="s-toast" wx:if="{{msg}}">
    <view class="s-toast-content">{{msg}}</view>
  </view>
</template>

当中 wxml 部分从没怎么异样的地点,和页面包车型大巴写法一致

toast.js

wxss 也是只对组件生效,与此同时 app.wxss 中的样式也不会对自定义组件生效

/**
 * toastMsg 必传 提示内容
 * showTime 非必传 显示时间秒
*/
function toast(page, toastMsg, showTime) {
  let timer
  page.setData({ toastMsg })
  showTime = showTime || toastMsg.length / 4
  console.log(showTime)
  clearTimeout(timer)
  timer = setTimeout(() => {
    page.setData({ toastMsg: '' })
    clearTimeout(timer)
  }, showTime * 1000)
}

module.exports = {
  toast: toast,
}
toast.wxss
.s-toast-content {
  position: fixed;
  left: 50%;
  color: #fff;
  width: 500rpx;
  bottom: 120rpx;
  background: hsla(0,0%,7%,.7);
  padding: 15rpx;
  text-align: center;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
  border-radius: 4rpx;
  z-index: 6999;
}

最注重的地点在于,须求在 json 中增进配置项:

利用方式

将 component 字段设为 true,那样能力注册这几个自定义组件

壹、wxml引用页面模板

图片 9

二、js 文件引用 toast.js

 

import { toast } from '../../../project/component/toast/toast.js'

本文由bwin必赢发布,转载请注明来源

关键词: 必赢国际bwin 微信小程序 前端项目