Vue中 数据改变但未渲染的问题,页面中并没有自动更新,但是在控制台可以打印出来,常见解决方法

在Vue组件中,在mounted阶段调用了一个函数去请求异步数据,将返回结果赋给data里面的值却失败了,赋值完console.log()出来明明是有值的,但页面却没有更新过来。我还一直以为是nuxt生命周期的原因,但明显不是。因为这个问题只有在偶尔才会出现,并不是每次进入页面时渲染都会有这个问题。

1.简单粗暴的方式:重新加载整个页面(体验不友好,不推荐)

2.不妥的方式:使用 v-if

<template>
  <my-component v-if="showComponent" />
</template>
<script>
  export default {
    data() {
      return {
        showComponent: true,
      };
    },
    methods: {
      forceRerender() {
        // 从 DOM 中删除 my-component 组件
        this.showComponent = false;
        
        this.$nextTick(() => {
          // 在 DOM 中添加 my-component 组件
          this.showComponent = true;
        });
      }
    }
  };
</script>

3.较好的方法:使用Vue的内置forceUpdate方法

  • 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身插入插槽内容的子组件,而不是所有子组件。

// 全局
import Vue from 'vue';
Vue.forceUpdate();

// 使用组件实例
export default {
  methods: {
    methodThatForcesUpdate() {
      // ...
      this.$forceUpdate();
      // ...
    }
  }
}

4.最好的方法:在组件上进行 key 更改

<template>
  <component-render :key="componentKey" />
</template>


export default {
  data() {
    return {
      componentKey: 0,
    };
  },
  methods: {
    forceRerender() {
      this.componentKey += 1;  
    }
  }
}

5.使用Object.assign()

MDN:Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象

方法:

  • 克隆对象,Object.assign({}, target)

  • 克隆数组,Object.assign([], target)
    针对上例,修改add方法。

this.queryParam = Object.assign({}, this.queryParam);
6.使用Vue.set( target , key , value)

方法:

target: 要更改的数据源(可以是一个对象或者数组)
key 要更改的具体数据。如果是数组元素更改,key表示索引;如果是对象,key表示键值
value 重新赋的值
add() {
      this.$set(this.persons, 1, {key: 'newkey', name: '888'})
      console.log(this.persons)
    }
7. ... 展开语法
  • 对象数据obj,使用obj = {...obj}

  • 对于数组arr,使用arr = [...arr]

add() {
      this.persons[1] = {key: 'newkey', name: '888'}
      this.persons = [...this.persons]
      console.log(this.persons)
    }