elementUI下拉单选框出现双重选中bug解决方案

问题重现

这个bug是我在工作的时候处理过的一个问题,今天特地将bug问题剥离出来记录一下以作备忘。话不多说,直接上图:


bug示例

问题排查

当时我看到之后第一反应以为下拉框启用了多选,去检查了一下后发现

el-select(v-model="options.selected.value")
    el-option(v-for="item, index in options.list" 
              :key="index" 
              :label='item.name' 
              :value='item.value')

没开multiple啊



然后去检查了下逻辑代码,发现这个下拉选单的内容是在初始化时动态加载的,获取到内容后先赋值给下拉选单的列表,然后取列表第一个内容当作默认选中值。

加载代码段

...
mounted() {
    this.getSelectList().then(resp => {
        this.options.list = resp.data
        this.options.selected = resp.data[0]
    })
}
...

data代码段

data: () => ({
    options: {
        selected: {},
        list: []
    }
}),

这里我们用promise模拟一个数据请求

getSelectList() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const resp = {
                data: [
                    { value: 1, name: '选项1' },
                    { value: 2, name: '选项2' },
                    { value: 3, name: '选项3' },
                    { value: 4, name: '选项4' }
                ]
            }
            resolve(resp)
        }, 1000)
    })
}

检查了一下发现好像并没有什么不对,随后一起检查这个bug的同事把请求的内容直接放在本地data里测试了一下,bug消失了。那问题肯定就出现在在加载列表内容的那两行代码里。其实现在已经很明显了,我们直接祭出杀器Vue Devtools检查一下运行时的状态再确认一下。

Vue Devtools

当我们点击选项3的时候,发现不止是selected的值被改变了,list[0]值也被修改了!水落石出,这是一个由数据浅拷贝引发的bug。
由于selected在赋值时只是进行了浅拷贝,所以selected其实是list[0]的一个引用,所以list[0]的值也会被el-select修改成被选中的值,页面在渲染时发现list[0]的key和被选中的key相同,自然就显示成选中状态了。

问题解决

只需要把浅拷贝换成深拷贝即可,这里我们直接用JSON.parse()JSON.stringify()深拷贝一下,这样selected和list[0]就不会相互干扰了。

mounted() {
    this.getSelectList().then(resp => {
        this.options.list = resp.data
        this.options.selected = JSON.parse(JSON.stringify(resp.data[0]))
    })
}

问题总结

  • 在发现出现数据污染的情况,特别是数据里包含数组或对象(这个基本避免不了),或者从数组里取值赋给某个值的时候,要优先考虑深浅拷贝的问题。
  • Vue Devtools真好用。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,973评论 4 60
  • 你所想要的,只要我有便都会给你。所以……请帮帮我。 by 徐明的日记 跟着苏默通过曲折漫长的林...
    零露漙兮久阅读 260评论 0 1
  • 本篇主要介绍cuda的安装以及kaldi下的配置 cuda官网下载对应版本 https://developer.n...
    泉泉酱阅读 5,120评论 0 0
  • · 1 生活本该充满诗意 为何我们选择失忆再难寻觅你的痕迹 梦醒只能把你回忆再也没有你的消息 再也没有甜言蜜语回想...
    玩词原创阅读 486评论 0 1
  • 目录 铨斋志怪(十一)电梯惊魂 大宝,冀北某县之子。自幼受宠于隔辈,未尝或缺。十八入省学,尚惧独处,同窗皆讪。 逢...
    铨斋阅读 374评论 4 16