1、bind:xx和catch:xx绑定事件
可以把bind和tap之间用冒号分割开来,ctache也可以
<button bind:tap="click_me1">点击</button>
<button bindtap="click_me2">点击</button>
<button catch:tap="click_me3">点击</button>
<button catchtap="click_me4">点击</button>
2、event事件对象
随着点击或触摸等事件在回调函数中默认带入的event对象
click_me1(event){
console.log(event);
},
1、event对象的touched和changedTouches
touches:多点触发的情况
changedTouches:多点触发中变化的情况,如多一个出发点,或少一个手指出发点
3、事件的传递参数
在wxml标签里面设置data-别名=‘数据’,然后在js数据中通过event对象拿event.currentTarget.dataset就可以拿到从wxml中传递过来的参数
index.wxml
<block class="content" wx:for="{{persons}}" wx:key="index">
<view data-person="{{item}}"
data-index="{{index}}"
bindtap="itemClick"
class="myview"
>{{item}}</view>
</block>
index.js
// 获取应用实例
const app = getApp()
Page({
data: {
persons:['zhagnsan','lisi','wanger','mazi','zhaoliu','defu','gawa',],
},
itemClick(event){
console.log(event);
const dataset=event.currentTarget.dataset;
const title=dataset.person;
const index=dataset.index;
console.log(title,index);
}
})
4、事件冒泡和事件捕获
capture-bind:事件会层层传递
capture-catch:会阻止事件冒泡
<view class='outter' capture-bind:tap="handCaptureOutter" bindtap="handBindOutter">
<view class="middle" capture-bind:tap="handCaptureMidle" bindtap="handBindMiddle">
<view class="inner" capture-bind:tap="handCaptureInner" bindtap="handBindinner"></view>
</view>
</view>
Page({
data: {
isshow:true,
persons:['zhagnsan','lisi','wanger','mazi','zhaoliu','defu','gawa',],
nums:[1,2,3,4,5]
},
handCaptureOutter(){
console.log('handCaptureOutter');
},
handCaptureMidle(){
console.log('handCaptureMidle');
},
handCaptureInner(){
console.log('handCaptureInner');
},
handBindOutter(){
console.log('handBindOutter');
},
handBindMiddle(){
console.log('handBindMiddle');
},
handBindInner(){
console.log('handBindInner');
}
})
5、创建自定义组件
组件由4部分组成
json
wxml
wxss
js
1、编写组件代码
mycpn.wxml
<!--components/mycpn/mycpn.wxml-->
<view class="title">i am title</view>
<view class="content">i am content</view>
<view class="footer">{{myfooter}}</view>
2、在引用页面的json配置文件中注册组件
也可以在app.json里进行注册,在全局中都可以使用。json文件不能使用注册
使用键值对,标签名:组件路径
index.json
{
"usingComponents": {
"mycpn":"/components/mycpn/mycpn"
}
3、在组件应用页面的wxml文件中使用组件
index.wxml
<mycpn></mycpn>
<mycpn/>
4、在组件js中可以定义数据或组件内部的相关逻辑
mycpn.js
data: {
myfooter:'i am footer'
},
6、自定义组件样式使用禁忌
组件选择器最好不用标签选择器,id选择器和属性选择器。会报警告,有时会报错
如果希望组件样式和引用样式之间相互影响。可以在组件对象中,传入一个options属性,其中options属性中有一个styleIsolation(属性隔离)属性。
styleIsolation有三个取值:
- isolated:表示启用样式隔离,在自定义组件内外,使用class指定的样式将不会相互影响(就是组件和应用页面的样式分离,互不干扰)
- apply-shared:页面样式将影响到组件样式,但组件样式不会影响到页面样式
- shared:表示页面样式影响到组件样式,组件样式也影响页面和其他设置。
7、组件和页面通信
组件内的数据通常不写死,可以由组件决定(组件自带的js)也可以从页面来传值,不同的数据对应不同的属性:
页面向组件通信(传值)使用三个手段
数据:properties
样式:externalClasses
标签:slot
组件向页面通信使用
自定义事件
以上和vue的页面和组件通信的原理基本一致
8、页面向组件通信(传值)
- 1、在js页面中的properties创建组件传值所需要的key,并设置好key的数据类型
mycpn.js
properties: {
title:{
type:String,
value:'我是默认标题',
observer:function(newVal,oldVal){
console.log(newVal,oldVal);//实际上newVal就是传来的值,oldVal就是默认的值
}
},
content:{
type:String,
value:'我是默认内容',
//observer是观察者,监听组件上值的改变。
observer:function(newVal,oldVal){
console.log(newVal,oldVal);
}
}
},
由于properties设定的通常是个对象也可以采用对象的写法,并设置默认值
- 2、创建组件,并在组件中使用mustache语法应用数据
mycpn.wxml
<!--components/mycpn/mycpn.wxml-->
<view class="title">{{title}}</view>
<view class="content">{{content}}</view><!--这里的title和content来自js中的properties-->
3、在应用页面中应用组件,并通过在组件js中设定的key进行传值
index.wxml
<mycpn content="来自主页"></mycpn>
<mycpn title="主页传来的title2" content="主页来的content"></mycpn>
<mycpn title="主页传来的title3" ></mycpn>
9、页面向组件传递样式
1、在组件页面中添加一个新的样式,是和原有class写在一个引号内
mycpn.wxml
<!--components/mycpn/mycpn.wxml-->
<view class="title titleclass">{{title}}</view>
<view class="content">{{content}}</view><!--这里的title和content来自js中的properties-->
- 2、在组件js页面中注册这个样式,使用externalClasses数组
externalClasses:[ 'titleclass'],//和components,data等同一级
- 3、在引用页面的wxss中设置要被传入的样式
index.wxss
.red{ color:red}
.green{ color:green}
.blue{ color:blue}
- 4、在引用页面中设置要传入的样式名
直接设置titleclass(在组件中设置的的class名)
<mycpn content="来自主页" titleclass="red"></mycpn>
<mycpn title="主页传来的title2" content="主页来的content" titleclass="green"></mycpn>
<mycpn title="主页传来的title3" titleclass="blue"></mycpn>
效果
10、组件向引用页面传递事件
1、创建组件
mycpn.wxml
<!--components/mycpn/mycpn.wxml-->
<button size="mini">+</button>
2、在json中注册组件
index.json
"usingComponents": {
"mycpn":"/components/mycpn/mycpn"
}
3、在组件中关联事件
<!--components/mycpn/mycpn.wxml-->
<button size="mini" bindtap="handleIncreament">+</button>
4、在组件的js中创建事件的回调函数,并在回调函数中发出一个事件及数据(三个参数)
Component({
methods:{
handleIncreament(){
//向页面传递信息,三个参数,第一个是自定义事件名,第二个是数据对象
this.triggerEvent('increment',{name:'zhangsan',age:19},{});
}
},
})
5、在引用页面中使用组件并绑定在组件中创建的事件(该事件时自定义事件,不是默认事件名)
index.wxml
<mycpn bind:increament="handleIncreat"></mycpn>
6、在引用页面的js中创建自定义事件的回调函数
Page({
data: {
counter:0,
},
handleIncreat(event){
this.setData({
counter:this.data.counter + 1
})
console.log(event.detail.name,event.detail.age);
}
})
7、总结:
- 1、自定义组件,绑定自定义事件
- 2、自定义组件的js中,定义方法将自定义事件弹出去
- 3、引用页json中注册组件
- 4、引用页使用自定义组件,并绑定自定义事件,并设置相应事件的回调函数
- 5、回调函数中处理相应逻辑
11、创建一个tabbar组件(案例练习)
1、创建组件mytabbar
mytabbar.xml
<view class="tabbar">
<view class="tab-item {{currentIndex == index ? 'active' : ''}}"
wx:for="{{titles}}" wx:key="index" bindtap="handItemClick" data-index="{{index}}"><text>{{item}}</text></view>
</view>
mytabbar.wxss
/* components/mytabbar/mytabbar.wxss */
.tabbar{display: flex; height: 88rpx; line-height: 88rpx; background-color:orange}
.tab-item{flex:1; text-align: center;}
.active{color:red;}
.active text{ padding: 20rpx 10rpx; border-bottom: 6rpx solid red;}
mytabbar.js
// components/mytabbar/mytabbar.js
Component({
/**
* 组件的属性列表
*/
properties: {
titles:{
type:Array,
value:[]
}
},
/**
* 组件的初始数据
*/
data: {
currentIndex:0,
},
/**
* 组件的方法列表
*/
methods: {
handItemClick(event){
const index = event.currentTarget.dataset.index;
this.setData({
currentIndex:index,
});
this.triggerEvent('clickItem',{index,title:this.properties.titles[index]},{})
}
}
})
2、创建引用页,注册组件
index.json
{
"usingComponents": {
"mytabbar":"/components/mytabbar/mytabbar"
}
}
index.js
// index.js
// 获取应用实例
const app = getApp()
Page({
data: {
},
handleClickItem(event){
console.log('从引用页面点击',event.detail.index,event.detail.title);
}
})
index.wxml
<mytabbar titles="{{['花生','瓜子','八宝粥']}}" bind:clickItem="handleClickItem"></mytabbar>
12、selectComponent直接选中组件修改数据/调用方法
1、创建组件myselect
myselect.wxml
<view >组件内的计数:{{counter}}</view>
2、设置组件数据
myselect.js
data: {
counter:0
},
3、引用页的json中注册组件
index.json
{
"usingComponents": {
"myselect":"/components/myselect/myselect"
}
}
4、引用页引入组件
index.wxml
<button bind:tap="handIncrementSelect">修改组件内的数据</button>
<myselect class="selclass" id="selid"></myselect>
5、引用页的js中编辑回调逻辑,通过selectComponent来拿到组件的数据
Page({
data: {
},
handIncrementSelect(){
//使用selectComponent修改组件中的数据,要通过类或id拿到组件对象,注意要包含 . 或 #
const myselect=this.selectComponent('.selclass');
//通过组件对象修改组件中的数据
myselect.setData({
counter:myselect.data.counter+1
});
}
})
6、对回调方法的优化,直接将对组件数据的调用通过一个接口函数来调用,而不是通过组件直接调用data中的数据
6-1:在组件的js创建一个修改数据的方法incrementCounter
myselect.js
// myselect/myselect.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
counter:0
},
/**
* 组件的方法列表
*/
methods: {
incrementCounter(num){
this.setData({
counter:this.data.counter+num
});
}
}
})
6-2:在应用页中调用组件方法
index.js
Page({
data: {
},
handIncrementSelect(){
//修改组件中的数据,要通过类或id拿到组件对象,注意要包含 . 或 #
const myselect=this.selectComponent('.selclass');
//通过组件对象修改组件中的数据
myselect.incrementCounter(10);
}
})
13、单个slot插槽的使用
一个很重要的概念就是由外部来决定组件内容的显示
slot插槽实际上其到了一个占位及导入标签的作用
1、创建插槽组件myslot
myslot.wxml
<!--components/myslot/myslot.wxml-->
<veiw class="myview">我是组件的头部</veiw>
<slot/>
<veiw class="myview">我是组件的尾部</veiw>
2、注册组件
index.json
{
"usingComponents": {
"myslot":"/components/myslot/myslot"
}
}
3、引入页面中使用插槽组件
index.wxml
<myslot>
<button>我是插入slot插槽的按钮</button>
</myslot>
<myslot>
<text>我是插入slot插槽的文本</text>
</myslot>
14、多个slot插槽的使用
- 需要给每个插槽起个名字
- 必须在component对象中添加一个options选项的 multipleSlots:true(实测不做这一步也是可以的)
1、创建一个插槽组件myslot
要给不同的插槽进行命名
mymulslot.xml
<view>我是组件的头部</view>
<view class="slotclz"><slot name="myslot1"></slot></view>
<view class="slotclz" ><slot name="myslot2"></slot></view>
<view class="slotclz" ><slot name="myslot3"></slot></view>
<view>我是组件的尾部</view>
2、注册插槽组件
index.json
{
"usingComponents": {
"mymulslot":"/components/mymulslot/mymulslot"
}
}
3、注册option,设置多插槽为真
在组件自身的js文件中注册options,设置多插槽为真
mymulslot.js
Component({
options:{
multipleSlots:true
},
properties: {
},
}
4、引用页面使用插槽
<mymulslot>
<button slot="myslot1">我是用来插入插槽的内容</button>
<slider slot="myslot2" >我是用来插入插槽的内容</slider>
<view slot="myslot3">我是用来插入插槽的内容</view>
</mymulslot>
结果:
15、component构造器
Component里面的对象
properties:定义组件的属性
data:定义组件的数据
methods:定义组件的方法
options:定义组件的配置选项
externalClasses:外界给组件传入的样式
obervers:监听properties(属性)和data(数据)的改变
16、组件监听生命周期函数
1、组件监听所在页面的声明周期
pageLifetimes:{
show(){//监听组件所在页面的显示行为
console.log('监听组件所在页面的显示');
},
hide(){//监听组件所在页面的hide(隐藏)行为
console.log('监听组件所在页面的hide(隐藏)行为');
},
resize(){//监听组件所在页面的尺寸改变行为
console.log('监听组件所在页面的尺寸改变行为');
}
}
2、组件监听组件本身的声明周期
lifetimes:{
created(){//监听组件被创建
console.log('监听组件被创建');
},
attached(){//监听组件被添加到页面
console.log('监听组件被添加到页面');
},
ready(){//监听组件被渲染出来
console.log('监听组件被渲染出来');
},
moved(){//监听组件被移动到节点另外一个位置
console.log('监听组件被移动到节点另外一个位置');
},
detached(){//监听组件被移除掉
console.log('监听组件被移除掉');
},
}
})