Чи можете ви змусити Vue.js перезавантажувати / відновлювати?


231

Просто швидке запитання.

Чи можна змусити Vue.jsдо перевантажувальної / перераховувати всі? Якщо так, то як?



Чудово, не знав про те місце дискусії. Я спробую там.
Дейв

Ви в кінцевому підсумку отримали відповідь? Я теж хочу знати.
Оддман

Не пам’ятаю точно. Але ось питання, яке я відкрив із деякими підказками: github.com/vuejs/Discussion/isissue/356
Дейв

Я маю директиву v-for у представленні і маю випадок використання, коли я вручну поміняю два об’єкти на цьому масиві. Vue автоматично не рендерує шаблон після цього. Я використовував обхідне рішення: просто виконайте будь-які дії з цим масивом (натисніть порожній об'єкт, а потім зробіть сплайс) - це запускає рендерінг. Але це особливий випадок.
Федір Хрущов

Відповіді:


237

Спробуйте це магічне заклинання:

vm.$forceUpdate();

Не потрібно створювати жодних висячих вар :)

Оновлення: це рішення я знайшов, коли тільки почав працювати з VueJS. Однак подальші розвідки довели цей підхід як милицю. Наскільки я пам’ятаю, я через деякий час позбувся цього просто вклавши всі властивості, які не вдалося автоматично оновити (в основному вкладені), в обчислювані властивості.

Більше інформації тут: https://vuejs.org/v2/guide/computed.html


4
це мені справді допомогло, коли я використовував його з компонентом форми майстра у Vue. Поля моїх форм втрачали стан, хоча змінні даних були недоторканими. Тепер я використовую це для оновлення поглядів, коли я повертаюся назад, мені довелося розмістити його у функції setTimeout.
Джиммі Іленлоа

26
Зауважте, що у файлах vue вам потрібно «це. $ ForceUpdate (); '
Катінка

1
Це чудово підходить для оновлення після тривалого виклику axios.
АльфредБр

4
$forceUpdate()Якимось дивним чином ніколи не працював для мене 2.5.17.
Абана Клара

2
@AbanaClara $ forceUpdate () ніколи не був публічним методом, я виявив, що він викопує вихідний код Vue. А оскільки його використання ніколи не було правильним способом Vue'ing, можливо, його можна було б позбавити. Не можу сказати точно, якщо він все ще є, оскільки я більше не займаюся фронтом.
Борис Моссунов

82

Це здається досить чистим рішенням з матіаса з цього питання :

ви також можете використовувати :key="someVariableUnderYourControl"та змінювати ключ, коли ви хочете, щоб компонент був повністю відновлений

Для мого використання я підживлював геттер Vuex в складі в якості опори. Якось Vuex отримає дані, але реактивність не буде надійно реалізовувати компонент для відновлення. У моєму випадку встановлення компонента keyна якийсь атрибут на опорі гарантувало оновлення, коли getters (та атрибут) остаточно вирішили.


1
Це акуратний маленький трюк, він в основному змушує повторно інстанціювати компонент ( mountedбуде запущений тощо)
btk

1
@btk Я погоджуюсь, це, мабуть, не "правильний" спосіб робити речі, але це досить чистий хакер, який він є.
Брайан Кунг

1
це корисно. Я використовую повний шлях маршруту як ключ для відтворення того ж компонента, коли маршрут змінюється. : key = "$ route.fullPath"
Нірав Ганді

44

Чому?

... чи потрібно примушувати оновлення?

Можливо, ви не вивчаєте 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, перевірте Офіційні Документи про Реактивність - Зміни Піктограм виявлення . Це обов’язково читати!


2
Безумовно, погоджуєтесь, що вам слід поставити під сумнів цю вимогу оновлення, але іноді вам просто потрібен інтерфейс для повторного відображення, оскільки вікно перегляду змінилося, і вам потрібно показати різні активи (як один приклад). Дані, можливо, насправді не змінилися.
the_dude_abides

1
Чому потрібно перезавантажувати? У деяких випадках файли ресурсів (таблиці стилів / js), кешовані браузером, потрібно перезавантажити через певний проміжок часу. У мене був таблиця стилів, яку потрібно було перезавантажити через 7 днів, і якщо користувач утримував відкриту вкладку з доступом до сторінки і повертався через 7 днів для переходу по цій сторінці, CSS було більше 7 днів.
Aurovrata

@AchielVolckaert ви, мабуть, вже знайшли відповідь, але так, Vue.set()також працює всередині компонентів.
acdcjunior

1
@the_dude_abides і @ Aurovrata, це законне використання оновлення, я згоден. Питання, яке я ставив, - це те, що люди не рідко роблять освіжаючі з неправильних причин.
acdcjunior

1
Можливо, ви просто намагаєтеся виправити помилку в погано розробленому веб-додатку, який використовує vue виключно як інструмент візуалізації, і, наприклад, перезавантажує всю програму кожного разу, коли вона переходить на сервер, ігноруючи можливості клієнтської програми vue. У реальному світі у вас не завжди є час виправити кожну гидоту.
Уоррен Роса

30

Будь ласка, прочитайте цей http://michaelnthiessen.com/force-re-render/

Жахливий спосіб: перезавантаження всієї сторінки
Страшний спосіб: використання v-if hack
Кращий спосіб: використання вбудованого методу forceUpdate Vue
Найкращий спосіб: зміна ключа на вашому компоненті

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

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

Я також використовую годинник: у деяких ситуаціях.


Абсолютно, я згоден з вами!
Діамант

Я майже здався на Vue. Але завдяки цьому моя віра у Vue була відновлена.
jokab

Посилання насправді не показує, як це зробити жахливим способом, що, на жаль, мені потрібно, оскільки мій додаток розроблено навколо навігації по жахливому шляху. Проста URL-адреса на поточну сторінку, здається, не працює, принаймні, не в додатку, з яким я маю справу, тому мені справді потрібні інструкції, як це зробити жахливим способом.
Warren Dew

@WarrenDew ласка , дотримуйтесь: stackoverflow.com/questions/3715047 / ...
Яша

25

Спробуйте використати this.$router.go(0);для перезавантаження поточної сторінки вручну.


3
Простіше: це. $ Router.go ()
Маріус

Насправді @MariusAndreiana - для функції .go () потрібен 1 необов'язковий параметр
a_lovelace


15

Звичайно .. ви можете просто скористатися атрибутом ключа, щоб змусити його повторно виводити (відпочити) у будь-який час.

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

Див. Https://jsfiddle.net/mgoetzke/epqy1xgf/ для прикладу

Тут також обговорювалося: https://github.com/vuejs/Discussion/isissue/356#issuecomment-336060875


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

разом з ним використовуйте this.$set(obj,'obj_key',value) та оновлюйте uniqueKeyдля кожного оновлення значення об'єкта (obj) для кожного оновленняthis.uniqueKey++

це працювало для мене таким чином


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>

5

використовуючи директиву v-if

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

Отже, просто змінивши значення дійснозначного значення з хибного на істинне, знову призведе компонент між дівом


1
На мій погляд, це найчистіший спосіб перезавантажити компонент. Хоча в створеному () методі Ви можете додати деякі речі ініціалізації.
Пьотр Шак

5

Для того, щоб перезавантажити / відновити / оновити компонент, зупиніть довгі кодування. Існує спосіб Vue.JS зробити це.

Просто використовуйте :keyатрибут.

Наприклад:

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

Я використовую цю в слоті BS Vue Table. Сказав, що я щось зроблю для цього компонента, щоб зробити його унікальним.


3

Це спрацювало на мене.

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

Інший компонент запускає подію оновлення-списку, що призведе до повторного відображення поточного компонента


2

Я знайшов спосіб. Це трохи хакі, але працює.

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

Де vmзнаходиться ваш об'єкт-модель перегляду, і xце неіснуюча змінна.

Vue.js поскаржиться на це у журналі консолі, але він запускає оновлення для всіх даних. Тестовано з версією 1.0.26.


2

Працювали для мене

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

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


0

: key = "$ route.params.param1" просто використовуйте ключ зі своїми будь-якими парамами для автоматичного перезавантаження дітей.


4
спробуйте дати детальну інформацію про своє рішення. додайте свій код, виділіть ключові слова
Агіланбу

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>

0

Вибачте, хлопці, окрім методу перезавантаження сторінки (мерехтіння), жоден з них не працює для мене (: ключ не працював).

і я знайшов цей метод із старого форуму vue.js, який працює для мене:

https://github.com/vuejs/Discussion/isissue/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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.