路线更改时更新VueJs组件

use*_*827 15 vue.js vue-component vuejs2

有没有办法在路线更改时重新渲染组件?我正在使用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
}
Run Code Online (Sandbox Code Playgroud)

然后我使用道具加载新地图和新数据,但地图保持与首次加载时相同.我不确定发生了什么.

该组件如下所示:

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
  });
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*ann 37

您可能希望添加:key属性,<router-view>如下所示:

<router-view :key="$route.fullPath"></router-view>
Run Code Online (Sandbox Code Playgroud)

这样,一旦路径改变,Vue Router将重新加载组件.如果没有密钥,它甚至不会注意到因为使用相同的组件(在您的情况下是Map组件)而发生了某些变化.

  • 这可行,但可能效率很低.假设您移动地图并将URL更改为gps coords ...这将每次刷新整个组件. (5认同)

Ber*_*ert 10

这个问题的替代解决方案在更多情况下处理这种情况.

首先,你不应该真的打电话给mounted()自己.将您正在进行的操作抽象为mounted可以调用的方法mounted.其次,Vue会尝试在可能的情况下重新使用组件,因此您的主要问题可能mounted只会被触发一次.相反,您可以尝试使用updatedbeforeUpdate 生命周期事件.

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()
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个小例子,不是绘制d3的东西,而是显示交换路由时如何mountedupdated被触发.弹出打开控制台,你会看到mounted只被射击一次.

  • 但是当使用一起安装和更新,并且有axios http请求时,它会重复发送请求.(对不起英格) (4认同)
  • 我同意上面的@FarshidRezaei:如果您将 http 请求放入 `updated()` 中,那么该请求返回的数据肯定会更改(或更新)组件数据,这将再次触发 `updated()` 并导致无限循环。 (2认同)

Irf*_*Jip 8

这是旧答案,最新答案如下

我对这个问题的解决方案是观看$route物业。
最终您将获得两个值,即tofrom

watch: {
  '$route'(to, from) {
    const id = to.params.id
    this.AJAXRequest(id)
  }
},
Run Code Online (Sandbox Code Playgroud)

更新--- 2019年7月3日

原理与上述相同,但是事实证明,我在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()
  },
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我只是添加了一个next()功能。希望这对您有所帮助!祝好运!

  • 这种方法比“关键”黑客方法好得多。 (3认同)