Update VueJs component on route change

2019-03-27 08:26发布

Is there a way to re-render a component on route change? I'm using Vue Router 2.3.0, and I'm using the same component in multiple routes. It works fine the first time or if I navigate to a route that doesn't use the component and then go to one that does. I'm passing what's different in props like so

{
  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
}

Then I'm using the props to load a new map and new data, but the map stays the same as when it first loaded. I'm not sure what's going on.

The component looks like this:

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
  });
}

2条回答
Ridiculous、
2楼-- · 2019-03-27 08:40

The alternate solution to this question handles this situation in more cases.

First, you shouldn't really call mounted() yourself. Abstract the things you are doing in mounted into a method that you can call from mounted. Second, Vue will try to re-use components when it can, so your main issue is likely that mounted is only ever fired once. Instead, you might try using the updated or beforeUpdate lifecycle event.

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()
  }
}

Here's a little example, not drawing the d3 stuff, but showing how mounted and updated are fired when you swap routes. Pop open the console, and you will see mounted is only ever fired once.

查看更多
我命由我不由天
3楼-- · 2019-03-27 08:51

You may want to add a :key attribute to <router-view> like so:

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

This way, Vue Router will reload the component once the path changes. Without the key, it won’t even notice that something has changed because the same component is being used (in your case, the Map component).

查看更多
登录 后发表回答