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

Dav*_*ave 178 javascript vue.js

只是一个简单的问题.

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

Bor*_*nov 192

试试这个魔法咒语:

vm.$forceUpdate();
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 请注意,在vue文件中,您需要'this.$ forceUpdate();' (12认同)
  • 当我在Vue中使用表单向导组件时,这确实帮助了我.尽管数据变量完好无损,但我的表单字段字段仍处于松散状态.我现在用这个来刷新视图,我不得不把它放在setTimeout函数中. (3认同)
  • 以某种绝对古怪的方式,$ forceUpdate()在2.5.17上从未对我有用。 (3认同)
  • @AbanaClara $forceUpdate() 从来都不是公共方法,我发现它在挖掘 Vue 的源代码。而且由于它的用法从来都不是 Vue'ing 的正确方式,也许它可以被删除。不能确定它是否还在那里,因为我不再做前端了。 (3认同)
  • 这对于在长时间的 axios 调用后更新 a 非常有用。 (2认同)

Bri*_*ung 66

对于这个问题,这似乎是matthiasg的一个非常干净的解决方案:

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

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

  • 这是一个巧妙的小技巧,它基本上强制重新实例化组件(“mounted”将运行,等等) (4认同)
  • 这很有帮助。我使用路由完整路径作为键来在路由改变时重新渲染相同的组件。:key="$route.fullPath" (2认同)

acd*_*ior 31

为什么?

...你需要强制更新吗?

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

要让Vue 自动对值更改做出反应,必须首先声明data对象.或者,如果没有,则必须使用Vue.set()它们添加.

请参阅下面演示中的注释.或打开在同一个演示的jsfiddle这里.

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.';
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
/* 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 }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

要掌握Vue的这一部分,请查看关于反应性官方文档- 更改检测警告.这是必读的!

  • 绝对同意您应该质疑这一刷新要求,但有时您只需要重新渲染 UI,因为视口已更改并且您需要显示不同的资产(作为一个示例)。数据实际上可能没有改变。 (2认同)
  • @the_dude_abides 和@Auroprata,我同意这些是令人耳目一新的合法用途。我提出的问题是,人们并非很少出于错误的原因进行提神。 (2认同)

den*_*lin 22

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

  • “找不到网页” (2认同)

Yas*_*ash 17

请阅读此 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>
Run Code Online (Sandbox Code Playgroud)

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


Poy*_*ang 14

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

  • 更简单: this.$router.go() (10认同)
  • 实际上@MariusAndreiana - .go() 函数需要 1 个非可选参数 (2认同)

Pus*_*kar 14

<my-component :key="uniqueKey" />
Run Code Online (Sandbox Code Playgroud)

随着它使用this.$set(obj,'obj_key',value) 和更新uniqueKey每次更新的对象(obj)值中的每个更新this.uniqueKey++

它以这种方式对我有用


mgo*_*zke 13

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

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

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

它也在这里讨论:https://github.com/vuejs/Discussion/issues/356#issuecomment-336060875


Sha*_*war 11

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

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

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

<script>
export default {
   methods: {
     reRender(){
        this.$forceUpdate()
     }
   }
}
</script>
Run Code Online (Sandbox Code Playgroud)
  1. 你可以给:key你的组件一个属性,并在想要重新渲染时增加

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

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


小智 7

2021 年 12 月更新:

您可以通过添加:key="$route.fullPath"来强制重新加载组件。

对于组件:

<Child :key="$route.fullPath" />
Run Code Online (Sandbox Code Playgroud)

对于路由器视图标签:

<router-view :key="$route.fullPath" />
Run Code Online (Sandbox Code Playgroud)

但是:key="$route.fullPath"只能强制重载不同路由的组件,不能强制重载同一路由的组件。为了能够强制重新加载同一路由的组件,我们需要将带有数组的“value”添加到:key="$route.fullPath"更改“value”。所以它变成:key="[$route.fullPath, value]"我们需要更改 "value"

*我们可以将数组分配给:key=

<template>
  <Child 
    :key="[$route.fullPath, value]" // Can assign "Array" to ":key="
    @childReload="reload" // Call @click="$emit('childReload')" in   
  />                      // Child Component to increment the value.
</template> 

    OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR

<template>
  <router-view 
    :key="[$route.fullPath, value]" // Can assign "Array" to ":key="
    @routerViewReload="reload" // Call @click="$emit('routerViewReload')"
  />                           // in Child Component to increment the value.
</template>
    
<script>
export default {
  name: "Parent", components: { Child, },
  data() {
    return {
      value: 0,
    };
  },
  methods: {
    reload() {
      this.value++;
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

然而,继续使用 "$route.fullPath" 和 "value" 有时会导致一些错误,因此只有当发生像Click这样的事件时,我们才会同时使用"$route.fullPath""value"。除非发生像Click这样的事件,否则我们总是只需要使用"$route.fullPath"

这是最终的代码:

<template>
  <Child 
    :key="state ? $route.fullPath : [$route.fullPath, value]"
    @childReload="reload" // Call @click="$emit('childReload')" in
  />                      // Child Component to increment the value.
</template>
    
    OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR OR
    
<template>
  <router-view 
    :key="state ? $route.fullPath : [$route.fullPath, value]"
    @routerViewReload="reload" // Call @click="$emit('routerViewReload')" in
  />                           // Child Component to increment the value.
</template>
        
<script>
export default {
  name: "Parent", components: { Child, },
  data() {
    return {
      state: true,
      value: 0,
    };
  },
  methods: {
    reload() {
      this.state = false;
      this.value++;
      this.$nextTick(() => this.state = true);
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

不幸的是,在 Vue 中没有简单的方法可以正确地强制重新加载组件。这就是 Vue 目前的问题。


Fel*_*yen 6

为了重新加载/重新渲染/刷新组件,停止长编码。有一种 Vue.JS 方法可以做到这一点。

只需使用:key属性。

例如:

<my-component :key="unique" />
Run Code Online (Sandbox Code Playgroud)

我在 BS Vue Table Slot 中使用了那个。告诉我会为这个组件做一些事情,让它独一无二。


Geo*_*off 5

使用 v-if 指令

<div v-if="trulyvalue">
    <component-here />
 </div>
Run Code Online (Sandbox Code Playgroud)

因此,只需将 truevalue 的值从 false 更改为 true 就会导致 div 之间的组件再次重​​新渲染