el-select中多选回显数据后没法重新选择和更改

本文介绍了解决Vue项目中使用el-select组件多选时遇到的问题,包括无法清除选择项、无法编辑数据及验证规则失效等。通过添加$forceUpdate()方法解决了部分问题,但也引发了新的验证规则失效问题,并深入探讨了数据结构与Vue观察机制的关系。
摘要由CSDN通过智能技术生成

我用element select 多选回显的时候 回显正常, 不能点击清除,不能选择改变数据, 然后去搜了这篇文章文章链接

博主解释要在select标签上加一个强制渲染 ,如下图

<el-select v-model="list" filterable multiple  @change="$forceUpdate()"></el-select>

在编辑数据时,使用v-model绑定 el-select多选,但无法进行编辑、删除,这是因为由于一些嵌套特别深的数据,导致数据更新了,但是页面却没有重新渲染

需要使用this.$forceUpdate()迫使 Vue 实例重新渲染。

在el-select 中使用@change="$forceUpdate()",标签里加个@change=“$forceUpdate()” 就好了

但是,重点来了

加了之后 , 功能其他的一切都正常

表单里这个el-select的rules校验规则就不生效了…

仔细查看数据结构后发现数据有问题

错误数据(rules校验失效)
在这里插入图片描述
正确数据(一切正常)在这里插入图片描述
前者和后者同样是数组, __proto__原型却不相同,需要我去深究一下

答案来了

__ob __会指向一个Observer对象,每个被双向绑定的对象元素(数组也是对象)都会有一个__ob __ ,而且是单例的

function observe (value, asRootData) {    
    if (!isObject(value) || value instanceof VNode) {    //必须是对象才能有__ob__ 属性
      return
    }
    var ob;
    if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {    //__ob__ 只能有一个
      ob = value.__ob__;
    } else if (
      shouldObserve &&                           //暂时没看懂    
      !isServerRendering() &&
      (Array.isArray(value) || isPlainObject(value)) &&
      Object.isExtensible(value) &&
      !value._isVue
    ) {
      ob = new Observer(value);
    }

    return ob
  }

Observe 对象里面有什么

data{
   obj:{
       a:1
   }
},

export class Observer {
  value: any;   //指的是双向绑定的那个对象,如上述例子 value 就指向 obj
  dep: Dep;   //  存的是当前对象双向绑定的的dep。  obj 里面会有一个__ob__,这个__ob__.dep 和 obj 的 dep 存放的东西是一样的
              //  或者说 __ob__.dep  和  obj  依赖收集的那个 dep 里面放的东西是一样的。                                                                                                                        
  vmCount: number; // number of vms that have this object as root $data
  constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    this.vmCount = 0
  }
}

何时会往这个 __ob __ 添加 内容

function defineReactive ( obj,  key, val, customSetter, shallow ) {
    var dep = new Dep();

    var childOb = !shallow && observe(val);
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get: function reactiveGetter () {
        var value = getter ? getter.call(obj) : val;
        if (Dep.target) {
          dep.depend();
          if (childOb) {
            childOb.dep.depend();
            if (Array.isArray(value)) {
              dependArray(value);
            }
          }
        }
        return value
      },
    });
  }


data{
   obj:{
       a:1
   }
},

如果 双向绑定的这个obj 是个对象,那么 var childOb 会是一个Observe 对象,否则是一个null。例如当为obj双向绑定的时候,会调用 obj.__ob __.dep.depend() 添加一个 同样的watcher。

后来我发现 vm.$delete 也会使用到最后__ob __

export function del (target: Array<any> | Object, key: any) {

 ......

  const ob = (target: any).__ob__

  ......

  delete target[key]   

 ......

  ob.dep.notify()   // ⑥
}

附原文链接

2021-9-24备注:其实数据的不一致区别在于这个对象是否被vue所观察 , 比如说一个对象被观察后绑定到dom上 , 数据变化后dom随之改变的道理是一样的 . 尽可能的用Object.asign()去重新赋值一下会比较好

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李泽举

如对你有帮助,那我就没白写

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值