你能强制Vue.js重新加载/重新渲染吗?

时间:2015-08-19 21:43:52

标签: javascript vue.js

只是一个简单的问题。

你能强迫Vue.js重新加载/重新计算一切吗?如果是这样,怎么样?

19 个答案:

答案 0 :(得分:160)

尝试这个魔法咒语:

vm.$forceUpdate();

无需创建任何悬挂变量:)

更新:当我刚开始使用VueJS时,我找到了这个解决方案。然而,进一步的探索证明这种方法是一种拐杖。据我所知,有一段时间我摆脱它只是将所有无法自动刷新的属性(大多数是嵌套的)放入计算属性中。

此处有更多信息:https://vuejs.org/v2/guide/computed.html

答案 1 :(得分:46)

这似乎是来自matthiasgthis issue的一个非常干净的解决方案:

  

您还可以使用:key="someVariableUnderYourControl"并在需要完全重建组件时更改密钥

对于我的用例,我将Vuex吸气剂作为支柱喂入组件。不知何故,Vuex会获取数据,但反应性不会可靠地启动以重新渲染组件。在我的例子中,将组件key设置为prop上的某个属性可确保在getter(和属性)最终解析时刷新。

答案 2 :(得分:22)

为什么?

... 需要 强制更新?

也许你没有最好地探索Vue:

  

要让Vue 自动 对值更改做出反应,对象必须<{>>最初在data 中声明。或者,如果没有,则必须使用Vue.set() 添加它们。

请参阅下面演示中的评论。或者打开same demo in a JSFiddle here

new Vue({
  el: '#app',
  data: {
    person: {
      name: 'Edson'
    }
  },
  methods: {
    changeName() {
      // because name is declared in data, whenever it
      // changes, Vue automatically updates
      this.person.name = 'Arantes';
    },
    changeNickname() {
      // because nickname is NOT declared in data, when it
      // changes, Vue will NOT automatically update
      this.person.nickname = 'Pele';
      // although if anything else updates, this change will be seen
    },
    changeNicknameProperly() {
      // when some property is NOT INITIALLY declared in data, the correct way
      // to add it is using Vue.set or this.$set
      Vue.set(this.person, 'address', '123th avenue.');
      
      // subsequent changes can be done directly now and it will auto update
      this.person.address = '345th avenue.';
    }
  }
})
/* CSS just for the demo, it is not necessary at all! */
span:nth-of-type(1),button:nth-of-type(1) { color: blue; }
span:nth-of-type(2),button:nth-of-type(2) { color: red; }
span:nth-of-type(3),button:nth-of-type(3) { color: green; }
span { font-family: monospace }
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <span>person.name: {{ person.name }}</span><br>
  <span>person.nickname: {{ person.nickname }}</span><br>
  <span>person.address: {{ person.address }}</span><br>
  <br>
  <button @click="changeName">this.person.name = 'Arantes'; (will auto update because `name` was in `data`)</button><br>
  <button @click="changeNickname">this.person.nickname = 'Pele'; (will NOT auto update because `nickname` was not in `data`)</button><br>
  <button @click="changeNicknameProperly">Vue.set(this.person, 'address', '99th st.'); (WILL auto update even though `address` was not in `data`)</button>
  <br>
  <br>
  For more info, read the comments in the code. Or check the docs on <b>Reactivity</b> (link below).
</div>

要掌握Vue的这一部分,请检查Official Docs on Reactivity - Change Detection Caveats。这是必读的!

答案 3 :(得分:21)

使用vm.$set('varName', value)。在Change_Detection_Caveats中查找详细信息。

答案 4 :(得分:12)

当然。您可以随时使用key属性强制重新渲染(创建)。

<mycomponent :key="somevalueunderyourcontrol"></mycomponent>

有关示例,请参见https://jsfiddle.net/mgoetzke/epqy1xgf/

这里也进行了讨论:https://github.com/vuejs/Discussion/issues/356#issuecomment-336060875

答案 5 :(得分:11)

尝试使用this.$router.go(0);手动重新加载当前页面。

答案 6 :(得分:7)

请阅读此 http://michaelnthiessen.com/force-re-render/

可怕的方式:重新加载整个页面
糟糕的方法:使用v-if hack
更好的方法:使用Vue内置的forceUpdate方法
最好的方法:更改组件上的键

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

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

在某些情况下,我还使用watch:。

答案 7 :(得分:7)

<my-component :key="uniqueKey" />

连同它一起使用this.$set(obj,'obj_key',value) 并针对对象(obj)值中的每个更新更新uniqueKey 每次更新this.uniqueKey++

以这种方式为我工作

答案 8 :(得分:6)

所以有两种方法可以做到这一点,

1)。您可以在方法处理程序中使用$forceUpdate(),即

<your-component @click="reRender()"></your-component>

<script>
export default {
   methods: {
     reRender(){
        this.$forceUpdate()
     }
   }
}
</script>

2)。您可以为组件提供:key属性,并在需要重新渲染时保持淡淡状态

<your-component :key="index" @click="reRender()"></your-component>

<script>
export default {
   data() {
     return {
        index: 1
     }
   },
   methods: {
     reRender(){
        this.index++
     }
   }
}
</script>

答案 9 :(得分:4)

使用v-if指令

<div v-if="trulyvalue">
    <component-here />
 </div>

因此,简单地将reallyvalue的值从false更改为true将导致div之间的组件再次重​​新呈现

答案 10 :(得分:2)

我发现了一种方法。它有点hacky但有效。

vm.$set("x",0);
vm.$delete("x");

vm是您的视图模型对象,x是不存在的变量。

Vue.js会在控制台日志中抱怨这一点,但它会触发所有数据的刷新。测试版本1.0.26。

答案 11 :(得分:2)

只需添加以下代码:

this.$forceUpdate()

好运

答案 12 :(得分:2)

为了重新加载/重新渲染/刷新组件,请停止长编码。有一种Vue.JS方式。

只需使用:key属性。

例如:

<my-component :key="unique" />

我正在BS Vue表插槽中使用那个。告诉我我将为此组件做些事情,因此使其独特。

答案 13 :(得分:2)

这对我有用。

created() {
            EventBus.$on('refresh-stores-list', () => {
                this.$forceUpdate();
            });
        },

其他组件触发refresh-stores-list事件将导致当前组件重新呈现

答案 14 :(得分:0)

由于要在其他标签上进行更改,我想重新呈现图像库的问题。所以tab1 = imageGallery,tab2 = favoriteImages

tab @ change =“ updateGallery()”->这会强制我的v-for指令在每次切换标签时都处理filteredImages函数。

<script>
export default {
  data() {
    return {
      currentTab: 0,
      tab: null,
      colorFilter: "",
      colors: ["None", "Beige", "Black"], 
      items: ["Image Gallery", "Favorite Images"]
    };
  },
  methods: {
    filteredImages: function() {
      return this.$store.getters.getImageDatabase.filter(img => {
        if (img.color.match(this.colorFilter)) return true;
      });
    },
    updateGallery: async function() {
      // instance is responsive to changes
      // change is made and forces filteredImages to do its thing
      // async await forces the browser to slow down and allows changes to take effect
      await this.$nextTick(function() {
        this.colorFilter = "Black";
      });

      await this.$nextTick(function() {
        // Doesnt hurt to zero out filters on change
        this.colorFilter = "";
      });
    }
  }
};
</script>

答案 15 :(得分:0)

为我工作

ArrayList<ObjectVO> ObjectList = getObjectList();
for(ObjectVO myVO : ObjectList) {
  Iterator<ObjectVO> iter = ObjectList.iterator();

  while(iter.hasNext()) {
     ObjectVO checkVO = iter.next();
     if(myVO.getID().equals(checkVO.getID()) {
         //they are the same object ID.  Check the version number, remove it lower
         if(myVO.getVersion() > checkVO.getVersion()) {
              iter.remove();
         }
      }
   }
 }

答案 16 :(得分:0)

:key =“ $ route.params.param1”只需将key与它的任何参数一起使用,即可自动重新加载子项。

答案 17 :(得分:0)

抱歉,除了页面重新加载方法(闪烁)外,它们都不适合我(:key不起作用)。

我从老的vue.js论坛中找到了这个方法,对我来说很有效

https://github.com/vuejs/Discussion/issues/356

<template>
    <div v-if="show">
       <button @click="rerender">re-render</button>
    </div>
</template>
<script>
    export default {
        data(){
            return {show:true}
        },
        methods:{
            rerender(){
                this.show = false
                this.$nextTick(() => {
                    this.show = true
                    console.log('re-render start')
                    this.$nextTick(() => {
                        console.log('re-render end')
                    })
                })
            }
        }
    }
</script>

答案 18 :(得分:0)

:key添加到vue-router库的router-view组件的方法引起了我的注意,所以我去了vue-router的“组件内防护”来拦截更新并相应地刷新整个页面当同一条路径上的路径有更新时(例如$ router.go,$ router.push,$ router.replace没有任何帮助)。唯一需要注意的是,我们将通过刷新页面来打破单页应用程序的行为。

  beforeRouteUpdate(to, from, next) {
    if (to.path !== from.path) {
      window.location = to.path;
    }
  },