我用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()去重新赋值一下会比较好