Vue (Hash) Router, обновление при изменении части хэша, а также с помощью кнопки возврата браузера (лучший подход) - PullRequest
1 голос
/ 05 мая 2019

У меня есть демонстрационное приложение, которое отображает некоторые погодные данные для некоторых городов. Я использую Vue hash router для 3 маршрутов:

  1. / (домашняя страница)
  2. /weather/:id (для подробного прогноза по конкретному месту)
  3. /search/:term (для поиска местоположений)

Все работает нормально, кроме маршрута /search/:term, который необходимо обновить при изменении условия поиска, а также при переходе на предыдущую страницу поиска с помощью кнопки «Назад» браузера.

Страница поиска выглядит так (url: http://localhost/#/search/lon):

enter image description here

Компонент страницы поиска:

<template>
  <div :key="'search_page_'+$route.params.term" class="page page-search">
    <h2 class="page-header">Search Results</h2>
    <div class="search-box">
        <input type="text" placeholder="search.." v-model="text" />
        <button type="button" @click="handleOnClick">Search!</button>
    </div>
    <Loader v-if="loading" text="Loading.." />
    <template v-else-if="data && data.length">
    <Weather v-for="place in data" :key="'weather_for_'+place.woeid" :woeid="String(place.woeid)" :city="place.title" />
    </template>
    <p v-else><b>No results found!</b></p>
</div>
</template>

<script>
// @ is an alias to /src
import Loader from '@/components/Loader.vue'
import Weather from '@/components/Weather.vue'
import store from '@/modules/Store'

const API_URL = '/weather.php?keyword=';

export default {
  name: 'search',
  components: {
    Loader, Weather
  },
  data: function() {
    return {
        loading: true,
        text: this.$route.params.term ? decodeURIComponent(this.$route.params.term) : '',
        data: null
    };
  },
  methods: {
    handleOnClick: function() {
        this.$router.push({ name: 'search', params: { term: encodeURIComponent(this.text) } });
    },
    loadData: function( withText ) {
        let searchData = store.get('search_'+this.$route.params.term);
        if ( searchData ) {
            if ( withText ) this.text = decodeURIComponent(this.$route.params.term);
            this.data = searchData;
            this.loading =  false;
        } else {
            fetch(API_URL+this.$route.params.term)
            .then(response => response.json())
            .then(jsonResponse => {
                store.set('search_'+this.$route.params.term, searchData = jsonResponse);
                if ( withText ) this.text = decodeURIComponent(this.$route.params.term);
                this.data = searchData;
                this.loading =  false;
            })
            .catch(error => console.log(error));
        }
    }
  },
  watch: {
    '$route': function(to, from) {
        if ( from.params.term !== to.params.term )
        {
            this.loadData(true);
        }
    }
  },
  mounted: function() {
    this.loadData();
  }/*,
  updated: function() {
    this.loadData();
  }*/
}
</script>

Конфигурация маршрутизатора:

import Vue from 'vue'
import Router from 'vue-router'
import HomePage from './views/HomePage.vue'
import SearchPage from './views/SearchPage.vue'
import WeatherPage from './views/WeatherPage.vue'

Vue.use(Router)

export default new Router({
  mode: 'hash',
  base: '/',
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomePage
    },
    {
      path: '/search/:term',
      name: 'search',
      component: SearchPage
    },
    {
      path: '/weather/:woeid',
      name: 'weather',
      component: WeatherPage
    }
  ]
})

Я заставил это работать (хотя страница поиска немного мигает при обновлении поискового запроса на той же странице и не так реагирует, как я ожидал), но Мне интересно, является ли это лучшим подходом, который я могу использовать или там лучше?

Например, я использую ловушки жизненного цикла для извлечения данных из API, а также использую наблюдатели на маршруте, чтобы иметь возможность реагировать на изменения поискового запроса на той же странице. Также добавлено свойство :key на весь компонент. Но у меня сложилось впечатление, что это можно сделать проще / лучше. возможно, мне не хватает sth и / или, может быть, я делаю что-то дважды (например, я не уверен, что при первом входе на страницу поиска вызывается loadData дважды, так как я loadData на mounted ловлю и на $route изменить).

UPDATE частично ответить 2nd часть вопроса: loadData метод не вызывается дважды при первом входе на страницу поиска. Либо ловушка жизненного цикла mounted вызывается при первом входе на страницу, либо наблюдатель $route запускается при обновлении страницы поиска изнутри самой страницы (включая кнопку возврата браузера), но не оба .

...