Обновить компонент VueJs при изменении маршрута

Есть ли способ переопределить компонент при изменении маршрута? Я использую Vue Router 2.3.0, и я использую один и тот же компонент на нескольких маршрутах. Он работает отлично в первый раз, или если я перехожу к маршруту, который не использует компонент, а затем перейдите к тому, что делает. Я передаю то, что по-разному в реквизитах.

{
  name: 'MainMap',
  path: '/',
  props: {
    dataFile: 'all_resv.csv',
    mapFile: 'contig_us.geo.json',
    mapType: 'us'
  },
  folder: true,
  component: Map
},
{
  name: 'Arizona',
  path: '/arizona',
  props: {
    dataFile: 'az.csv',
    mapFile: 'az.counties.json',
    mapType: 'state'
  },
  folder: true,
  component: Map
}

Затем я использую реквизиты для загрузки новой карты и новых данных, но карта остается такой же, как при первой загрузке. Я не уверен, что происходит.

Компонент выглядит следующим образом:

data() {
  return {
    loading: true,
    load: ''
  }
},

props: ['dataFile', 'mapFile', 'mapType'],

watch: {
    load: function() {
        this.mounted();
    }
},

mounted() {
  let _this = this;
  let svg = d3.select(this.$el);

  d3.queue()
    .defer(d3.json, `static/data/maps/${this.mapFile}`)
    .defer(d3.csv, `static/data/stations/${this.dataFile}`)
    .await(function(error, map, stations) {
    // Build Map here
  });
}

Ответ 1

Альтернативное решение этого вопроса обрабатывает эту ситуацию в большем количестве случаев.

Во-первых, вы не должны вызывать mounted() самостоятельно. Абстрагируйте вещи, которые вы делаете в mounted в метод, который вы можете вызвать из mounted Во-вторых, Vue попытается повторно использовать компоненты, когда это возможно, поэтому ваша главная проблема, вероятно, заключается в том, что mounted только один раз. Вместо этого вы можете попробовать использовать beforeUpdate жизненного цикла updated или beforeUpdate.

const Map = {
  data() {
    return {
      loading: true,
      load: ''
    }
  },
  props: ['dataFile', 'mapFile', 'mapType'],
  methods:{
    drawMap(){
        console.log("do a bunch a d3 stuff")
    }
  },
  updated(){
    console.log('updated')
    this.drawMap()
  },
  mounted() {
    console.log('mounted')
    this.drawMap()
  }
}

Вот небольшой пример, не прорисовывающий материал d3, а показывающий, как mounted и updated срабатывания при смене маршрутов. Откройте консоль, и вы увидите, что mounted только один раз.

Ответ 2

Вы можете добавить атрибут: key к <router-view> так:

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

Таким образом, Vue Router перезагрузит компонент после изменения пути. Без ключа он даже не заметит, что что-то изменилось, потому что тот же компонент используется (в вашем случае, компонент Map).

Ответ 3

Это старый ответ, последний ответ ниже

Моим решением этой проблемы было наблюдение за свойством $route.
Что будет в конечном итоге вы получаете два значения, то есть to и from.

watch: {
  '$route'(to, from) {
    const id = to.params.id
    this.AJAXRequest(id)
  }
},

ОБНОВЛЕНИЕ --- 3 июля 2019

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

export default () {
  beforeRouteUpdate (to, from, next) {
    // called when the route that renders this component has changed,
    // but this component is reused in the new route.
    // For example, for a route with dynamic params '/foo/:id', when we
    // navigate between '/foo/1' and '/foo/2', the same 'Foo' component instance
    // will be reused, and this hook will be called when that happens.
    // has access to 'this' component instance.

    const id = to.params.id
    this.AJAXRequest(id)
    next()
  },
}

Как видите, я просто добавляю функцию next(). Надеюсь, это поможет вам! Удачи!