Обновить компонент 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()
. Надеюсь, это поможет вам! Удачи!