class10:自定义组件的数据监听器-纯数据字段、组件的生命周期、插槽

一、自定义组件的数据监听器-纯数据字段

1.数据监听器的简单例子

在组件data中定义num,点击按钮时通过函数addNum函数num自增1,通过监听器来监听num是否发生改变。

<!--components/test01/test01.wxml-->
<view class="textBox">{{num}}</view>
<button bindtap="addNum" type="primary">点击num+1</button>
// components/test01/test01.js
Component({
    /**
     * 组件的初始数据
     */
    data: {
        num:0
    },

    /**
     * 组件的方法列表
     */
    methods: {
        addNum(){
            this.setData({
                num:this.data.num + 1
            })
        }
    },
    
    // 定义数据监听器
    observers:{
        "num":function(){   //:function可省略
            console.log("监听到num发生改变");
        }
    }
})

在这里插入图片描述
在这里插入图片描述

如果需要监听多个相同数据类型的变化,如num1,num2,num3等,可用逗号隔开:

observers:{
    "num1, num2, num3":function(){
        console.log("监听到num发生改变");
    }
}

可通过function的形参来监听三个 num值的变化:

<!--components/test01/test01.wxml-->
<view class="textBox">{{num1}}</view>
<view class="textBox">{{num2}}</view>
<view class="textBox">{{num3}}</view>
<button bindtap="addNum1" type="primary">点击num1</button>
<button bindtap="addNum2" type="primary">点击num2</button>
<button bindtap="addNum3" type="primary">点击num3</button>
// components/test01/test01.js
Component({
    /**
     * 组件的初始数据
     */
    data: {
        num1: 0,
        num2: 0,
        num3: 0,
    },

    /**
     * 组件的方法列表
     */
    methods: {
        addNum1(){
            this.setData({
                num1:this.data.num1 + 1
            })
        },
        addNum2(){
            this.setData({
                num2:this.data.num2 + 1
            })
        },
        addNum3(){
            this.setData({
                num3:this.data.num3 + 1
            })
        }
    },
    
    // 定义数据监听器
    observers:{
        "num1, num2, num3":function(newVal1, newVal2, newVal3){
            console.log(newVal1, newVal2, newVal3);
        }
    }
})

在这里插入图片描述
在这里插入图片描述

监听对象:

// components/test01/test01.js
Component({
    /**
     * 组件的初始数据
     */
    data: {
        obj:{
            name:"罗栎洵",
            age:18
        }
    },

    /**
     * 组件的方法列表
     */
    methods: {
        setObj(){
            this.setData({
                "obj.name":"勒布朗"
            })
        }
    },
    // 定义数据监听器
    observers:{
        "obj.name":function(newVal){
            console.log("监听到obj.name发生变化为:");
            console.log(newVal);
        }
    }
})
<!--components/test01/test01.wxml-->
<view class="textBox">{{obj.name}}</view>
<button bindtap="setObj" type="primary">点击</button>

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

注:
数据监听器监听的是当前数据是否被setData(),即使被setData后的数据与之前一样,也认为数据被修改了,数据监听器也会被触发。
数据监听器的处理函数中,不要修改本身监听的数据字段,否则会进入死循环。

案例:通过按钮改变RGB的值(R、G、B),从而改变颜色块的颜色,监听器监听RGB是否发生变化,当这三个分量发生变化时,修改颜色的RGB值(colorRGB)。

<!--components/test02/test02.wxml-->
<view class="colorBox" style="background-color: rgb({{colorRGB}});"></view>
<view class="colorShow">{{rgb.r}} {{rgb.g}} {{rgb.b}}</view>
<button bindtap="changeR" type="primary">R</button>
<button bindtap="changeG" type="primary">G</button>
<button bindtap="changeB" type="primary">B</button>
/* components/test02/test02.wxss */
.colorBox{
    height: 300rpx;
    border: 1px solid;
}

.colorShow{
    font-size: 100rpx;
}
// components/test02/test02.js
Component({
    /**
     * 组件的初始数据
     */
    data: {
        rgb: {
            r: 0,
            g: 0,
            b: 0
        },
        colorRGB: "0,0,0"
    },

    /**
     * 组件的方法列表
     */
    methods: {
        changeR() {
            this.setData({
                "rgb.r": this.data.rgb.r + 10 > 255 ? 255 : this.data.rgb.r + 10,
            })          
        },
        changeG() {
            this.setData({
                "rgb.g": this.data.rgb.g + 10 > 255 ? 255 : this.data.rgb.g + 10,
            })          
        },
        changeB() {
            this.setData({
                "rgb.b": this.data.rgb.b + 10 > 255 ? 255 : this.data.rgb.b + 10,
            })            
        }
    },
    observers:{
        "rgb.r, rgb.g, rgb.b":function(r, g, b){
            this.setData({
                colorRGB:`${r}, ${g}, ${b}`
            })
        }
    }
    // observers:{
    //     // ** 为通配符:监听rgb对象下所有的子数据
    //     "rgb.**":function(obj){
    //         this.setData({
    //             colorRGB:`${obj.r}, ${obj.g}, ${obj.b}`
    //         })
    //     }
    // }
})

在这里插入图片描述
在这里插入图片描述

2.纯数据字段

说明:纯数据字段不渲染到wxml结构中的数据,不参与页面渲染。
优点:性能更高,运算更快。

如:

// components/test02/test02.js
options:{
    // 设置所有以_开头的data数据为纯数据字段
    pureDataPattern: /^_/   //正则表达式
},

二、组件的生命周期

链接: https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html

1.组件的生命周期

组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。

其中,最重要的生命周期是 created attached detached ,包含一个组件实例生命流程的最主要时间点

组件实例刚刚被创建好时, created 生命周期被触发。此时,组件数据 this.data 就是在 Component 构造器中定义的数据 data 。 此时还不能调用 setData 。 通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段。

在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data 已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。

在组件离开页面节点树后, detached 生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则 detached 会被触发。

在这里插入图片描述

2.定义生命周期方法

生命周期方法可以直接定义在 Component 构造器的第一级参数中。
自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段 内进行声明(这是推荐的方式,其优先级最高)。

示例:当页面初步完成时,只触发created和attached,当点击按钮时isShow变为FALSE,相当于被页面移除,此时触发detached。

在这里插入图片描述

<!--pages/home/home.wxml-->
<button bindtap="hidden" type="primary">点击</button> 
<my_test03 wx:if="{{isShow}}"></my_test03> 
// pages/home/home.js
Page({

    /**
     * 页面的初始数据
     */
    data: {
        isShow:true
    },

    hidden(){
        this.setData({
            isShow:false
        })
    },
})
// components/test03/test03.js
Component({
    lifetimes: {
        created: function () {
            //组件实例刚刚被创建好时, created 生命周期被触发
            console.log("created");
        },
        attached: function () {
            // 在组件实例进入页面节点树时执行
            console.log("attached");
        },
        detached: function () {
            // 在组件实例被从页面节点树移除时执行
            console.log("detached");
        },
    },
    // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
    // attached: function() {
    //   // 在组件实例进入页面节点树时执行
    // },
    // detached: function() {
    //   // 在组件实例被从页面节点树移除时执行
    // },
    // ...
})

3.组件所在页面的生命周期

说明:pageLifetimes:show、hide、resize
在这里插入图片描述

// components/test03/test03.js
Component({
    //定义组件所在页面的生命周期
    pageLifetimes:{
        show(){
            console.log("show:组件页面显示时触发")
        },
        hide(){
            console.log("hide:组件页面被隐藏时触发");
        },
        resize(){
            console.log("resize:组件页面尺寸发生改变时触发");
        }
    }
})

在这里插入图片描述

当网页初始化完成时,加载组件会触发show;当切换后台后,组件页面被隐藏,触发hide。

切后台方法:工具->工具栏管理->勾选切后台

三、插槽 slot

1.默认(单个)插槽

页面使用组件,则页面成为父组件,组件成为子组件。
默认插槽即使写很多slot标签也只会引用一个。

示例:

<!--pages/home/home.wxml-->
<my_test04>
    <view>home页面引用的组件内容:即子组件标签定义的内容</view>
</my_test04>
<!--components/test04/test04.wxml-->
<view>
    <!-- slot占一个空位,用于父组件填坑,接收wxml结构 -->
    <!-- 单个(默认插槽):接收所有定义在子组件标签间的内容 -->
    <slot></slot>
    <text>这是子组件wxml内容</text>
</view>

当定义slot标签时页面效果:

在这里插入图片描述

当未定义slot标签时页面效果:
在这里插入图片描述

2.具名(多个)插槽

在子组件中定义多个slot标签,并为slot标签定义自己的名字,每一个slot标签接收同名父组件传给子组件的数据。

若子组件的slot标签未定义名字,则接收父组件中所有没有定义名字的数据;若子组件中没有未定义名字的slot标签,且父组件中存在未定义名字的数据,则该数据不会被渲染到wxml结构中。

注:使用多个插槽时需要在组件js中开启多个插槽的功能:multipleSlots

// components/test04/test04.js
Component({
    options:{
        multipleSlots: true  // 启用多个slot插槽功能
    },
})

示例:

<!--pages/home/home.wxml-->
<my_test04>
    <view slot="let1">父组件填入第一个插槽的数据</view>
    <view slot="let2">父组件填入第二个插槽的数据</view> 
    <view>home页面引用的组件内容:即子组件标签定义的内容</view>
    <view>父组件填入未定义名字插槽的数据</view>
</my_test04>
<!--components/test04/test04.wxml-->
<view>
    <slot name="let1"></slot>
    <slot name="let2"></slot>
    <slot></slot> // 该slot标签接收父组件中没有定义名字的插槽数据
</view>

在这里插入图片描述

当子组件没有定义slot标签时,父组件中没有名字的插槽数据将不被渲染:
在这里插入图片描述

3.父子组件传值

3种方法:

  • 组件属性传值;
  • 通过绑定事件的方式传值;
  • 通过子组件实例对象的方式。

更多详情,请看下一节。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laker 23

要秃啦,支持一下嘛~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值