vue 数据不更新的问题

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>

界面上看是这样的。

clipboard.png

第一个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重新方式:

clipboard.png

我在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'}]}} )
阅读 12.1k
1 个回答

首先,watch 没有触发的原因是少了 deep 属性的设置

其次,field_table_change 是在第一个 select 发生改变之后才会触发的,因此不改变第一个列表就不会执行 $set 语句,因此第二个列表是没有数据的。

可以考虑改为对 table 字段设置一个 immediate 的 watch。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏