前言
写这篇文章主要是遇到了一个bug,与$set有些关系。
说一下这个bug
商品编号是一个输入商品编号的输入框,保存是一个保存按钮。问题是这样的:
1、当商品编号为空时,点击保存按钮,然后会进行校验,在商品编号输入框下面提示商品编号不能为空
2、在输入框下面有提示的前提下,获取商品编号后,仍提醒商品编号不能为空
涉及的代码
getShopID() {
this.form.id = this.transferRow.id //当获取到id值后进行赋值
}
解决
getShopID() {
this.$set(this.form,'id',this.transferRow.id)
}
为什么这么改呢,最初我也不知道,当看完$set的使用时就明白了
$set的基本使用
使用场景
在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。
根据官方文档定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
看到这是不是有些想法了。是的,出现bug是因为data对象中并没有this.form.id
这个属性,虽然给他赋值了(对象对没有的属性会添加进对象中,但是并没有添加getter/setter这个步骤),但是这个新属性不是响应式的,不能够触发视图更新
所以可以通过$set的方式解决这个问题。当然出现bug是因为没有这个属性,也可以在data中添加这个属性
$set的使用方式
对象
this.$set(Object, key, value)
实例
<div id="app">
姓名:{{ name }}<br>
年龄:{{age}}<br>
性别:{{sex}}<br>
说明:{{info.content}}
</div>
<script>
var data = {
name: "张三",
age: '3',
info: {
content: 'my name is test'
}
}
var key = 'content';
var vm = new Vue({
el: '#app',
data: data,
ready: function() {
//Vue.set(data,'sex', '男')
//this.$set('info.'+key, 'what is this?');
}
});
data.sex = '男';
</script>
数组:
this.$set(Array, index, newValue)
实例
<div id="app">
<button type="button" @click="change">修改</button>
<ul>
<li v-for="item in num" :key="item">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
num: [0, 1, 2, 3]
},
methods: {
change() {
//Vue.set(this.num,'4',0) //可以
//this.$set(this.num,'4',0) //可以
//this.num[4]=0 //无反应
}
}
})
</script>