目录
第一种:在.js文件中加上:‘styleIsolation’,这三个参数对应的是不同的影响
第二种:在.json文件中加上:‘styleIsolation’,参数也是类似于上面的配置方法
1.3.detached, 在组件实例被从页面节点树移除时执行
一、创建自定义组件
首先在项目目录中新建一个components的文件夹
然后在该文件夹中创建自定义的组件,为了项目结构更加清晰,每个自定义组件单独一个文件夹存放
第一步:先创建一个文件夹
第二步:右击该文件夹新建一个component
自定义组件就创建好了
二、自定义组件的使用(局部使用和全局使用)
1.局部使用
首先我们要在需要引用的页面的json文件中加入组件的配置项:usingComponents
"usingComponents": {
"my_test1":"/components/test1/test1"
}
这里的my_test1是组件的名字(就是我们要在页面中使用的标签名字)后面是自定义组件的路径
在home页面中使用:
可以看到组件引用成功了
2.全局使用
首先要在项目的总配置文件app.json中创建对应的配置,其和局部使用一样的
这样配置后我们在任何页面中都可以使用该组件了
三、组件和页面的区别
其实乍一看组件和页面好像长的非常的像,一样的结构,都有json、js、wxml、wxss这些文件,但其实组件和页面还是有一些区别的,可以从下面三个方面体现出来
1. 组件的.json文件中必须声明: "component": true,而页面的文件中是不需要声明的
2.组件的.js文件调用的是Compent函数
而页面使用的是Page函数
3.组件的事件处理函数需要写到methods列表中,而页面只需要跟其他的生命周期函数同级即可
四、组件样式隔离特性
1.样式隔离特性
我们在全局样式中定义的样式,在组件中是无法生效的,这就是组件样式的隔离
但是存在一些个例会造成影响,像这种标签形式的会造成影响
所以在开发过程中尽量使用class选择器和id选择器,少使用标签选择器
2.修改组件样式隔离特性
这里有二种方法,一种是在组件的.js文件中进行修改,一种是在.json文件中进行修改
第一种:在.js文件中加上:‘styleIsolation’,这三个参数对应的是不同的影响
options:{
styleIsolation:'shared'
//开启隔离(默认):isolated
//apply-shared :单向影响 页面样式影响组件,但是组件不影响页面
//shared :双向奔赴,互相影响
},
第二种:在.json文件中加上:‘styleIsolation’,参数也是类似于上面的配置方法
详情配置可以参考官方文档:组件模板和样式 | 微信开放文档 (qq.com)
五、组件的data和methods
data顾名思义是用来存放数据的,methods是用来写事件处理函数或方法的
在methods中编写一个事件处理函数,实现点击按钮数据增加的效果
wxml:
<view>Count的值为:{
{count}}</view>
<button bindtap="addCount">+1</button>
js:
data: {
count:1
},
/**
* 组件的方法列表
*/
methods: {
addCount(){
this.setData({ count:this.data.count+1})
this._showCount()
},
_showCount(){
wx.showToast({
title: 'count的值为'+this.data.count,
icon:'none'
})
}
}
实现的效果如下:可以点击增加数据并显示提示框
六:自定义组件的properties属性
properties是组件的对外属性,用来接收外界传递给组件的数据,类似于vue的props,其定义方法也与vue类似。
第一种:简化方法,值+数据类似
//第一种简化方式
max:Number
第二种:可以带默认值
//第二种方式 可以指定默认值
max:{
type:Number,
value:10
}
使用:
七、data和properties的区别
在vue中,我们一般规定props里面的值是只读的,不建议去修改它,那么在小程序中他们又有什么区别呢?一起来看看吧
可以看到上面的打印结果显示完全是一样的,甚至用‘===’符也是true,可以看到他们俩的本质是一样的,他们存放的数据是对方共有的数据,在访问时也可以直接互相访问,而且当data中也存在和properties一样的数据时,properties中的优先级要比data高
所以对于properties我们也是可以进行可读可写操作的,读也是类似与data,使用{ {properties}}即可,对于修改也就是类似于data的setData
this.setData({count:this.properties.count+1})
this.setData({max:this.data.max+1})
注意看我的代码片段,count原本是在data中的,但是properties也可以访问,并且能做到修改的效果
八、数据监听器(类似于vue的watch)
数据监听器类似于vue中的watch监听器,它可以监听数据的变化,从而进行一些必要的操作
1.语法格式
在组件的js文件与data同级,新建一个observers
//数据监听器
observers:{
'字段A,字段B':function(字段A的新值,字段B的新值){
//do something
}
}
这里要注意的是它只有最新值,没有旧值
2.小案例:监听新值计算出新的和
wxml:
<view>{
{n1}} + {
{n2}} = {
{sum}}</view>
<button bindtap="addN1">n1+1</button>
<button bindtap="addN2">n2+1</button>
js:
data: {
n1:0,
n2:0,
sum:0
},
methods: {
addN1(){
this.setData({n1:this.data.n1+1})
},
addN2(){
this.setData({n2:this.data.n2+1})
}
},
//数据监听器
observers:{
'n1, n2':function(n1,n2){
//do something
this.setData({sum:n1+n2})
}
}
实现效果:
3.监听对象身上的属性值
语法格式:像这样即可
该方法的监听触发条件:
- name属性发生变化
- age属性发生变化
- user对象发生变化
observers:{
'user.name, user.age':function(name,age){
//do something
console.log(name);
console.log(age);
}
}
修改的函数:
this.setData({user:{
...this.data.user,
name:'ls'
}})
可以看到已经监听到了新变化
4.observers监听案例
案例效果:点击按钮改变盒子的rgb的值,从而改变盒子的颜色
wxml:
<view style="background-color: rgb({
{fullColor}});" class="colorBox">颜色值:{
{fullColor}}</view>
<button size="mini" type="default" bindtap="changeR">R</button>
<button size="mini" type="primary" bindtap="changeG">G</button>
<button size="mini" type="warn" bindtap="changeB">B</button>
wxss:
.colorBox{
line-height: 200rpx;
font-size: 24rpx;
color: white;
text-shadow: 0rpx 0rpx 2rpx black;
text-align: center;
}
js:
data: {
rgb:{
r:0,
g:0,
b:0
},
fullColor:'0, 0, 0'
},
/**
* 组件的方法列表
*/
methods: {
changeR(){
this.setData({'rgb.r':this.data.rgb.r + 5 > 255 ? 255 : this.data.rgb.r + 5})
},
changeG(){
this.setData({'rgb.g':this.data.rgb.g + 5 > 255 ? 255 : this.data.rgb.g + 5})
},
changeB(){
this.setData({'rgb.b':this.data.rgb.b + 5 > 255 ? 255 : this.data.rgb.b + 5})
}
},
observers:{
// 'rgb.r, rgb.g, rgb.b':function(r, g, b){
// this.setData({fullColor:`${r},${g},${b}`})
// },
//使用通配符 ** 监听对象的所有属性变化
'rgb.**':function(obj){
this.setData({fullColor:`${obj.r},${obj.g},${obj.b}`})
}
}
该案例利用了点击事件改变rgb的属性值,然后通过监听事件来让盒子的颜色及时发生变化
九、纯数据字段
纯数据字段就是指不用于页面渲染的data数据,也不会传递给其他组件,仅仅在当前组件内部使用。就像上面的observers案例中的:“rgb”那样没有用到页面渲染中,只是参与了逻辑运算,纯数据字段的优点就是有利于提升页面刷新的性能rgb
纯数据字段使用规则:
在js中options下定义pureDatePrttern
options:{
// 指定所有以 _开头的字段为纯数据
pureDataPattern:/^_/
},
这样做了之后,凡是以"_"开头的数据都不会被用于渲染页面中
//data:
a:1,
_b:2
//wxml
<text>{
{a}}</text>
<text>{
{b}}</text>
页面中只渲染了a的数据值,而b并没有被渲染出来
利用纯数据字段改造observers监听案例,提高性能
首先是定义好使用规则,然后将所有的rgb全部替换成_rgb即可,这样一来就可以提高页面的渲染性能了,具体可参考官方文档:纯数据字段 | 微信开放文档 (qq.com)
十、 自定义组件的生命周期函数
组件所在页面的生命周期
生命周期 | 参数 | 描述 | 最低版本 |
---|---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 | 1.6.3 |
attached | 无 | 在组件实例进入页面节点树时执行 | 1.6.3 |
ready | 无 | 在组件在视图层布局完成后执行 | 1.6.3 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 | 1.6.3 |
detached | 无 | 在组件实例被从页面节点树移除时执行 | 1.6.3 |
error | Object Error |
每当组件方法抛出错误时执行 | 2.4.1 |
1.主要的周期函数
1.1.created,在组件实例刚刚被创建时执行
- 此时还不能调用setData
- 通常在这个生命周期函数中,只应该用于给组件的this挂载一些自定义的属性字段
1.2.attached, 在组件实例进入页面节点树时执行
- 此时, this.data已被初始化完毕
- 这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
1.3.detached, 在组件实例被从页面节点树移除时执行
- 退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数
- 此时适合做一些清理性质的工作
2.定义周期函数
旧版的方法现在官方已经不推荐了,下面可以看到已经差不多被移除了
所以我们直接采用最新的方式:所有的周期函数都放在lifetimes中
3.组件所在页面的生命周期
还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。这样的生命周期称为“组件所在页面的生命周期”,在
pageLifetimes
定义段中定义。
生命周期 | 参数 | 描述 | 最低版本 |
---|---|---|---|
show | 无 | 组件所在的页面被展示时执行 | 2.2.3 |
hide | 无 | 组件所在的页面被隐藏时执行 | 2.2.3 |
resize | Object Size |
组件所在的页面尺寸变化时执行 | 2.4.0 |
routeDone | 无 | 组件所在页面路由动画完成时执行 | 2.31.2 |
代码示例:
Component({
pageLifetimes: {
show: function() {
// 页面被展示
console.log('show');
},
hide: function() {
// 页面被隐藏
console.log('hide');
},
resize: function(size) {
// 页面尺寸变化
}
}
})
当页面展示时:
切换页面后:
十一、插槽
插槽的作用其实就是充当一个占位符的作用,当我们复用组件时但是有一部分的内容是不一样的,这时候就可以使用插槽来实现
1.使用单个插槽
组件的wxml:
<view>
<text>组件内部结构</text>
<slot></slot>
</view>
页面的wxml:
<my_test4>
<view>这是通过插槽填充的内容</view>
</my_test4>
2.使用多个插槽
首先需要在js中进行配置
Component({
options:{
multipleSlots:true // 开启多个插槽的使用
}
}
因为有多个插槽我们在使用过程中肯定不能混淆,需要进行一定的区分
可以在slot中设置name
<view>
<text>组件内部结构</text>
<slot name="before"></slot>
<slot name="after"></slot>
</view>
使用时进行必要的区分
<my_test4>
<view slot="before">这是before插槽填充的内容</view>
<view slot="after">这是after插槽填充的内容</view>
</my_test4>
这样就能对其进行区分了
十二、组件间的通信
在开发过程中,组件之间互相传递参数是必不可少的,也是非常重要的部分
1.父向子传递数据(属性绑定)
!!!父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据
使用案例:父组件将数据传递给子组件
<view>父组件中的count的值:{
{count}}</view>
<my_test5 count="{
{count}}"></my_test5>
子组件在js中定义properties接收
properties: {
count:Number
},
子组件中使用count
<view>父组件传递过来的count值:{
{count}}</view>
效果:
2.子向父传递数据(事件绑定)
先在父组件中定义一个事件
syncCount(e){
console.log('syncCount');
console.log(e);
},
将该方法传递给子组件
<view>父组件中的count的值:{
{count}}</view>
<my_test5 count="{
{count}}" bind:sync="syncCount"></my_test5>
子组件写一个名为:sync的事件触发函数
methods: {
addCount(){
//触发自定义事件
this.triggerEvent('sync',{val:"son"})
}
}
当触发事件时,父组件就可以接受到传输过去的数据val
打印出来可以看到我们需要的数据在detail中,所以只要e.detail即可拿到数据
3.获取子组件示例(父组件直接访问子组件数据)
首先给组件一个类名class
然后可以定义一个方法获取到子组件实例对象
getChild(){
const child = this.selectComponent('.child')
console.log(child);
child.setData({
count:child.properties.count + 1 // 修改子组件数据
})
},
打印结果可以看到子组件的数据及方法都获取到了
所以我们可以直接获取到子组件的数据,甚至是使用它其中的方法进行修改
十三、组件中的behaviors
behaviors
是用于组件间代码共享的特性,类vue似于一些编程语言中的 “mixins(vue)” 或 “traits”。每个behavior
可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 每个组件可以引用多个behavior
,behavior
也可以引用其它behavior
。
1.创建behaviors
项目目录中创建behaviors 文件夹及js文件
代码示例:(共享代码)
module.exports = Behavior({
data:{
username:'zs'
},
properties:{},
methods:{}
})
2.导入使用behaviors
在需要使用的组件的js中最上层导入behaviors
const myBehavior= require('../../behaviors/my-behavior')
在Component中接收数据
behaviors:[myBehavior],
在组件中使用
<text>myBehavior中的用户名:{
{username}}</text>
3.behaviors可用的节点
定义段 | 类型 | 是否必填 | 描述 | 最低版本 |
---|---|---|---|---|
properties | Object Map | 否 | 组件的对外属性,是属性名到属性设置的映射表 | |
data | Object | 否 | 组件的内部数据,和 properties 一同用于组件的模板渲染 |
|
observers | Object | 否 | 组件数据字段监听器,用于监听 properties 和 data 的变化,参见 数据监听器 | 2.6.1 |
methods | Object | 否 | 组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用,参见 组件间通信与事件 | |
behaviors | String Array | 否 | 类似于mixins和traits的组件间代码复用机制,参见 behaviors | |
created | Function | 否 | 组件生命周期函数-在组件实例刚刚被创建时执行,注意此时不能调用 setData ) |
|
attached | Function | 否 | 组件生命周期函数-在组件实例进入页面节点树时执行) | |
ready | Function | 否 | 组件生命周期函数-在组件布局完成后执行) | |
moved | Function | 否 | 组件生命周期函数-在组件实例被移动到节点树另一个位置时执行) | |
detached | Function | 否 | 组件生命周期函数-在组件实例被从页面节点树移除时执行) | |
relations | Object | 否 | 组件间关系定义,参见 组件间关系 | |
lifetimes | Object | 否 | 组件生命周期声明对象,参见 组件生命周期 | 2.2.3 |
pageLifetimes | Object | 否 | 组件所在页面的生命周期声明对象,参见 组件生命周期 | 2.2.3 |
definitionFilter | Function | 否 | 定义段过滤器,用于自定义组件扩展,参见 自定义组件扩展 | 2.2.3 |