微信小程序复杂对象的双向绑定(附代码可直接使用)

发布于:2023-01-04 ⋅ 阅读:(272) ⋅ 点赞:(0)

一 双向绑定报错:Maximum call stack size exceeded

最近在小程序的开发过程中,遇到一个需求,需要绑定一个list到自定义表单组件,组件根据列表渲染表单,表单的值需要和父组件双向绑定。
但是这里却出现了问题,本人先使用vue的方式将list直接做整体绑定。

<k-input-group2 model:input_list="{{input_group_list}}" />
	... ...
    data: {
        input_group_list: [{
                type: "input",
                label: "名称"
                placeholder: "",
                disabled: false,
                value: "1"
            },{
                type: "input",
                label: "地址",
                placeholder: "",
                disabled: false,
                value: ""
            }]
    }
    ... ...

结果在子组件内部使用setData对list的属性做出变更时直接报错栈溢出。

<input class="weui-input" bindinput="bindChange" value="{{item.value}}" data-index="{{index}}" />
	... ...
    methods: {
        bindChange: function ( e:any ) {
            console.log('改变,携带值为', e.detail.value)
            let index = e.currentTarget.dataset.index
            this.setData({
              [`input_list[${index}].value`]: e.detail.value
            })
        }
    }
    ... ...

这里运行时报错:Maximum call stack size exceeded
而使用"a.b"的路径方式绑定也是不行的,首先不符合需求,其次官方文档上也写明微信小程序目前为止只是支持简单对象的双向绑定,只支持单一字段的绑定,表达式、路径和对象等都不支持。。

二 实现微信小程序复杂对象的双向绑定

于是考虑将list转为json串做双向绑定的载体。
首先将list定义为json串。

Page({
    data: {
        input_group_list: "[]"
    },
    onLoad() {
        this.setData({
            input_group_list: JSON.stringify([{
                type: "input",
                label: "名称",
                placeholder: "",
                disabled: false,
                value: "1"
            },{
                type: "input",
                label: "地址",
                placeholder: "",
                disabled: false,
                value: ""
            }])
        })
    }
}

该字符串传入子组件。

<k-input-group model:input_list="{{input_group_list}}" />

在子组件中接到该数据,并做一个映射,方便使用。

	... ...
    properties: {
        input_list: {
            type: String,
            defalut: "[]"
        }
    }
    data: {
        input_list_local: []
    },
    observers: {
        'input_list': function(input_list) {
            this.setData({
                input_list_local: JSON.parse(input_list)
            })
        }
    }
	... ...

在子组件中,在input值改变时,更新list的值。

	... ...
    methods: {
        bindChange: function ( e:any ) {
            console.log('改变,携带值为', e.detail.value)
            let index = e.currentTarget.dataset.index
            this.data.input_list_local[index].value = e.detail.value
            let input_list_local = JSON.stringify(this.data.input_list_local)
            this.setData({
              input_list: input_list_local
            })
        }
    }
    ... ...

现在在父组件打印list的值,发现当子组件表单变化的时候,父组件也改变了。

如果这篇文章对您有帮助,请点个赞给博主一点鼓励。
如果您读完本文有未解决的疑惑,可以在下方评论和博主一起解决。
如果您对博主感兴趣,可以关注博主一起成长。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到