微信小程序官网介绍!
本文提供给急需使用自定义组件人群,以下是博主个人理解和案例!可以辅助官网来看
从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。所有自定义组件相关特性都需要基础库版本 1.6.3 或更高。
开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。
类似页面,一个自定义组件由json ,wxml,wxss,js 4个文件组成
1、在根目录下自定义一个components文件夹,用来存放自定义的组件。
2、再针对每一个组件创建一个文件夹,用来存放这个组件相关的文件。、
在这里插入图片描述
在需要引入组件的页面的json文件中,在usingComponents里面写键值对,写组件名和路径
{"usingComponents": {//引用组件"cell": "/components/cell/cell","item": "/components/item/item"}
}
在需要引入组件的页面的wxml文件中,添加组件标签
- 使用item自定义组件
效果:
生命周期:lifetimes
组件的挂载: attach
数据:data
方法:methods
属性(只读):properties
外部类:externalClasses
选项:options
多个插槽:multipleSlots:true
组件的样式格式: styleIsolation:“isolated”
组件对应 wxss 文件的样式,只对组件 wxml 内的节点生效。编写组件样式时,需要注意以下几点:
1,组件和引用组件的页面不能使用 id 选择器(#a)、属性选择器([a])和标签名选择器,请改用 class 选择器。
2,组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
3,子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
4,继承样式,如 font 、 color ,会从组件外继承到组件内。
5,除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效(除非更改组件样式隔离选项)。
除此以外,组件可以指定它所在节点的默认样式,使用 :host 选择器(需要包含基础库 1.7.2 或更高版本的开发者工具支持)。
组件:cell.js
// components/cell/cell.js
Component({// 选项:options:{// 样式隔离:apply-shared 父影响子,shared父子相互影响, isolated相互隔离styleIsolation:"isolated",// 允许多个插槽multipleSlots:true,},
styleIsolation : " 值 ",
值:
apply-shared :父影响子
shared:父子相互影响
isolated:相互隔离
// 通过组件的外部类实现父组件控制子自己的样式externalClasses:["cell-class"],
在组件:cell.js 中定义外部类
我是cell组件
使用组件
|
在页面设组件样式
.mycell{line-height: 120rpx !important;color:#F70;
}
父组件
插槽内容
|
子组件
父组件com.wxml(页面)
🚒 🥗
|
子组件 cell.js
// 允许多个插槽
options:{ multipleSlots:true}
子组件 cell.wxml
允许多个插槽
options:{ multipleSlots:true}
父传子
property
子传参父
triggerEvent
组件 cell.js
/*** 组件的方法列表*/methods: {tapHd(){this.setData({count:this.data.count+1})// 发送一个事件this.triggerEvent("cellclick",this.data.count)}}
组件 cell.wxml 使用插槽
{{title}} {{count}}
此时还不能调用 setData
props
title:标题
icon :图标
tip :提示
url :跳转连接
open-type : 打开的方式
slot
right
left :插槽
event
click :事件
外部类itemClass :整体
titleClass :标题
item.js 代码:
// components/item/item.js
Component({options:{multipleSlots:true},externalClasses:["itemclass"],/*** 组件的属性列表*/properties: {// 标题title:{type:String,value:""},// 显示右侧插槽showrslot:{type:Boolean,value:false,},// 图标icon:{type:String,value:""},tip:{type:String,value:"",},badge:{type:[Boolean,Number],value:false},url:{type:String,value:""},openType:{type:String,value:"navigate"}},/*** 组件的初始数据*/data: {},/*** 组件的方法列表*/methods: {itemclick(e){console.log(e); //发送一个事件 this.triggerEvent("itemclick",e.detail)}}
})
组件 item.json
{"component": true,"usingComponents": {}
}
组件 item.wxml
{url}}" open-type="{{openType}}" bindtap="itemclick">{icon}}">{icon}}" mode="aspectFill"> {title}}">{{title}} {!showrslot}}">{{tip}} {badge}}">{badge===true}}" class="dot"> {{badge}}
组件 item.wxss 代码:
/* components/item/item.wxss */
.item{line-height: 88rpx;display: flex;align-items: center;justify-content: space-between;
}
.icon{margin-left: 30rpx;margin-right: 30rpx; height: 100%;display: flex;align-items: center;
}
.icon image{width: 60rpx;height: 60rpx;
}
.content{padding: 0 30rpx;border-bottom: 1rpx solid #ccc;display: flex;flex:1;}
.title{flex:1;color:#333;font-size: 32rpx;
}
.right{display: flex;align-items: center;
}
.right .arrow{height: 30rpx;width: 30rpx;border-top:3rpx solid #999;border-right: 3rpx solid #999;transform: rotate(45deg);
}.tip{color:#999;font-size: 24rpx;
}
.dot{height: 14rpx;width: 14rpx;background-color: #f00;border-radius: 12rpx;margin-left: 15rpx;}
.redbadeg{font-size: 18rpx;color:#fff; border-radius: 18rpx;background-color: #f00;max-height: 30rpx;width: 30rpx;line-height: 30rpx;text-align: center;margin-left: 15rpx;
}
com.js 代码如下:
// pages/com/com.js
Page({/*** 页面的初始数据*/data: {},cellHd(e){console.log(e);wx.showToast({title: '你点击了'+e.detail,})},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函数--监听页面隐藏*/onHide() {},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
})
com.json 代码如下:
{
"usingComponents": {
"cell":"/components/cell/cell",
"item":"/components/item/item"
}
}
com.wxml 代码如下:
- {true}}" tip="3条未读">
- {12}}" tip="12条未读">
- {true}}">
插槽title
-
-
- {true}}" itemclass="myitem">
{5}}">
| -->
com.wxss 代码如下:
/* pages/com/com.wxss */
.title{line-height: 88rpx;background-color: #f0f0f0;padding: 0 15rpx;
}
.cell{color:red;
}
.mycell{line-height: 120rpx !important;color:#F70;
}.myitem{line-height: 200rpx !important;background-color: #F0f0f0;}
wx.getMenuButtonBoundingClientRect() —— 胶囊的边界
wx.getSystemInfoSync(); —— 系统信息(状态栏的高度)
配置自定义状态栏
两个图标
back.svg
home.svg
// components/nav/nav.js
Component({/*** 组件的属性列表*/properties: {"title":{type:"string",value:""},"color":{type:"string",value:"#fff"}},/*** 组件的初始数据*/data: {statusBarHeight:20,barHeight:44,pagesLen:0,},lifetimes:{attached(){// 获取系统信息var info = wx.getSystemInfoSync();console.log(info);// 更新状态栏的高度this.setData({statusBarHeight:info.statusBarHeight})// 胶囊的位置const res = wx.getMenuButtonBoundingClientRect()console.log(res);// 标题栏可以使用的宽度(排除右侧胶囊的位置)this.setData({titleWidth:res.left});// 标题栏高度var barHeight = res.height+(res.top-info.statusBarHeight)*2;this.setData({barHeight});// 获取当前页var pages = getCurrentPages();console.log(pages);//更新页面的长度this.setData({pagesLen:pages.length})}},/*** 组件的方法列表*/methods: {goBack(){wx.navigateBack()},goHome(){wx.navigateBack({// 返回历史的长度为总页面数delta: this.data.pagesLen,})}}
})
{"component": true,"usingComponents": {}
}
{statusBarHeight}}px; height: {{barHeight}}px;">{titleWidth}}px; height: {{barHeight}}px; color: {{color}};">{pagesLen>1}}" bindtap="goBack" > {{title}} {{pagesLen}}
/* components/nav/nav.wxss */
.nav{background-image: linear-gradient(90deg, rgb(96, 197, 236), rgb(37, 125, 197));position: sticky;
}
.nav .bar{box-sizing: border-box;padding: 0 7px;display: flex;align-items: center;}
.btn{display: flex; align-items: center;}
.btn>view{height: 40px;width: 40px;text-align: center;display: flex;align-items: center;justify-content: center;
}
.btn image{height: 22px;width: 22px;align-items: center;
}
.btn .back { border-right: 1rpx solid rgba(255,255,255,.5); height: 22px;}
// pages/navpa/navpa.js
Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函数--监听页面隐藏*/onHide() {},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
})
{"usingComponents": {"nav":"/components/nav/nav"},"navigationStyle":"custom"
}
/* pages/navpa/navpa.wxss */
/* 空 */