tip:实例创建之后添加新的属性到实例上,不会触发视图更新
分解tip:new Vue() 生命周期created() 之后 在data内添加的属性,不会触发view层的更新
new Vue({{
el: '#app',
data: {
user: {
name: 'tom',
sex: 'male'
}
},
created() {
this.user.msg = 'reactivity' // 成功创建并在视图更新
},
mounted() {
this.user.data = 'reactivity' // 成功创建,但不更新视图
}
})
解决方法
1Vue API
vm.$set(obj, key, value)
2Object.assign()
Object.assign({}, this.user, {key: value})
new Vue({{
el: '#app',
data: {
user: {
name: 'tom',
sex: 'male'
}
},
created() {
this.user.msg = 'reactivity' // 成功创建并在视图更新
},
mounted() {
this.$set(this.user, 'data', 'reactivity') // Vue API
Object.assign({}, this.user, {'data', 'reactivity'}) // Object.assign
}
})
异步数据操作
异步获取数据后更新视图:
new Vue({{
el: '#app',
data: {
user: {
name: 'tom',
sex: 'male'
}
},
created() {
setTimeout(() => {
// this.user.msg = 'reactivity' // 不更新视图
this.$set(this.user, 'data', 'reactivity') // Vue API
Object.assign({}, this.user, {'data', 'reactivity'}) // Object.assign
}, 1000) // 模拟异步数据
},
mounted() {
}
})
原理:异步数据操作的栈队列在整个vue生命周期最后
异步更新队列
this.$nextTick() 下一次栈队列执行完毕之后
异步数据更新后,操作对应的dom更新
new Vue({{
el: '#app',
data: {
user: {
name: 'tom',
sex: 'male'
}
},
created() {
setTimeout(() => {
this.user = {'age': 18}
this.$nextTick(() => {
// 数据刷新后对应的dom更新完毕
})
}, 1000) // 模拟异步数据
},
mounted() {
}
})
MutationObserver
vue2.0使用MutationObserver API作为异步更新队列的DOM更新解决方案
MutationObserver属于microtasks,执行效率更高,优先于macrotasks - setTimeout执行
// Firefox和Chrome早期版本中带有前缀
const MutationObserver = window.MutationObserver
|| window.WebKitMutationObserver || window.MozMutationObserver
// 创建观察者对象
const observer = new MutationObserver(mutations=>{
mutations.forEach(function(mutation) {
console.log(mutation.type);
})
})
// 配置观察选项:
const config = {
attributes: true,
childList: true,
characterData: true
}
// 选择目标节点
const target = document.querySelector('#test');
// 传入目标节点和观察选项
observer.observe(target, config);
target.appendChild(document.createElement("div"))
/*
* mutationObserver优先于setTimeout
*/
setTimeout(console.log,0,'setTimeout')
console.log('appending')
target.setAttribute('class','hello') //添加了一个元素子节点,触发回调函数.
// 随后,你还可以停止观察
// observer.disconnect();
/*
* doc https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
*/
执行结果
/*
appending
childList
attributes
setTimeout
*/