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

只是一个简单的问题。

你能强制Vue.js重新加载/重新计算所有东西吗?如果有,怎么做?

591373 次浏览

使用vm.$set('varName', value)

Change_Detection_Caveats中寻找细节

我找到了一个办法。这有点俗气,但很管用。

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

其中vm是你的视图模型对象,x是一个不存在的变量。

Vue.js会在控制台日志中抱怨这个问题,但它确实会触发所有数据的刷新。使用版本1.0.26进行测试。

试试这个神奇的咒语:

vm.$forceUpdate();
//or in file components
this.$forceUpdate();

不需要创建任何悬挂变量:)

更新:我发现这个解决方案时,我只开始与VueJS工作。然而,进一步的探索证明这种方法是一种拐杖。据我回忆,在一段时间内,我摆脱了它,只是把所有不能自动刷新的属性(大部分是嵌套的)放入计算属性中。

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

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

你也可以使用:key="someVariableUnderYourControl"并在你想要完全重建组件时更改键值

对于我的用例,我将Vuex getter作为道具提供给组件。Vuex会以某种方式获取数据,但反应性不会可靠地重新呈现组件。在我的例子中,将组件key设置为道具上的某个属性可以确保在getter(和属性)最终解析时刷新。

使用v-if指令

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

因此,简单地将truyvalue的值从false更改为true将导致div之间的组件重新渲染

为什么?

...你是否<强> < /需要强大的>强制更新?

也许你没有在最好的状态下探索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.';
}
}
})
/* 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的这一部分,请检查关于<强>反应 -变化检测警告的官方文档. exe。这是一本必读的书!

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

确定. .可以简单地使用key属性在任何时候强制重新呈现(重新创建)。

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

参见https://jsfiddle.net/mgoetzke/epqy1xgf/的例子

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

请读这个 http://michaelnthiessen.com/force-re-render/ < / p >

可怕的方式:重新加载整个页面
可怕的方式: 使用v-if hack
更好的方法:使用Vue内置的 forceUpdate方法
最好的方法:key-changing on your 组件< /强> < br > < / p >

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


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

在某些情况下,我也用watch。

这对我来说很有效。

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

另一个组件触发refresh-stores-list事件将导致当前组件重新呈现

<router-view :key="$route.params.slug" />

只需使用你的任何参数的关键,它的自动重载子..

为我工作

    data () {
return {
userInfo: null,
offers: null
}
},


watch: {
'$route'() {
this.userInfo = null
this.offers = null
this.loadUserInfo()
this.getUserOffers()
}
}

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

只需使用:key属性。

例如:

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

我正在使用BS Vue表槽。我要为这个组件做一些事情,让它是唯一的。

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

连同它一起使用this.$set(obj,'obj_key',value) 并为object (obj)值的每次更新更新uniqueKey this.uniqueKey++

这对我来说很管用

有两种方法,

  1. 你可以在你的方法处理程序中使用$forceUpdate()

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

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

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

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

添加以下代码:

this.$forceUpdate()

除了页面重载方法(闪烁),没有一个适合我(:键没有工作)。

我发现这个方法从旧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>

:key添加到vue-router库的router-view组件的方法会引起我的fickers,所以我使用vue-router的“组件内保护”来拦截更新,并在同一路由上的路径更新时相应地刷新整个页面(如$router. xml)。美元,路由器。推,路由器。替换也无济于事)。唯一需要注意的是,通过刷新页面,我们暂时打破了单页应用行为。

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

2021年12月更新:

你可以通过添加:关键=“route.fullPath"美元;来强制加载组件。

对于孩子组件:

<Child :key="$route.fullPath" />

对于router-view标签:

<router-view :key="$route.fullPath" />

但是,:关键=“route.fullPath"美元;只能强制重载不同的路线的组件,而不能强制重载同样的路线的组件。为了能够强制重载同样的路线的组件,我们需要将“value"使用数组添加到:关键=“route.fullPath"美元;改变“value"中。所以它变成了:关键=“[$路线。fullPath、价值]“;,我们需要改变“value"

*我们可以将数组赋值给:关键=

<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>

然而,$route.fullPath"和“;value"有时会导致一些错误,所以只有当一些像点击这样的事件发生时,我们才同时使用“route.fullPath"美元;“value"。除非发生一些类似点击的事件,否则我们总是只需要使用“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>

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

对于那些还在四处寻找的人来说,现在有一个包。

https://github.com/gabrielmbmb/vuex-multi-tab-state

我所要做的就是安装它,并将它添加到我的插件中。ts(就像它在那个页面上显示的那样),它确实做了我想要的。

如果你的URL在加载组件时也发生了变化,你可以在:key属性中使用它。如果你直接在router-view标记上使用它,这工作得特别好。这与添加的键的benedit是一个实际绑定到页面内容的值,而不仅仅是一些随机数。

<router-view :key="this.$route.path"></router-view>

如果您正在使用路由器视图或Vue路由器,您可以直接使用关键功能

<router-view :key="$route.path"></router-view>

这将告诉路由器视图在每次路径改变时重新渲染页面。