小程序组件和页面的通信 ★

目录

1、向组件传递数据 — properties

2、向组件传递样式 — externalClasses

3、组件向外传递事件 — 自定义事件

4、页面直接调用组件修改数据/方法 — this.selectComponent

5、组件的插槽 — slot

6、自定义组件练习 — tab-control


很多情况下,组件内展示的内容(数据、样式、标签)并不是在组件内写死的,而且由使用者(引用组件的页面)来决定,这样就可以做到类似于 vue 的父子组件传值,组件还可以定义自定义事件向页面发送信息,示意图如下:

小程序组件和页面的通信 ★_第1张图片

1、向组件传递数据 — properties

大部分情况下,组件只负责布局和样式,内容是由使用组件的对象来决定,所以,我们经常需要从外部传递数据给组件,让组件来进行展示。向组件传递数据 — 使用 properties 属性:


{{title}}        
我是组件的内容/view>


Component({
    properties:{           
        //title:String,
        title:{            
            type:String,
            value:'默认犬种'
        },
        observer:function(neVal,oldVal){    
            console.log(newVal,oldVal);
        }
    },
    data:{}
    methods:{}
})


        

                       

2、向组件传递样式 — externalClasses

有时候,我们不希望将样式在组件内固定不变,而是外部可以决定样式,这个时候,我们可以使用 externalClasses 属性:(1)在 Component 对象中,定义 externalClasses 属性(2)在组件内的 wxml 中使用 externalClasses 属性中的 class(3)在页面中传入对应的 class,并且给这个 class 设置样式。


我是组件    
我是组件的内容/view>


Component({
    properties:{},
    externalClasses:['titleclass'],   
    data:{}
    methods:{}
})


      
     
    

3、组件向外传递事件 — 自定义事件

有时候是自定义组件内部发生了事件,需要告知使用者(引用组件的页面),这个时候可以使用自定义事件:(1)监听组件的点击,为其绑定点击函数(2)在组件的 js 文件定义点击函数,并通过:this.triggerEvent('increment',{name:'erha'},{}); 的方式向外传递事件(3)在页面的的组件占位符上对组件发射出来的事件进行监听,并在页面的 js 文件对鉴定事件进行定义(4)在页面的 js 文件中可以通过 event 参数拿到组件传递过来的 payload 参数。





Component({
    methods:{
        handleIncrement(){
            this.triggerEvent('increment',{name:'erha'},{});    
        }
    }
})





Page({
    data:{
        counter:0;
    }, 
    handleIncrement(event){
        console.log(event);    
        this.setData({
            counter: this.data.counter + 1;
        })
    }
})

4、页面直接调用组件修改数据/方法 — this.selectComponent

在页面或者别的组件中,可以通过 selectComponent() 方法获取指定的 id 或 class 的组件对象(推荐使用 id 的方式),然后通过该组件对象即可直接调用该组件内的数据和方法,不推荐直接修改组件中的数据,而是调用组件内的方法修改组件内的数据。

            
组件内的计数:{{counter}}            {
                   "components":true;
Component({                                      }
    data:{ counter:0 },
    methods:{ increment(num){ this.setData({counter:this.data.counter + num}) }
})
-----------------------------------------------------------------------------------------------------------------

    


                         
Page({                                            "usingComponents":{ "my-sel":"/components/my-sel/my-sel" }
    handleIncrementCpn(){
        
        const my_sel_class = this.selectComponent('.sel-class');
        const my_sel_id = this.selectComponent('#sel-id');      
        
        my_sel_id.setData({
            counter: my_sel.data.counter + 20;
        })
        
        my_sel_id.increment(10);
    }
})

5、组件的插槽 — slot

5.1、slot 插槽的定义:在生活中很多地方都有插槽,电脑的 USB 插槽,插板当中的电源插槽。插槽的目的是让原来的设备具备更多的扩展性,比如电脑的 USB 插槽就可以插入U盘、硬盘、手机、音响、键盘、鼠标等等。组件的 slot 插槽也是为了让我们封装的组件更加具有扩展性,使用者可以决定组件内部的一些内容到底展示什么。

5.2、单个插槽的使用

除了组件的内容和样式可能由外界决定之外,显示的方式也可由外界决定,比如一个组件定义了头部和尾部,但是中间的内容可能是一段文字,也可能是一张图片,或者是一个进度条。在不确定外界想插入什么的前提下,我们可以在组件内预留 slot 插槽。

                        
组件头部                                          {
                     "components":true;
组件尾部                                          }
-----------------------------------------------------------------------------------------------------------------

"usingComponents":{ "my-slot":"/components/my-slot/my-slot" }


     
             

5.3、多个插槽的使用

有时候为了让组件更加灵活,需要定义多个插槽,为了区分它们,需要给每一个组件 name 属性,而且还必须在组件的 Component 对象中添加一个选项:options:{ multipleSlots:true }。

                        
组件头部                                            {
                      "components":true;
                 }
                 
组件尾部                                            Component({
                                                                    options:{
                                                                        multipleSlots:true
                                                                    }
                                                                })
-----------------------------------------------------------------------------------------------------------------

"usingComponents":{ "my-slots":"/components/my-slots/my-slots" }



    

6、自定义组件练习 — tab-control

需求:开发一个 tabcontrol 自定义控制导航组件,如下图所示,为了提高该组件的复用性,要求导航中的文字不能在组件中写死,而是由外界页面传递进去的,而且在点击该组件时需要向外界发送自定义事件,告知外界页面导航中的哪个模块被点击了。

开发前准备:需要在根目录下新建 components\tab-control 组件,tab-control 组件的 json 文件中,有一个 "component":true 标识,只有加上这行代码,当前的文件夹才是一个组件。然后到 home.json 文件中对该组件进行注册:{"usingComponents":{"tab-control":/component/tab-control/tab-control}},然后再到 home.wxml 通过 标签对其进行引用。



  
    
      {{item}}
    
  


.tab-control{              .tab-item{                .active{         .active text{
    display:flex;              flex:1;                   color:red;       border-bottom:6rpx solid red;
    height:88rpx;              text-align:center;    }                    padding:26rpx 16rpx;
    line-height:88rpx;     }                                          }
}
              
Component({                                               {
    properties:{              "component":true
        titles:{                                          }
            type:Array,
            value:[]
        }
    },
    data:{ currentIndex:0 }
    methods:{
        handleItemclick(event){
            const index = event.currentTarget.dataset.index;    
            this.setData({ currentIndex:index; });              
            
            this.triggerEvent('itemclick',{index,title:this.properties.titles[index]},{});
        }
    }
}
-----------------------------------------------------------------------------------------------------------------

"usingComponents":{ "tab-control":"/components/tab-control/tab-control" }



Page({
    handleTabClick(event){
        console.log(event);    
    }
})

你可能感兴趣的:(微信小程序)