亚洲
亚洲
  • 发布:2022-12-15 11:57
  • 更新:2022-12-15 15:37
  • 阅读:376

【报Bug】视图渲染和对象数据不一致,视图未同步渲染

分类:uni-app

注:h5是正常的,小程序存在此问题

代码功能就是一个选择城市的页面,最上方可以输入相关字符搜索城市,左边悬浮可以点击滚动到具体前缀的城市集合,也可以按住进行拖动同时滚动城市集合。

目前遇到一个很蛋疼的问题,当我执行搜索时,但发现对象数据是更新成功了的(即cityValue是已经更新过的),但是视图渲染一直存在bug。

比如我在最上方输入框中搜索 “宁” ,再搜索 “安”,然后视图渲染后的顺序就会乱掉并且存在无效数据的的渲染,但cityValue数据本身却是正确的。

具体的问题可以点击 操作录像 查看。

录像的链接地址:https://www.loom.com/share/9b4bbe86208a48d59b35d90db62aa06f

以下是的选择城市页面的全部代码,附件里也有压缩后的代码文件,可以直接复制运行。

全部代码:

<template>  
    <view class="container">  
        <scroll-view class="scroller">  
            <div class="searchDiv">  
                <input type="text" v-model="searchTxt" confirm-type="search" @confirm="doSearch" class="searchInput"  
                    placeholder="请输入城市名、拼音或首字母查询">  
            </div>  
            <div v-for="(item,index) in cityValue" :key="index">  
                <div :class="'cityPrefix prefix_'   index">{{index}}</div>  
                <div class="provinceCity" v-for="cityName in item" :key="index">  
                    <div class="cityItem">{{cityName}}</div>  
                </div>  
            </div>  
        </scroll-view>  

        <div class="fixedPrefixBar" @touchmove.stop.prevent="disabledScroll">  
            <div @click="choicePrefix(index)"  
                :class="[prefix == index ? 'fixedPrefixBarItemChecked' : 'fixedPrefixBarItem']"  
                v-for="(item, index) in cityValue" :key="index" @touchmove.stop.prevent="disabledScroll"  
                @touchstart="touchstart($event)" @touchmove="touchmove($event)" @touchend="touchend($event)">  
                {{index}}  
            </div>  
        </div>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                prefix: 'A',  
                cityValue: {},  
                searchTxt: "",  
                fixedListTop: 0,  
                fixedItemHeight: 0,  
                isMove: false,  
                cityRawValue: {  
                    'A': [  
                        "安阳",  
                        "安庆",  
                        "鞍山",  
                        "安康",  
                        "安顺",  
                        "阿克苏",  
                        "阿拉尔",  
                        "阿拉善",  
                        "阿勒泰",  
                        "阿里",  
                        "阿坝",  
                        "澳门",  
                    ],  
                    'B': [  
                        "北京",  
                        "白银",  
                        "白城",  
                        "白山",  
                        "巴中",  
                        "巴彦淖尔",  
                        "滨州",  
                        "蚌埠",  
                        "亳州",  
                        "本溪",  
                        "北海",  
                        "百色",  
                        "保定",  
                        "宝鸡",  
                        "包头",  
                        "保山",  
                        "毕节",  
                        "巴音",  
                        "博尔塔拉"  
                    ],  
                    'C': [  
                        "重庆",  
                        "常州",  
                        "常德",  
                        "长沙",  
                        "长治",  
                        "长春",  
                        "潮州",  
                        "成都",  
                        "滁州",  
                        "池州",  
                        "朝阳",  
                        "崇左",  
                        "郴州",  
                        "承德",  
                        "沧州",  
                        "赤峰",  
                        "昌吉",  
                        "楚雄"  
                    ],  
                    'D': [  
                        "大连",  
                        "大庆",  
                        "大兴安岭",  
                        "大同",  
                        "东莞",  
                        "东营",  
                        "德阳",  
                        "德州",  
                        "达州",  
                        "丹东",  
                        "定西",  
                        "大理",  
                        "德宏",  
                        "迪庆"  
                    ],  
                    'E': [  
                        "鄂州",  
                        "鄂尔多斯",  
                        "恩施",  
                    ],  
                    'F': [  
                        "抚顺",  
                        "抚州",  
                        "阜阳",  
                        "阜新",  
                        "佛山",  
                        "防城港",  
                        "福州",  
                    ],  
                    'G': ["广州", "广元", "广安", "贵港", "贵阳", "桂林", "赣州", "固原", "甘孜", "甘南", "果洛"],  
                    'H': [  
                        "淮南",  
                        "淮北",  
                        "淮安",  
                        "黄石",  
                        "黄冈",  
                        "黄山",  
                        "河源",  
                        "河池",  
                        "衡阳",  
                        "衡水",  
                        "哈尔滨",  
                        "哈密",  
                        "呼和浩特",  
                        "呼伦贝尔",  
                        "惠州",  
                        "鹤壁",  
                        "菏泽",  
                        "合肥",  
                        "葫芦岛",  
                        "贺州",  
                        "怀化",  
                        "鹤岗",  
                        "黑河",  
                        "邯郸",  
                        "杭州",  
                        "湖州",  
                        "汉中",  
                        "海口",  
                        "海北",  
                        "海西",  
                        "海南",  
                        "黄南",  
                        "红河"  
                    ],  
                    'J': [  
                        "济源",  
                        "济南",  
                        "济宁",  
                        "荆门",  
                        "荆州",  
                        "晋城",  
                        "晋中",  
                        "金昌",  
                        "金华",  
                        "江门",  
                        "九江",  
                        "吉安",  
                        "吉林",  
                        "揭阳",  
                        "焦作",  
                        "锦州",  
                        "鸡西",  
                        "佳木斯",  
                        "嘉峪关",  
                        "酒泉",  
                        "嘉兴",  
                        "景德镇",  
                    ],  
                    'K': [  
                        "开封",  
                        "昆明",  
                        "克拉玛依",  
                        "喀什",  
                        "克孜勒苏",  
                    ],  
                    'L': [  
                        "六安",  
                        "六盘水",  
                        "临沂",  
                        "临沧",  
                        "临汾",  
                        "辽阳",  
                        "辽源",  
                        "丽水",  
                        "丽江",  
                        "泸州",  
                        "乐山",  
                        "洛阳",  
                        "漯河",  
                        "莱芜",  
                        "聊城",  
                        "柳州",  
                        "来宾",  
                        "连云港",  
                        "娄底",  
                        "兰州",  
                        "陇南",  
                        "吕梁",  
                        "廊坊",  
                        "龙岩",  
                        "拉萨",  
                        "临夏",  
                    ],  
                    'M': [  
                        "茂名",  
                        "梅州",  
                        "绵阳",  
                        "眉山",  
                        "马鞍山",  
                        "牡丹",  
                    ],  
                    'N': [  
                        "南充",  
                        "南阳",  
                        "南宁",  
                        "南京",  
                        "南通",  
                        "南昌",  
                        "南平",  
                        "宁波",  
                        "宁德",  
                        "内江",  
                        "怒江",  
                    ],  
                    'P': [  
                        "平顶山",  
                        "平凉",  
                        "攀枝花",  
                        "濮阳",  
                        "盘锦",  
                        "萍乡",  
                        "莆田",  
                        "普洱",  
                    ],  
                    'Q': [  
                        "清远",  
                        "青岛",  
                        "钦州",  
                        "齐齐哈尔",  
                        "七台河",  
                        "庆阳",  
                        "秦皇岛",  
                        "衢州",  
                        "泉州",  
                        "曲靖",  
                        "黔东南",  
                        "黔南",  
                        "黔西南"  
                    ],  
                    'R': ["日照", "日喀则"],  
                    'S': [  
                        "上海",  
                        "三门峡",  
                        "三明",  
                        "三亚",  
                        "汕头",  
                        "汕尾",  
                        "韶关",  
                        "深圳",  
                        "遂宁",  
                        "商丘",  
                        "宿州",  
                        "沈阳",  
                        "苏州",  
                        "宿迁",  
                        "十堰",  
                        "随州",  
                        "邵阳",  
                        "双鸭山",  
                        "绥化",  
                        "朔州",  
                        "石家庄",  
                        "绍兴",  
                        "上饶",  
                        "商洛",  
                        "石嘴山",  
                        "四平",  
                        "松原",  
                    ],  
                    'T': [  
                        "天津",  
                        "泰安",  
                        "泰州",  
                        "通辽",  
                        "通化",  
                        "铜川",  
                        "铜仁",  
                        "铜陵",  
                        "铁岭",  
                        "天水",  
                        "太原",  
                        "唐山",  
                        "台州",  
                        "吐鲁番",  
                    ],  
                    'W': [  
                        "武汉",  
                        "武威",  
                        "乌海",  
                        "乌兰察布",  
                        "乌鲁木齐",  
                        "潍坊",  
                        "威海",  
                        "芜湖",  
                        "梧州",  
                        "无锡",  
                        "温州",  
                        "渭南",  
                        "吴忠",  
                    ],  
                    'X': [  
                        "西昌",  
                        "西安",  
                        "西宁",  
                        "新乡",  
                        "新余",  
                        "许昌",  
                        "信阳",  
                        "宣城",  
                        "徐州",  
                        "襄阳",  
                        "孝感",  
                        "咸宁",  
                        "湘潭",  
                        "忻州",  
                        "邢台",  
                        "咸阳",  
                        "厦门",  
                        "湘西",  
                        "凉山",  
                        "西双版纳"  
                    ],  
                    'Y': [  
                        "宜宾",  
                        "宜昌",  
                        "宜春",  
                        "玉林",  
                        "玉溪",  
                        "阳江",  
                        "阳泉",  
                        "云浮",  
                        "雅安",  
                        "烟台",  
                        "营口",  
                        "盐城",  
                        "扬州",  
                        "岳阳",  
                        "益阳",  
                        "永州",  
                        "伊春",  
                        "运城",  
                        "鹰潭",  
                        "延安",  
                        "榆林",  
                        "银川",  
                        "延边",  
                        "伊犁",  
                        "玉树"  
                    ],  
                    'Z': [  
                        "张家界",  
                        "张掖",  
                        "张家口",  
                        "中山",  
                        "中卫",  
                        "珠海",  
                        "湛江",  
                        "肇庆",  
                        "自贡",  
                        "资阳",  
                        "郑州",  
                        "周口",  
                        "驻马店",  
                        "淄博",  
                        "枣庄",  
                        "镇江",  
                        "株洲",  
                        "舟山",  
                        "漳州",  
                        "昭通",  
                        "遵义",  
                    ],  
                }  
            }  
        },  
        onReady() {  
            this.cityValue = this.cityRawValue;  

            this.getFixedPrefixBarHeight();  
        },  
        methods: {  
            touchstart(e) {  
                this.isMove = true;  
            },  
            touchmove(e) {  
                if (this.isMove) {  
                    var _karr = Object.keys(this.cityValue);  
                    var _DValue = parseInt((e.touches[0].clientY - this.fixedListTop) / this.fixedItemHeight);  
                    if (_DValue > (_karr.length - 1) || _DValue < 0) {  
                        return false;  
                    } else {  
                        this.choicePrefix(_karr[_DValue]);  
                    }  
                }  
            },  
            touchend(e) {  
                this.isMove = false;  
            },  
            disabledScroll() {  
                return;  
            },  
            getFixedPrefixBarHeight() {  
                const self = this;  
                setTimeout(function() {  
                    uni.createSelectorQuery().in(self).select(".fixedPrefixBar").boundingClientRect(data => {  
                        self.fixedListTop = data.top;  
                    }).exec();  

                    uni.createSelectorQuery().in(self).select(".fixedPrefixBarItemChecked").boundingClientRect(  
                        data => {  
                            self.fixedItemHeight = data.height;  
                        }).exec();  
                }, 100);  
            },  
            doSearch() {  
                this.cityValue = {};  

                for (var index in this.cityRawValue) {  
                    var valid = false;  
                    var _arr = [];  
                    for (var _index in this.cityRawValue[index]) {  
                        if (this.cityRawValue[index][_index].indexOf(this.searchTxt) != -1) {  
                            valid = true;  
                            _arr.push(this.cityRawValue[index][_index]);  
                        }  
                    }  

                    if (valid) {  
                        this.cityValue[index] = _arr;  
                    }  
                }  

                console.log(Object.keys(this.cityValue));  
            },  
            choicePrefix(prefix) {  
                if (this.prefix != prefix) {  
                    this.prefix = prefix;  
                    uni.pageScrollTo({  
                        selector: ".prefix_"   prefix,  
                        duration: 300  
                    });  
                }  
            },  
        }  
    }  
</script>  

<style>  
    .container {  
        position: absolute;  
        top: 0px;  
        left: 0px;  
        right: 0px;  
        bottom: 0px;  
    }  

    .scroller {  
        top: 0px;  
        bottom: 0px;  
        left: 0px;  
        right: 0px;  
    }  

    .cityPrefix {  
        padding-left: 30upx;  
        width: 100%;  
        height: 50upx;  
        line-height: 50upx;  
        background-color: #efefef;  
        color: #333;  
        font-size: 26upx;  
    }  

    .provinceCity {  
        width: 100%;  
        padding-left: 30upx;  
        padding-right: 30upx;  
    }  

    .cityItem {  
        width: 100%;  
        height: 100upx;  
        line-height: 100upx;  
        color: #333;  
        font-size: 30upx;  
        border-bottom: solid 1upx #efefef;  
    }  

    .fixedPrefixBar {  
        width: 60upx;  
        background-color: pink;  
        padding-left: 30upx;  
        display: flex;  
        position: fixed;  
        top: 160upx;  
        right: 0upx;  
        flex-direction: column;  
    }  

    .fixedPrefixBarItem {  
        width: 60upx;  
        height: 40upx;  
        line-height: 40upx;  
        padding-right: 30upx;  
        text-align: center;  
        font-size: 26upx;  
        color: #333333;  
    }  

    .fixedPrefixBarItemChecked {  
        width: 40upx;  
        text-align: center;  
        height: 40upx;  
        line-height: 40upx;  
        margin-left: 10upx;  
        border-radius: 20upx;  
        font-size: 26upx;  
        color: #ffffff;  
        background-color: #00CC00;  
    }  

    .searchDiv {  
        width: 690upx;  
        height: 65upx;  
        margin-left: 30upx;  
        margin-right: 30upx;  
        margin-bottom: 15upx;  
        margin-top: 15upx;  
        border-radius: 50upx;  
        background-color: #e7e7e7;  
        display: flex;  
        flex-direction: row;  
        align-items: center;  
    }  

    .searchIcon {  
        width: 30upx;  
        height: 30upx;  
        margin-right: 10upx;  
        margin-left: 115upx;  
    }  

    .searchInput {  
        width: 515upx;  
        height: 65upx;  
        line-height: 65upx;  
        text-align: left;  
        font-size: 26upx;  
        color: #666;  
    }  

    .locationTitle {  
        margin-left: 30upx;  
        color: #ccc;  
        font-size: 26upx;  
    }  

    .locationCity {  
        width: 230upx;  
        height: 65upx;  
        text-align: center;  
        line-height: 65upx;  
        margin-left: 30upx;  
        border-radius: 60upx;  
        border: solid 1upx #aaa;  
        font-size: 26upx;  
        color: #666;  
        margin-bottom: 20upx;  
        margin-top: 15upx;  
    }  
</style>  
2022-12-15 11:57 负责人:无 分享
已邀请:
亚洲

亚洲 (作者)

很无语,只有小程序有这个问题,h5是正常的。
我暂也不清楚啥问题,搜了很多渲染不同步的解决方案,用this.$set 或者 this.$forceUpdate,变化绑定的key,新增变量做v-if绑定等都没效果。
无奈暂用异步处理即定时器然后强制渲染解决这个问题,有没有大佬有更好的解决方案,烦请不吝赐教,感谢。

doSearch() {  
                let that = this;  

                that.cityValue = {};  

                setTimeout(function() {  
                    for (var index in citydata.cityRawValue) {  
                        var valid = false;  
                        var _arr = [];  
                        for (var _index in citydata.cityRawValue[index]) {  
                            if (citydata.cityRawValue[index][_index].indexOf(that.searchTxt) != -1) {  
                                valid = true;  
                                _arr.push(citydata.cityRawValue[index][_index]);  
                            }  
                        }  

                        if (valid) {  
                            that.cityValue[index] = _arr;  
                        }  
                    }  

                    that.$forceUpdate();  
                }, 0)  

                console.log(Object.keys(that.cityValue));  

            },

要回复问题请先登录注册