目录:
注:详情使用方法见官方文档:微信开放文档/开发-自定义组件
小程序基础组件见文章- 微信小程序开发-各组件
开发者常见的自定义组件有两种:
1、公共组件: 将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;
2、页面组件: 将复杂的页面拆分成多个低耦合的模块,有助于代码维护。
自定义组件在使用时与基础组件非常相似。
一、自定义组件-创建、注册、使用组件
1、创建自定义组件:
- 如果是公共组件,建议放在项目根目录的 components 文件夹中
- 如果是页面组件,建议放在对应页面的目录下
建议: 一个组件一个文件夹
自定义组件创建完成后,还不能使用,需要进行注册
2、注册自定义组件:
- 如果是公共组件,需要全局注册: 在 app.json 文件中配置 usingComponents 进行注册,注册后可以在任意页面使用
- 如果是页面组件,需要局部注册: 在 .json 文件中配置 usingComponents 进行注册,注册后只能在当前页面使用
在 usingComponents 中进行组件注册时,需要提供自定义组件的组件名和自定义组件文件路径
3、使用自定义组件:
将组件注册注册好以后,直接将 自定义组件的组件名 当成 组件标签名 使用即可
二、自定义组件的数据、方法和属性 properties
自定义组件的数据以及方法需要在组件.js文件中的 Component 方法中进行定义。
Component 构造器可用于定义组件,调用 Component 构造器时可以指定组件的属性、数据、方法等
1、data: 定义组件的内部需要使用的数据
2、methods: 在组件中事件处理程序需要写到 methods 中
3、properties: 是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据,和 data 一同用于组件的模板渲染
app.json 文件代码示例:
"usingComponents": {
"custom-checkbox": "./components/custom-checkbox/custom-checkbox"
}
page.wxml 文件代码示例:
<!--
label:文本显示的内容
position:控制文本显示的位置
-->
<custom-checkbox label="我已阅读并同意 用户协议 和 隐私协议" position="right" />
<view></view>
<custom-checkbox label="匿名提交" position="left" />
custom-checkbox.wxml 文件代码示例:
<view class="custom-checkbox-container">
<view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left'}}" >
<checkbox class="custom-checkbox" checked="{{ isChecked }}" bind:tap="updateChecked"/>
<view>
<text>{{ label }}</text>
</view>
</view>
</view>
custom-checkbox.js 文件代码示例:
Component({
/**
* 组件的属性列表:是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据与属性
*/
properties: {
// 如果需要传递的是属性,有两种方式:简写和全写
// 简写:
// label: String
// 全写:
label: {
// type 组件使用者传递的数据类型,是必填项
// 数据类型:String、Number、Boolean、Object、Array
// 也可以设置为 null,表示不限制类型
type: String,
// value 属性值为默认值
value: ""
},
position: {
type: String,
value: "right"
}
},
/**
* 组件的初始数据:定义组件的内部需要使用的数据
*/
data: {
isChecked: false
},
/**
* 组件的方法列表:在组件中事件处理程序需要写到 methods 中可以
*/
methods: {
// 更新复选框的状态
updateChecked() {
this.setData({
isChecked: !this.data.isChecked,
// 在 JS 中可以访问和获取 properties 中的数据,但一般情况下不建议修改,因为会造成数据流的混乱
// label: '在组件内部也可以修改 properties 中的数据'
})
console.log(this.properties.label)
}
}
})
custom-checkbox.scss 文件代码示例:
.custom-checkbox-container {
display: inline-block;
}
.custom-checkbox-box {
display: flex;
align-items: center;
}
.custom-checkbox-box.left {
flex-direction: row-reverse;
}
.custom-checkbox-box.right {
flex-direction: row;
}
.custom-checkbox {
margin-left: 10rpx;
}
三、自定义组件的 slot-插槽
在使用基础组件时,可以在组件中间写子节点,从而将子节点的内容展示到页面中,自定义组件也可接收子节点。
只不过在自定义组件模板中,需要定义 <slot />
节点,用于承载组件中间的子节点
默认情况下,一个组件的 wxml 中只能有一个 slot (默认卡槽)。需要使用多 slot 时,可以在组件 js 中声明启用。
同时需要给 slot 添加 name 属性,以不同的 name 来区分不同的 slot(具名卡槽)。
然后给子节点内容添加 slot 属性,属性值是对应 slot 的 name 名称,从而将内容插入到对应的 slot 中。
app.json 文件代码示例:
"usingComponents": {
"custom01": "./components/custom01/custom01"
}
page.wxml 文件代码示例:
<custom01>
<!-- 默认情况下,自定义组件的子节点不会展示,如果内容需要展示,需要在组件模板中定义 slot 节点 -->
<text slot="slot-top">我需要显示到顶部-具名卡槽</text>
我是子节点内容--默认卡槽
<text slot="slot-bottom">我需要显示到底部-具名卡槽</text>
</custom01>
custom01.wxml 文件代码示例:
<!-- slot 就是用来接收子节点内容 -->
<!-- slot 只是一个占位符,子节点内容会将 slot 替换 -->
<view>
<!-- 具名卡槽 -->
<slot name="slot-top" />
<!-- 默认卡槽 -->
<view><slot /></view>
<!-- 具名卡槽 -->
<slot name="slot-bottom" />
</view>
custom01.js 文件代码示例:
Component({
options:{
// 启用多slot支持
multipleSlots: true
}
})
四、自定义组件的样式以及注意事项
组件对应 wxss 文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:
- 不建议在 app.wxss 或 page.wxss 中使用了标签(view)选择器或一些其他特殊选择器来直接指定样式,这些选择器会影响到页面和全部组件,通常不推荐此做法
- 组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。
- 组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
- 子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
- 继承样式,如 font 、 color ,会从组件外继承到组件内。
- 除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效(除非更改组件样式隔离选项)。
custom02.wxss 文件代码示例:
// 第一个注意事项:在自定义组件的 wxss 文件中不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用 class 选择器
// 可以使用 class 选择器
// .content {
// color: rgb(136, 224, 224);
// }
// 不能使用标签名选择器,否则打印台会有警告
// text{
// color: plum;
// }
// 不能使用id选择器(#a)
// #content {
// color: pink;
// }
// 不能使用属性选择器([a])
// [id = content]{
// color: lightcoral;
// }
// 第二个注意事项:子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况
// .content > .label {
// color: peachpuff;
// }
custom02.wxml 文件代码示例:
<text id="content" class="content son">
<text class="label">给自定义组件设置样式</text>
</text>
app.json 文件代码示例:
"usingComponents": {
"custom02": "./components/custom02/custom02"
}
page.wxss 文件代码示例:
page {
padding: 10rpx;
box-sizing: border-box;
}
// 第三个注意事项:继承样式,如 font 、 color ,会从组件外继承到组件内。
// .custom {
// color: orange;
// font-size: 30rpx;
// }
// 第四个注意事项:除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效
// .label {
// color: lightgreen;
// }
// 第五个注意事项-官方不推荐做法:不建议在 app.wxss 或 page.wxss 中使用标签选择器直接使用样式、
// 如果在 app.wxss 中设置样式,会影响项目中全部的相同组件
// 如果在 page.wxss 中设置样式,会影响当前页面所有的相同组件
// text {
// color: lightpink;
// }
// 第六个注意事项:组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用
.parent .son.test {
color: orange;
}
page.wxml 文件代码示例:
<custom02 />
<view class="custom">
<custom02 />
</view>
<text>我是父级页面中的结构</text>
<view class="custom parent">
<view>
<custom02 />
<view class="son test">我是父级页面中的结构</view>
</view>
</view>
五、自定义组件的组件样式隔离
默认情况下,自定义组件的样式只受到自定义组件 wxss 的影响。但有时我们需要组件使用者的样式可以影响到组件,这时就需要指定特殊的样式隔离选项 styleIsolation 。它支持以下取值:
- isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
- apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
- shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。(这个选项在插件中不可用。)
custom-checkbox.scss 文件代码示例:
/*
复选框组件是公共组件,以后需要在多个页面或多个项目中使用,所以需要给复选框准备、设置一些默认样式
若在其他页面或其他项目中使用时,发现样式不符合产品要求,可以对默认样式进行修改
*/
/*
1、需要给复选框设置默认样式:
需要先找到小程序给复选框提供的类名,通过小程序提供的类名进行修改才可以
需要打开小程序开发文档,找到复选框文档,审查元素,进行查找
在自定义组件中,不能直接修改复选框样式,若需要修改,需要设置 styleIsolation 才可以
shared:修改其他页面、组件使用者的样式、以及使用了 apply-shared 或 shared 的自定义组件,这并不是我们想要的需求
需求是只影响当前组件:可以添加命名空间
*/
// 复选框未选中的默认样式
.custom-checkbox .wx-checkbox-input {
width: 24rpx !important;
height: 24rpx !important;
border-radius: 50% !important;
border: 1px solid orange !important;
margin-top: -3rpx;
}
// 复选框选中时的默认样式
.custom-checkbox .wx-checkbox-input-checked {
background-color: orange;
}
// 复选框选中时 ✔️ 样式
.custom-checkbox .wx-checkbox-input.wx-checkbox-input-checked:before {
font-size: 22rpx;
color: white;
}
.custom-checkbox-container {
display: inline-block;
}
.custom-checkbox-box {
display: flex;
align-items: center;
}
.custom-checkbox-box.left {
flex-direction: row-reverse;
}
.custom-checkbox-box.right {
flex-direction: row;
}
.custom-checkbox {
margin-left: 10rpx;
}
.content{
font-size: 24rpx;
}
custom-checkbox.wxml 文件代码示例:
<!-- <text>我是全局-自定义组件</text> -->
<view class="custom-checkbox-container">
<view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left'}}" >
<checkbox class="custom-checkbox" checked="{{ isChecked }}" bind:tap="updateChecked"/>
<view class="content">
<!-- 如果用户传递了 label 属性,就展示 label;否则展示子节点内容 -->
<text wx:if="{{ label !== '' }}">{{ label }}</text>
<slot wx:else="" />
</view>
</view>
</view>
custom-checkbox.js 文件示例:
Component({
options: {
styleIsolation: "shared"
},
/**
* 组件的属性列表:是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据与属性
*/
properties: {
// 如果需要传递的是属性,有两种方式:简写和全写
// 简写:
// label: String
// 全写:
label: {
// type 组件使用者传递的数据类型,是必填项
// 数据类型:String、Number、Boolean、Object、Array
// 也可以设置为 null,表示不限制类型
type: String,
// value 属性值为默认值
value: ""
},
position: {
type: String,
value: "right"
}
},
/**
* 组件的初始数据:定义组件的内部需要使用的数据
*/
data: {
isChecked: false
},
/**
* 组件的方法列表:在组件中事件处理程序需要写到 methods 中可以
*/
methods: {
// 更新复选框的状态
updateChecked() {
this.setData({
isChecked: !this.data.isChecked,
// 在 JS 中可以访问和获取 properties 中的数据,但一般情况下不建议修改,因为会造成数据流的混乱
// label: '在组件内部也可以修改 properties 中的数据'
})
console.log(this.properties.label)
}
}
})
app.json 文件代码示例:
"usingComponents": {
"custom-checkbox": "./components/custom-checkbox/custom-checkbox"
}
page.scss 文件代码示例:
/*
2、组件使用者也可以修改复选框样式:
*/
// 复选框未选中的默认样式
.custom .custom-checkbox .wx-checkbox-input {
border: 1px solid green !important;
}
// 复选框选中时的默认样式
.custom .custom-checkbox .wx-checkbox-input-checked {
background-color: green !important;
}
page.wxml 文件代码示例:
<view class="custom">
<custom-checkbox position="left" >
匿名提交
</custom-checkbox>
</view>
六、自定义组件的数据监听器
数据监听器主要用于监听和响应任何属性和数据的变化,当数据发生变化时会触发对应的回调函数,从而方便开发者进行业务处理
在组件中如果需要进行数据监听,需要使用 observers 字段
custom04.js文件代码示例:
Component({
/**
* 组件的属性列表
*/
properties: {
label: {
type: String,
value: '测试'
}
},
/**
* 组件的初始数据
*/
data: {
num: 10,
count: 100,
obj: { name: 'Tom', age: 10},
arr: [1, 2, 3]
},
// 用来监听数据属性是否发生变化
observers: {
// 一、监听一个数据
// key: 需要监听的数据
// value: 就是一个回调函数,形参:最新的数据
num: function (newNum) {
// 对 data 中的数据进行监听,若数据没有发生改变,监听器不会执行
console.log(newNum)
},
count: function (newcount) {
console.log(newcount)
},
// 二、同时监听多个数据
'num, count': function (newNum, newCount) {
console.log(newNum, newCount)
},
// 三、支持监听属性的变化
'obj.name': function (newName) {
console.log(newName)
},
'arr[1]': function (newItem) {
console.log(newItem)
},
// 四、监听一个对象的所有属性的变化,使用通配符
'obj.**': function (newObj) {
console.log(newObj)
},
// 五、只要组件使用者进行传递了数据,这时候在监听器中就能获取传递的数据,也就是说,监听器立即执行了
label: function (newLabel) {
console.log(newLabel)
}
},
/**
* 组件的方法列表
*/
methods: {
// 更新数据
updateData () {
this.setData({
num: this.data.num + 1,
count: this.data.count - 1,
'obj.name': 'jerry',
'arr[1]': 666,
label: '最新的标题'
})
}
}
})
custom04.wxml 文件代码示例:
<view>{{ num }}</view>
<view>{{ count }}</view>
<view>{{ obj.name }}</view>
<view>{{ arr[1] }}</view>
<view>{{ label }}</view>
<button type="warn" plain bind:tap="updateData">更新数据</button>
app.json 文件代码示例:
"usingComponents": {
"custom04": "./components/custom04/custom04"
}
page.wxml 文件代码示例:
<custom04 label='标题' />
七、自定义组件的组件通信
1、父组件向子组件传递数据,需要两个步骤:
- 1.1、在父组件 WXML 中使用数据绑定的方式向子组件传递动态数据
- 1.2、子组件内部使用 properties 接收父组件传递的数据即可
2、子组件若向父组件传递数据,可以通过小程序提供的事件系统实现,可以传递任意数据,需要两个步骤:
- 2.1、自定义组件内部使用 triggerEvent 方法发射一个自定义事件,同时可以携带数据
- 2.2、自定义组件标签上通过 bind 方法监听发射的事件,同时绑定事件处理函数,在事件处理函数中通过事件对象获取传递的数据
3、父组件可以通过 this.selectComponent 方法,获取子组件实例对象,这样就可以直接访问子组件的任意数据与方法,this.selectComponent 方法在调用时需要传入一个匹配选择器 selector
page.wxml 文件代码示例:
<!-- 1、自定义组件的数据通信-父往子传值 -->
<custom-checkbox position="right" checked="{{ isChecked }}">
我已阅读并同意 用户协议 和 隐私协议 - 222
</custom-checkbox>
<!-- 2、自定义组件的数据通信-子往父传值 -->
<view>{{ num }}</view>
<!-- 需要自定义组件标签上通过 bind 方法绑定自定义事件,同时绑定事件处理函数 -->
<custom-checkbox
label="我已阅读并同意 用户协议 和 隐私协议"
position="right"
checked="{{ isChecked }}"
bind:changechecked="getChecked"
>
</custom-checkbox>
<!-- 3、自定义组件的数据通信-获取组件实例 -->
<button type="primary" plain bind:tap="getChild">获取子组件实例对象</button>
<custom-checkbox
label="我已阅读并同意 用户协议 和 隐私协议"
position="right"
checked="{{ isChecked }}"
class="child"
id="child"
>
</custom-checkbox>
page.js 文件代码示例:
Page({
// 获取子组件的实例对象
getChild() {
// this.selectComponent 方法获取子组件实例对象,获取到实例对象以后,就能获取到子组件所有的数据,也能调用子组件的方法
// .child 也可以写成 #child
const res = this.selectComponent('.child')
console.log(res)
},
// 获取子组件传递给父组件的数据
getChecked(event) {
console.log(event.detail)
if (event.detail){
console.log("提交")
} else {
console.log("请同意协议!")
}
},
/**
* 页面的初始数据
*/
data:{
isChecked: true,
num: ''
}
}
custom-checkbox.js 文件代码示例:
Component({
/**
* 组件的属性列表:是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据与属性
*/
properties: {
// 如果需要传递的是属性,有两种方式:简写和全写
// 简写:
// label: String
// 全写:
label: {
// type 组件使用者传递的数据类型,是必填项
// 数据类型:String、Number、Boolean、Object、Array
// 也可以设置为 null,表示不限制类型
type: String,
// value 属性值为默认值
value: ""
},
position: {
type: String,
value: "right"
},
// 复选框组件公共组件,需要在多个组件多个页面使用,但有的地方希望默认是选中的效果,有的地方希望默认是未选中的效果,怎么处理呢?
// 首先让复选框默认未选中效果,若需要默认选中效果,这时候传递属性(checked=true) 到复选框
checked: {
type: Boolean,
value: false
}
},
/**
* 组件的初始数据:定义组件的内部需要使用的数据
*/
data: {
isChecked: false
},
observers: {
// 如果需要将 properties 中的数据赋值给 data,可以使用 observers 进行处理
checked: function(newChecked) {
console.log(newChecked)
this.setData({
isChecked: newChecked
})
}
},
/**
* 组件的方法列表:在组件中事件处理程序需要写到 methods 中可以
*/
methods: {
// 更新复选框的状态
updateChecked() {
this.setData({
checked: !this.data.checked,
// 在 JS 中可以访问和获取 properties 中的数据,但一般情况下不建议修改,因为会造成数据流的混乱
// label: '在组件内部也可以修改 properties 中的数据'
})
console.log(this.data.isChecked)
// 目前复选框组件的状态是存储在复选框组件内部的、存储在自定义组件内部的,但在实际开发中,组件使用者、父组件有时候也需要获取到复选框内部的状态,怎么办?
// 这时候,自定义组件需要发射一个自定义事件,如果组件使用者或父组件需要使用数据,绑定自定义事件获取即可
this.triggerEvent('changechecked', this.data.isChecked)
}
}
})
八、自定义组件的生命周期
见文章:微信小程序-生命周期
九、自定义组件拓展-使用 component 构造页面
component 方法用于创建自定义组件,小程序页面也可视为自定义组件,因此页面也可以使用 component 方法进行创建,从而实现复杂的页面逻辑开发
- 小程序页面也可以使用 component 方法进行构造,注意事项:
- 1、要求 .json 文件必须包含 usingComponents 字段
- 2、里面的配置项需要和 Component中的配置项保持一致
- 3、页面中 Page 方法有一些事件监听方法、钩子函数,这些方法函数必*放在方法 methods 对象中
- 4、组件的属性 properties也可以接收页面的参数,在 onLoad 钩子*数中可以通过 this.data 获取
- 为什么需要使用 component 方法进行构造页面?
- component 方法功能比 page 方法强大很多,可以实现更复杂的页面逻辑
detail.js 文件代码示例:
Component({
/**
* 小程序页面也可以使用 component 方法进行构造
* 注意事项:
* 1、要求 .json 文件必须包含 usingComponents 字段
* 2、里面的配置项需要和 Component中的配置项保持一致
* 3、页面中 Page 方法有一些事件监听方法、钩子函数,这些方法函数必*放在方法 methods 对象中
* 4、组件的属性 properties也可以接收页面的参数,在 onLoad 钩子*数中可以通过 this.data 获取
* 为什么需要使用 component 方法进行构造页面?
* component 方法功能比 page 方法强大很多,可以实现更复杂的页面逻辑
*/
/**
* 组件的属性列表
*/
properties: {
id: String,
title: String
},
/**
* 组件的初始数据
*/
data: {
name: "tom"
},
/**
* 组件的方法列表
*/
methods: {
// 更新 name
updateName() {
this.setData({
name: "jerry"
})
},
onLoad (options) {
console.log('页面加载')
console.log(options)
console.log(this.data.id)
console.log(this.data.title)
console.log(this.properties.id)
}
}
})
detail.wxml 文件代码示例:
<view>{{ name }}</view>
<button type="warn" plain bind:tap="updateName">更新 name</button>
page.wxml 文件代码示例:
//自定义组件拓展-使用 component 构造页面
<navigator url="/pages/detail/detail?id=10&title=测试">跳转到详情页面</navigator>
十、自定义组件拓展-组件复用机制 behaviors
小程序的 behaviors 方法是一种代码复用方式,可将一些通用的逻辑和方法提取出来,然后在多个组件中复用,从而减少代码冗余,提高代码的可维护性。
如果需要 behavior 复用代码,需要使用 Behavior 方法,每个 behavior 可包含一组属性、数据、生命周期函数和方法。
组件引用它时,它的属性、数据和方法被合并到组件中,生命周期函数也会在对应时机被调用。
在以后开发中使用 behaviors 进行代码复用时,组件和 behaviors 可能存在相同的字段:
- 如果有同名的属性或方法,采用“就近原则”,组件会覆盖 behavior 中的属性或方法
- 如果有同名的数据字段且都是对象类型,会进行对象合并,其余情况会采用“就近原则”进行数据覆盖
- 生命周期函数和 observers 不会相互覆盖,会在对应触发时机逐个调用,也就是都会被执行
在自定义组件文件夹中创建 behavior.js 文件,代码示例:
const behavior = Behavior({
/**
- 组件的属性列表
*/
properties: {
label: {
type: String,
value:'我已同意该协议'
}
},
/**
- 组件的初始数据
*/
data: {
name: "Lida",
obj: {
name: "Mike"
}
},
/**
- 组件的方法列表
*/
methods: {
updateName () {
this.setData({
name: "jerry"
})
console.log("我是 behavior 内部的方法")
}
},
lifetimes: {
attached() {
console.log("我是 behavior 内部的生命周期函数")
}
}
})
export default behavior
custom07.js 文件代码示例:
// components/custom07/custom07.js
import behavior from './behavior'
Component({
behaviors: [behavior],
/**
- 组件的属性列表
*/
// 如果存在相同的 properties,就近原则,使用组件内部的数据
properties: {
label: {
type: String,
value:'匿名提交'
}
},
/**
- 组件的初始数据
*/
// 如果存在相同的 data,若 data 是对象类型,属性会进行合并,如果不是对象类型,就近原则,使用组件内部的数据
data: {
name: "组件中的 name",
obj: {
name: "组件中的 obj name",
age: 100
}
},
/**
- 组件的方法列表
*/
// 如果存在相同的方法,就近原则,使用组件内部的方法
methods: {
updateName () {
console.log("我是组件内部的方法")
}
},
// 如果存在相同的生命周期函数,生命周期函数都会被触发
lifetimes: {
attached() {
console.log("我是组件内部的生命周期函数")
}
}
})
custom07.wxml 文件代码示例:
<!--components/custom07/custom07.wxml-->
<view>{{ label }}</view>
<view>{{ name }}</view>
<view>{{ obj.name }}-{{obj.age}}</view>
<button type="primary" plain bind:tap="updateName">更新数据</button>
page.wxml 文件代码示例:
<custom07 />
app.json 文件代码示例:
"usingComponents": {
"custom07": "./components/custom07/custom07"
}
十一、自定义组件拓展-外部样式类
默认情况下,组件与组件使用者之间若存在相同的类型不会相互影响,组件使用者若想修改组件的样式,就需要解除样式隔离,但解除样式隔离后,在极端情况下,会产生样式冲突、CSS嵌套太深等问题,从而给开发带来一定的麻烦。
外部样式类:在使用组件时,组件使用者可以给组件传入CSS 类名,通过传入的类名修改组件的样式。
如果需要使用外部样式类修改组件的样式,在 Component 中需要用 externalClasses 定义若干个外部样式类。
外部样式类使用步骤:
- 在 Component 中用 externalClasses 定义若干个外部样式类
- 自定义组件标签通过 属性绑定 的方式提供一个样式类,属性是 externalClasses 定义的元素,属性值是传递的类名
- 将接收到的样式类用于自定义组件内部
注意事项:
在同一节点,若存在外部样式类和普通样式类时,两个类的优先级是未定义的,因此需要添加 !important 以保证外部样式类的优先级
custom08.js 文件代码示例:
// components/custom08/custom08.js
Component({
// 组件接受的外部样式类
externalClasses: ['external-class']
})
custom08.scss 文件代码示例:
.box {
color: aqua;
}
custom08.wxml 文件代码示例:
<!--
在同一节点,若存在外部样式类和普通样式类
两个类的优先级是未定义的
建议:在使用外部样式类时,样式需要通过 !important 添加权重
-->
<view class="external-class box">通过外部样式类修改组件样式</view>
app.json 文件代码示例:
{
"usingComponents": {
"custom08": "./components/custom08/custom08"
}
}
page.scss 文件代码示例:
.my-class{
color: orange !important;
}
page.wxml 文件代码示例:
<!--
属性是 externalClass 里面定义的元素
属性值必须是一个类名
-->
<custom08 external-class="my-class" />