Почему в браузере отображается кэшированное Vue. js представление об изменении маршрута / URL? - PullRequest
1 голос
/ 06 апреля 2020

У меня есть домашняя страница с <router-link> тегами для просмотра. Это простое отношение мастер / подробности, где Homepage представляет собой каталог продуктов, а на странице подробностей Product отображается информация о каждом элементе.

Когда я впервые запускаю веб-сайт и нажимаю на элемент в представлении Homepage (например, URL: http://localhost:8080/100-sql-server-2019-licence) загружается представление Product и детали продукта загружаются нормально.

Если я затем нажимаю кнопку возврата в браузере, чтобы вернуться к Homepage и затем нажмите на другой Product (например, URL: http://localhost:8080/101-oracle-12c-licence), URL-адрес в адресной строке браузера изменится, но я получу информацию о предыдущем продукте. Это молниеносно, и новые сетевые вызовы не выполняются, что означает, что он просто показывает кэшированную страницу предыдущего продукта. Если я затем нажму на кнопку refre sh, находясь на этой странице, будет выполнен сетевой вызов и отобразится правильная информация о продукте.

Я выполнил поиск в Интернете, но не смог найти эту проблему, описанную в поиске. Результаты. Может ли кто-нибудь указать мне правильное направление, как вызвать обновление / повторную визуализацию маршрута при изменении маршрута?

1 Ответ

1 голос
/ 06 апреля 2020

Что происходит

vue-router будет кэшировать ваши компоненты по умолчанию.
Поэтому, когда вы переходите ко второму продукту (который, вероятно, отображает тот же компонент, что и первый продукт), компонент будет не быть повторно создан для повышения производительности.

Из vue-router документации :

Например, для маршрута с Dynami c params /foo/:id, когда мы перемещаемся между /foo/1 и /foo/2, один и тот же экземпляр компонента Foo будет использоваться повторно.

Простое (но грязное) исправление

Простой, но хакерский и не рекомендуемый способ решить эту проблему - дать вашему <router-view /> ключевое свойство, например:

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

Это заставит vue-router повторно создать экземпляр компонента view. каждый раз, когда изменяется URL.
Однако вы потеряете все преимущества производительности, которые вы обычно получаете от кэширования.

Чистое исправление: правильная обработка изменений маршрута

Чистый способ решения этой проблемы это реагировать на изменение маршрута в вашем компоненте (в основном это сводится к перемещению ajax вызовов из mounted в $route наблюдателя), например:

<script>
export default {
  data() {
    return {
      productDetails: null,
      loading: false
    };
  },
  watch: {
    '$route': {
      // with immediate handler gets called on first mount aswell
      immediate: true,
      // handler will be called every time the route changes.
      // reset your local component state and fetch the new data you need here.
      async handler(route) {
        this.loading = true;
        this.productDetails = null;
        try {
          // example for fetching your product data
          const res = await fetch("http://give.me.product.data/" + encodeURIComponent(route.params.id));
          this.productDetails = await res.json();
        } finally {
          this.loading = false;
        }
      }
    }
  }
};
</script>

Альтернатива: навигационная защита

В качестве альтернативы вы могли бы также используйте vue-router s Встроенные навигационные элементы для реагирования на изменения маршрута:

<script>
export default {
  async beforeRouteUpdate (to, from, next) {
    // TODO: The route has changed.
    // The old route is in `from`, the new route in `to`.
    this.productData = await getProductDataFromSomewhere();

    // route will not change before you haven't called `next()`
    next();
  }
};
</script>
  • Недостатком навигационных элементов является то, что вы можете использовать их только в компонент, который отображает маршрут.
    Таким образом, вы не можете использовать средства навигации в компонентах, находящихся глубже в иерархии.
  • Преимущество заключается в том, что браузер не будет просматривать ваш сайт до вас. Позвоните next(), что даст вам время для загрузки данных, необходимых до отображения вашего маршрута.

Некоторые полезные ресурсы

...