邂逅小程序(王洪元)笔记02事件绑定,event时间对象,事件的参数传递,事件冒泡和事件捕获自定义组件,组件和页面通信,组件向引用页传递事件,修改组件中的数据,单插槽,多插槽,组件监听生命周期函数

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('监听组件被移除掉');
    },
  }
  
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值