Vue动态添加属性
饭啊饭° 人气:0一、场景例子
<body> <div id="app"> <p v-for="(value,key) in item" :key="key"> {{value}} </p> <button @click="addProperty">动态添加新属性</button> </div> </body> </html> <script> new Vue({ el:'#app', data:{ item:{ oldProperty:"旧属性" } }, methods: { addProperty(){ this.item.newProperty = "新属性"; console.log(this.item); } }, }) </script>
效果:点击按钮后,输出的结果中有新添加的新属性,但是页面没有显示新属性。
二、原理分析
vue2使用Object.defineProperty实现数据响应式;
const obj = {} Object.defineProperty(obj, 'foo', { get() { console.log(`get foo:${val}`); return val }, set(newVal) { if (newVal !== val) { console.log(`set foo:${newVal}`); val = newVal } } }) }
- 当访问foo属性,或者设置foo值的时候都能触发setter与getter;
- 但是为obj添加新属性的时候,却无法触发事件属性的拦截
bj.bar = '新属性'
原因是一开始obj的foo属性被设成了响应式数据,而bar是后面新增的属性,并没有通过Object.defineProperty设置成响应式数据
三、解决方案
有三种解决方案:
- Vue.set()
- Object.assign()
- $forcecUpdated()
常用的就是Vue.set(),语法为:Vue.set( target, propertyName/index, value )
<script> new Vue({ el:'#app', data:{ item:{ oldProperty:"旧属性" } }, methods: { addProperty(){ Vue.set(this.item,"newProperty","新属性") console.log(this.item); } }, }) </script>
加载全部内容