zhangdaren / miniprogram-to-uniapp

轻松将各种小程序转换为uni-app项目
Other
1.67k stars 277 forks source link

setData运行时报错 #58

Closed yyISACoder closed 4 years ago

yyISACoder commented 4 years ago

在onload中使用setData给data中多层级数据对象的内部属性赋值时,会出现Avoid adding reactive properties to a Vue instance or its root $data at runtime - declare it upfront in the data option.望解决

zhangdaren commented 4 years ago

这是因为vue不支持给未在data里声明的变量赋值,这个需要将变量手动添加到报错页面的data属性里

yyISACoder commented 4 years ago

变量我都赋了初始值的,这里我想要更改非根级节点的数据,比如data:{test:{key:‘defaultVal’}},这里我是更改test.key的值,就会报错,你看下能找到原因吗

zhangdaren commented 4 years ago

经测试没问题哈,下面附上我的代码

<template>
    <view>
        <view @click="setDataVal">改变值</view>
        <view>test.key -- > {{ test.key }}</view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            test: { key: 'defaultVal' }
        };
    },
    methods: {
        setDataVal() {
            this.setData({ 'test.key': 'cccc' });

                   // this.setData({"cc": "error"}) 执行这行代码会报错,因为没有cc这个变量
        },
        setData: function(obj, callback) {
            let that = this;
            let keys = [];
            let val, data;
            Object.keys(obj).forEach(function(key) {
                keys = key.split('.');
                val = obj[key];
                data = that.$data;
                keys.forEach(function(key2, index) {
                    if (index + 1 == keys.length) {
                        that.$set(data, key2, val);
                    } else {
                        if (!data[key2]) {
                            that.$set(data, key2, {});
                        }
                    }

                    data = data[key2];
                });
            });
            callback && callback();
        }
    }
};
</script>
<style>
</style>
yyISACoder commented 4 years ago

emmm,那就奇怪了,我这边一直跑不起来呢 关键代码我贴一下:

data() { return { canvasWidth: 0, canvasHeight: 0, isIos: app.globalData.isIos, list: [{ id: 1, top: 2, left: 0, opacity: 1, dis: true, width: '33.3%', height: '99%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 2, top: 2, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 3, top: 0, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 4, top: 2, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 5, top: 0, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 6, top: 2, left: 0, dis: true, opacity: 1, width: '29%', height: '32.72%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 7, top: 0, opacity: 1, left: 0, dis: true, width: '29%', height: '32.72%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 8, top: 0, left: 0, dis: true, opacity: 1, width: '29%', height: '32.72%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }], //选择的本地图片临时路径列表 filePaths: [], //用户信息 userInfo: {}, isShowGuide1: false, isShowGuide2: false, isShowGuide3: false, //设备像素比 pixelRatio: app.globalData.myDevice.pixelRatio, //movableArea的left值 movableLeft: 0, //movableArea的top值 movableTop: 0, //引导图 guideImg1: '', guideImg2: '', guideImg3: '', //二维码图片 codeImg: '', //屏幕宽度 clientWidth: app.globalData.myDevice.screenWidth, //区分是否是制作社团模卡 isMakeOrg: false, orgName: '', //背景颜色 bgColor: '', //字体颜色 fontColor: '', //信息边框颜色 borderColor: '' }; },

this.setData({ 'list[0].src': this.filePaths[0], 'list[1].src': this.filePaths[1], 'list[2].src': this.filePaths[2], 'list[3].src': this.filePaths[3], 'list[4].src': this.filePaths[4], 'list[5].src': this.filePaths[5], 'list[6].src': this.filePaths[6], 'list[7].src': this.filePaths[7] });

zhangdaren commented 4 years ago

大概明白了,是setData这个方法没有处理过这种情况。。。我先研究一下,这两天更新一下哈 

不管你是逐渐繁华,还是即将枯萎,此时此刻才是你的人生!

 

------------------ 原始邮件 ------------------ 发件人: "Carl"<notifications@github.com>; 发送时间: 2020年1月7日(星期二) 下午3:13 收件人: "zhangdaren/miniprogram-to-uniap"<miniprogram-to-uniapp@noreply.github.com>; 抄送: "张鹏"<375890534@qq.com>; "Comment"<comment@noreply.github.com>; 主题: Re: [zhangdaren/miniprogram-to-uniapp] setData运行时报错 (#58)

emmm,那就奇怪了,我这边一直跑不起来呢 关键代码我贴一下:

data() { return { canvasWidth: 0, canvasHeight: 0, isIos: app.globalData.isIos, list: [{ id: 1, top: 2, left: 0, opacity: 1, dis: true, width: '33.3%', height: '99%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 2, top: 2, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 3, top: 0, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 4, top: 2, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 5, top: 0, left: 0, opacity: 1, dis: true, width: '18.5%', height: '49.3%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 6, top: 2, left: 0, dis: true, opacity: 1, width: '29%', height: '32.72%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 7, top: 0, opacity: 1, left: 0, dis: true, width: '29%', height: '32.72%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }, { id: 8, top: 0, left: 0, dis: true, opacity: 1, width: '29%', height: '32.72%', realWidth: 0, realHeight: 0, zIndex: 10, src: '', scrollTop: 0, scrollLeft: 0, touch: { distance: 0, scale: 1, baseWidth: null, baseHeight: null, scaleWidth: null, scaleHeight: null } }], //选择的本地图片临时路径列表 filePaths: [], //用户信息 userInfo: {}, isShowGuide1: false, isShowGuide2: false, isShowGuide3: false, //设备像素比 pixelRatio: app.globalData.myDevice.pixelRatio, //movableArea的left值 movableLeft: 0, //movableArea的top值 movableTop: 0, //引导图 guideImg1: '', guideImg2: '', guideImg3: '', //二维码图片 codeImg: '', //屏幕宽度 clientWidth: app.globalData.myDevice.screenWidth, //区分是否是制作社团模卡 isMakeOrg: false, orgName: '', //背景颜色 bgColor: '', //字体颜色 fontColor: '', //信息边框颜色 borderColor: '' }; },

this.setData({ 'list[0].src': this.filePaths[0], 'list[1].src': this.filePaths[1], 'list[2].src': this.filePaths[2], 'list[3].src': this.filePaths[3], 'list[4].src': this.filePaths[4], 'list[5].src': this.filePaths[5], 'list[6].src': this.filePaths[6], 'list[7].src': this.filePaths[7] });

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

zhangdaren commented 4 years ago

把这个页面的setData改成这样吧,就可以了,但还不完善没法适应所有情况,先改成这样吧,,我还要再看看。

setData: function(obj, callback) {
            let that = this;
            let keys = [];
            let val, data;
            Object.keys(obj).forEach(function(key) {
                keys = key.split('.');
                val = obj[key];
                data = that.$data;
                keys.forEach(function(key2, index) {
                    if (index + 1 == keys.length) {
                        that.$set(data, key2, val);
                    } else {
                        if (/\[\d+\]/.test(key2)) {
                            let re = /(.*?)\[(\d+)\]/.exec(key2);
                            let name = re[1];
                            let index = re[2];
                            data = data[name][index];
                        } else if (!data[key2]) {
                            that.$set(data, key2, {});
                            data = data[key2];
                        }
                    }
                });
            });
            callback && callback();
        }
zhangdaren commented 4 years ago

升级最新版, 现在支持给list[0].item[0].src这种赋值,然后对于list[0][1]这种不支持。

zzlb0224 commented 4 years ago

正则部分转义之后出现错误 应该用
/\\\[\\\d+\\\]/

zhangdaren commented 4 years ago

/\[\\d+\]/

不是太明白,出现错误是在哪种情况出现的?运行微信小程序ok,h5ok,app测试通过,

v1.0.53里的setData已经完善为如下代码:

setData: function(obj, callback) {
    let that = this;
    let keys = [];
    let val, data;
    let reg = /\[\d+\]/;
    Object.keys(obj).forEach(function(key) {
        keys = key.split('.');
        val = obj[key];
        data = that.$data;
        keys.forEach(function(key2, index) {
            if (index + 1 == keys.length) {
                if (reg.test(key2)) {
                    let re = /(.*?)\[(\d+)\]/.exec(key2);
                    let name = re[1];
                    let kk = re[2];
                    data = data[name];
                    data[kk] && that.$set(data, kk, val);
                } else {
                    data[key2] && that.$set(data, key2, val);
                }
            } else {
                if (reg.test(key2)) {
                    let re = /(.*?)\[(\d+)\]/.exec(key2);
                    let name = re[1];
                    let kk = re[2];
                    data = data[name][kk];
                } else if (data[key2]) {
                    that.$set(data, key2, {});
                    data = data[key2];
                }
            }
        });
    });
    callback && callback();
}
zhangdaren commented 4 years ago

正则部分转义之后出现错误 应该用 /\\\[\\\d+\\\]/

明白了,是输出到页面时,\会转义导致正则不对,,

最新v1.0.54已经将setData代码放入mixins里,不在每个vue文件都添加setData了,并且setData代码已经还原为之前版本,因为发现还是有问题。

zhangdaren commented 4 years ago

v1.0.64 已经使用网友的超强setData代码,不会再报这种错误了。