html代码如下:
<div class="db_api_tr">
<span class="db_api_span">数据表</span>
<el-select style="padding:10px 8px;" v-model="form.public_data.field_bind[scope.row].version.table" placeholder="请选择数据表" @change="field_table_change(scope.row)">
<el-option v-for="(v,k) in db_api_data.table_datas" :label="v" :value="v" >
</el-option>
</el-select>
</div>
<div class="db_api_tr">
<span class="db_api_span">字段</span>
<el-select style="padding:10px 8px;" v-model="form.public_data.field_bind[scope.row].version.field" placeholder="请选择字段" >
<el-option v-for="(v,k) in db_api_data.table_fields[form.public_data.field_bind[scope.row].version.table].data" :label="v.Field" :value="v.Field">
</el-option>
</el-select>
</div>
界面上看是这样的。
第一个select是数据表,然后切换数据表,下面的数据表字段随之更新。
所以,第二个select的数据来源于第一个的切换的数据变化。
切换的函数如下:
field_table_change:function (a) {
this.$set(this.db_api_data.table_fields.reply, 'data', [{Field:'哈哈'}]);
}
本来这里是异步请求的,现在我把问题简化了。所以,现在问题就是明明数据源更新了,但是dom没更新。
如果我反复切换第一个select,就可以了。我不明白这是为什么。
我在watch监听数据的变化
db_api_data: function (newVal, oldVal) {
console.log('更新了。。。。。。。。');
console.log(newVal);
console.log(oldVal);
},
但切换select的时候,这里没有触发过。
-----------补充--------------
这几天制作了一个demo。地址:https://git.oschina.net/milu/...
bug重新方式:
我在vue的文档里面看到:
由于 Vue 不允许动态添加根级响应式属性,所以你必须在初始化实例前声明根级响应式属性,哪怕只是一个空值:
这意味着,如果一个属性,如果你不实现声明,后面再增加,他不能检测到变化。
对于一些固定的结构,这是可以做到的。比如我知道一个obj里面必然有key1、key2属性,我可以事先初始化。如果这些东西是动态的,我没法事先声明。后面再增加,vue没法检测到变化了。
为了证实这个猜想,我把本例的数据结构,全部初始化。就可以了。
但是实际生产环境,因为有些数据结构的key都是未知的,所以不能这样做。
-----------------------补充-----------------------------
历经2天,终于自己解决了。
解决的办法。
比如,你自己数据定义了
{
db_api_data:{}
}
数据更新那就必须这样设置
mainVue.$set(vm, 'db_api_data', {table_fields:{reply:{data:[{Field:'134353453'}]}}} )
如果这样,就不行。
mainVue.$set(vm.db_api_data, 'table_fields', {reply:{data:[{Field:'abcdef'}]}} )
首先,watch 没有触发的原因是少了 deep 属性的设置
其次,field_table_change 是在第一个 select 发生改变之后才会触发的,因此不改变第一个列表就不会执行 $set 语句,因此第二个列表是没有数据的。
可以考虑改为对 table 字段设置一个 immediate 的 watch。