Vue的this.$set()单页演示
源码位置: vue/src/core/observer/index.js/*** Set a property on an object. Adds the new property and* triggers change notification if the property doesn't* already exist.*/export function set (target: Arra
·
源码位置: vue/src/core/observer/index.js
/**
* Set a property on an object. Adds the new property and
* triggers change notification if the property doesn't
* already exist.
*/
export function set (target: Array<any> | Object, key: any, val: any): any {
/*如果传入数组则在指定位置插入val*/
if (Array.isArray(target) && typeof key === 'number') {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
/*因为数组不需要进行响应式处理,数组会修改七个Array原型上的方法来进行响应式处理*/
return val
}
/*如果是一个对象,并且已经存在了这个key则直接返回*/
if (hasOwn(target, key)) {
target[key] = val
return val
}
/*获得target的Oberver实例*/
const ob = (target : any).__ob__
/*
_isVue 一个防止vm实例自身被观察的标志位 ,_isVue为true则代表vm实例,也就是this
vmCount判断是否为根节点,存在则代表是data的根节点,Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(root-level reactive property)
*/
if (target._isVue || (ob && ob.vmCount)) {
/*
Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(root-level reactive property)。
https://cn.vuejs.org/v2/guide/reactivity.html#变化检测问题
*/
process.env.NODE_ENV !== 'production' && warn(
'Avoid adding reactive properties to a Vue instance or its root $data ' +
'at runtime - declare it upfront in the data option.'
)
return val
}
if (!ob) {
target[key] = val
return val
}
/*为对象defineProperty上在变化时通知的属性*/
defineReactive(ob.value, key, val)
ob.dep.notify()
return val
}
测试代码
<template>
<div id="app">
<p v-for="(item,index) in items" :key="index">{{item.name}},{{item.id}},{{item.add}}</p>
<button class="btn" @click="handClick()">更新数据</button>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
items: [
{ name: "111", id: "1" },
{ name: "222", id: "2" },
{ name: "333", id: "3" }
],
}
},
mounted () {
// this.$set(this.items,0,art) //$set 可以触发更新视图
},
methods: {
handClick(){
let change = this.items[0]
change.name="666"
this.$set(this.items,0,change) //$set(数组对象,被修改的对象索引值,修改内容)
this.$set(this.items,3,change) //$set(数组对象,被修改的对象索引值,修改内容)如果不存在则会添加,但是在对象数组级别操作只能紧跟最后一个索引,如本例索引0,1,2;则添加时只能填3
this.$set(this.items[0],'add','change') //$set(某一个对象,被修改对象中的key,修改key对应的值),如果在该对象中不存在该key,则将其连同值一起添加至该对象
this.$set(this.items[1],'id','99')
this.$set(this.items[2],'name','555')
}
}
}
</script>
<style>
</style>
结果
更新数据前
111,1,
222,2,
333,3,
更新数据后
666,1,change
222,99,
555,3,
666,1,change
更多推荐
已为社区贡献7条内容
所有评论(0)