方法1 splice()
1 .增删改查都能实现
2 .实现原理
const methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
methodsToPatch.forEach(function (method) {
// cache original method
const original = arrayProto[method]
def(arrayMethods, method, function mutator (...args) {
const result = original.apply(this, args)
const ob = this.__ob__
let inserted
switch (method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
if (inserted) ob.observeArray(inserted)
ob.dep.notify()
return result
})
})
1 .对这些方法包装,新增的数据,而且会把新加入的值变成响应式对象
2 .手动调用依赖触发通知.
3 .既然这里已经知道了触发的是什么操作,为啥还需要都diff操作呢??
方法2 Vue.set==this.$set
1 .用来主动触发一个响应
this.data[1]='hello'
//不会生效
this.$set(this.data,1,'hello')
Vue.set(this.data,1,'hello')
//会生效
2 .数组的时候,其实是在底层调用了splice方法
if (Array.isArray(target) && isValidArrayIndex(key)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
3 .对象的时候
如果之前有这个值的时候,换了值直接返回
if (key in target && !(key in Object.prototype)) {
target[key] = val
return val
}
//如果没有的话
//看属性是不是添加在了根级,加在根级就报错,__ob__指的是Observer对象。vmCount用来表示当前对象是否是根级属性。_isVue用来表示是否是Vue实例。上面说过target不能是根级属性或者Vue实例
if (!ob) {
target[key] = val
return val
}
defineReactive(ob.value, key, val)
ob.dep.notify()
return val
//绑定数据,然后触发检测
2.0 和3.0 nwe 出来的东西还不一样啊
image.png
//可以看到,在根部添加一个新的key值,虽然没有报错,但是实际没有绑定到,也就是说如果要用到,还是提前定义吧.不然别人也不知道有这个变量
为什么会有Vue.set这个操作呢?
image.png1 .每次修改都是全量的吧,深层嵌套的怎么改,每次只想改一个key,现在是必须全部替换.难道一定要拆分组件么?
Vue.set(app,"love",{home:{'age':"lala",work:"123"}})
//比如这个新增一个属性的时候,还要必须先把原来的属性加上么.这样写很累的吧
var vm=new Vue({
el:'#test',
data:{
//data中已经存在info根属性
info:{
name:'小明';
}
}
});
//给info添加一个性别属性
Vue.set(vm.info,'sex','男');
//似乎不是
2 .向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property比如this.myObject.newProperty='hi'
3 .注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。
4 .Vue.set新增的变量,Vue tools能否看到,这个是属于data里面的吧
5 .为啥会有动态添加新属性的需求呢?不都是初始化的时候写在里面么?
1 .数据是一个对象,但是这个对象的值是不确定的,或者需要及时生成的
2 .从这里看他确实和react完全不同,react可以是直接setDate一个新对象进去,他这里是无法直接替换新对象??
6 .Vue.set是定义在构造函数上的,this.$set定义在原型对象上
7 .受 ES5 的限制,Vue.js 不能检测到对象属性的添加或删除。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以 属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的
vm.$forceUpdate
1 .强制使Vue实例渲染,其实this.list[1]="xxx"这种操作已经修改了数据,但是这种修改没有触发到对应更新的钩子函数,所以使用这个函数可以强制使页面刷新
2 .尽量避免使用这个函数,如果你使用这个,多半是使用不正确
3 .
网友评论