前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序组件化编程和实践(下)

微信小程序组件化编程和实践(下)

原创
作者头像
疯狂的小程序
发布2018-01-25 17:06:01
1.9K0
发布2018-01-25 17:06:01
举报
文章被收录于专栏:疯狂的小程序疯狂的小程序

现在我们已经可以做到了两个组件之间的数据传递,那么如何在多个组件间传递数据呢?

如上图所示,同级的组件b 和同级的组件c , b 和 c 之间不可以直接获取,b可以获取到a, c 也可以获取到a,而a可以直接获取到 b 和 c。所以,如果想获取到兄弟元素,需要先获取到祖先节点,然后再通过祖先节点获取兄弟节点

我在组件b 里面,我需要先找到祖先组件a的实例,然后用祖先组件a的实例的getRelationNodes方法获取到组件c的实例。

看见没?恐怕我们又要写一大堆重复性的代码了。

幸好,微信小程序还提供了behavior 属性, 这个属性相当于 mixin,很容易理解的,是提高代码复用性的一种方法。

思路:

假设目前有三个组件,组件a,  组件b, 组件c, 其中组件b和组件c是兄弟组件,组建a是b和c的兄弟组件。为了减少代码的重复性,我们把获取父组件的方法,和获取兄弟组件的方法封装一下,封装在 behavior 的 methods 中。只要是引入该behavior的组件,都可以便捷的调用方法。

实现:

新建一个behavior文件,命名无所谓,比如说relation_behavior.js

代码语言:javascript
复制
// 在 get_relation.js 文件里面
module.exports = Behavior({
	methods:{
	    // 获取父组件实例的快捷方法
		_parent () {
			// 如果根据该路径获取到acestor组件为null,则说明this为ancesor
			var parentNode =  this.getRelationNodes('../record_item/record_item')
			if (parentNode&&parentNode.length !== 0) {
				return parentNode[0]
			} else {
				return this
			}
		},
		// 获取兄弟组件实例的快捷方法
		_sibling(name) {
			var node = this._parent().getRelationNodes(`../${name}/${name}`)
			if (node &&node.length > 0) {
				return node[0]
			}
		}
	}
})

然后在组件b, 和 组件c 上引入该behavior,并且调用方法,获取父组件和兄弟组件的实例

代码语言:javascript
复制
// 组件b中
var relation_behavior = require('./path_to_relation_behavior')
Component({
    behaviors:[relation_behavior],
    methods:{
        test () {
            // 获得父组件的实例
            let parent = this._parent()
            
            // 访问父组件的数据d
            console.log(parent.data.name)
            
            // 修改父组件的数据
            parent.setData({
                name: 'test1'
            })
            
            // 获得兄弟组件的实例
            let sibling = this._sibling('c')
            
            // 访问兄弟组件的数据
            console.log(sibling.data.name)
            
            // 修改兄弟组件的数据
            sibling.setData({
                name:"test"
            })
        }
    }
})
 
// 组件c中
var relation_behavior = require('./path_to_relation_behavior')
Component({
    behaviors:[relation_behavior],
    methods:{
        test () {
            // 获得父组件的实例
            let parent = this._parent()
            
            // 访问父组件的数据d
            console.log(parent.data.name)
            
            // 修改父组件的数据
            parent.setData({
                name: 'test1'
            })
            
            // 获得兄弟组件的实例
            let sibling = this._sibling('b')
            
            // 访问兄弟组件的数据
            console.log(sibling.data.name)
            
            // 修改兄弟组件的数据
            sibling.setData({
                name:"test"
            })
        }
    }
})

同时需要注意,c和b两个组件,从relations属性的角度来说,是a的后代组件。

但是组件b和组件c 所处的作用域, 都是主页面的作用域,传入的property都是主页面的property,这样就保证了组件数据的灵活性。relations 像一个隐形的链子一样把一堆组件关联起来,关联起来的组件可以相互访问,修改对方的数据,但是每一个组件都可以从外界独立的获取数据。

看了这么多理论的东西,还是需要一个具体的场景来应用。

比如说,我们有个一个分享记录图片心情的页面,当用户点击【点赞】的按钮时候,该心情的记录 点赞按钮会变红,下面的一栏位置会多出点赞人的名字。

如果不通过组件化,很可能的做法是 修改一个点赞按钮,然后遍历数据更新数据,最后所有记录列表的状态都会被重新渲染一遍。

如果是通过组件化拆分:把点赞的按钮封装为 组件b, 下面点赞人的框封装为组件c, 每一个心情记录都是一个组件a

下面是代码实现

代码语言:javascript
复制
// 在主页面内
<view wx:for='{{feed_item}}'>
    <a item='{{item}}'>
        <b></b>
        <c></c>
    </a>
<view>
 
 
// 在组件a内
var behavior_relation = require('../../relation_behavior.js)  //这里引入上文说的Behavior
Component({
    behaviors:[behavior_relation],
    relations:{
        '../b/b':{
            type: 'descendant'
        }
    }
})
 
// 在组件b内
var behavior_relation = require('../../relation_behavior.js)  //这里引入上文说的Behavior
Component({
    behaviors:[behavior_relation]
    relations:{
        '../a/a':{
            type: 'ancestor'
        }
    },
    data: {
        is_like: false  //控制点赞图标的状态
    },
    methods:{
        // 当用户点赞的时候
        onClick () {
            //  修改本组件的状态
            this.setData({
                is_like: true
            })
            // 修改 c 组件的数据
            this._sibling('c').setData({
                likeStr: this._sibling('c').data.likeStr + '我' 
            })
        }
    }
})
 
// 在组件c内
var behavior_relation = require('../../relation_behavior.js)  //这里引入上文说的Behavior
Component({
    behaviors:[behavior_relation],
    relations:{
        '../a/a':{
            type: 'ancestor'
        }
    },
    data:{
        likeStr:'晓红,小明'
    }
})

这样,组件b 可以修改组件c中的数据。同时,组件b 和 组件c 又可以通过 properties 和 事件系统,和主页面保持独立的数据通信。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档