在路由更改时更新 VueJs 组件
Update VueJs component on route change
有没有办法在路由更改时重新渲染组件?我正在使用 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
});
}
这个问题的替代解决方案在更多情况下可以处理这种情况。
首先,您真的不应该亲自给 mounted()
打电话。将您在 mounted
中所做的事情抽象为您可以从 mounted
中调用的方法。其次,Vue 会尽可能重用组件,因此您的主要问题可能是 mounted
只被触发过一次。相反,您可以尝试使用 updated
或 beforeUpdate
lifecycle 事件。
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()
}
}
这里有一个 little example,不是绘制 d3 的东西,而是显示交换路由时如何触发 mounted
和 updated
。弹出控制台,您会看到 mounted
只触发一次。
您可能希望向 <router-view>
添加一个 :key 属性,如下所示:
<router-view :key="$route.fullPath"></router-view>
这样,一旦路径发生变化,Vue Router 就会重新加载组件。如果没有密钥,它甚至不会注意到某些内容发生了变化,因为正在使用相同的组件(在您的例子中是 Map 组件)。
更新 --- 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()
},
}
如您所见,我只是添加了一个next()
函数。希望这对你有帮助!祝你好运!
下面是我以前的回答。
只为“进步”而保存
我解决这个问题的方法是观看 $route
属性。
最终你会得到两个值,即 to
和 from
.
watch: {
'$route'(to, from) {
const id = to.params.id
this.AJAXRequest(id)
}
},
是的,我遇到了同样的问题,通过以下方式解决了;
ProductDetails.vue
data() {
return {
...
productId: this.$route.params.productId,
...
};
},
methods: {
...mapActions("products", ["fetchProduct"]),
...
},
created() {
this.fetchProduct(this.productId);
...
}
fetchProduct
功能来自 Vuex
商店。当单击另一个产品时,路由参数被 productId
更改,但 component
不会重新呈现,因为 created
生命周期挂钩在初始化阶段执行。
当我在父组件 app.vue
文件
上添加 router-view
时
app.vue
<router-view :key="this.$route.path"></router-view>
现在对我来说效果很好。希望这对 Vue 开发人员有所帮助!
您可以只使用此代码:
watch: {
$route(to, from) {
// react to route changes...
}
}
有没有办法在路由更改时重新渲染组件?我正在使用 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
});
}
这个问题的替代解决方案在更多情况下可以处理这种情况。
首先,您真的不应该亲自给 mounted()
打电话。将您在 mounted
中所做的事情抽象为您可以从 mounted
中调用的方法。其次,Vue 会尽可能重用组件,因此您的主要问题可能是 mounted
只被触发过一次。相反,您可以尝试使用 updated
或 beforeUpdate
lifecycle 事件。
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()
}
}
这里有一个 little example,不是绘制 d3 的东西,而是显示交换路由时如何触发 mounted
和 updated
。弹出控制台,您会看到 mounted
只触发一次。
您可能希望向 <router-view>
添加一个 :key 属性,如下所示:
<router-view :key="$route.fullPath"></router-view>
这样,一旦路径发生变化,Vue Router 就会重新加载组件。如果没有密钥,它甚至不会注意到某些内容发生了变化,因为正在使用相同的组件(在您的例子中是 Map 组件)。
更新 --- 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()
},
}
如您所见,我只是添加了一个next()
函数。希望这对你有帮助!祝你好运!
下面是我以前的回答。
只为“进步”而保存
我解决这个问题的方法是观看 $route
属性。
最终你会得到两个值,即 to
和 from
.
watch: {
'$route'(to, from) {
const id = to.params.id
this.AJAXRequest(id)
}
},
是的,我遇到了同样的问题,通过以下方式解决了;
ProductDetails.vue
data() {
return {
...
productId: this.$route.params.productId,
...
};
},
methods: {
...mapActions("products", ["fetchProduct"]),
...
},
created() {
this.fetchProduct(this.productId);
...
}
fetchProduct
功能来自 Vuex
商店。当单击另一个产品时,路由参数被 productId
更改,但 component
不会重新呈现,因为 created
生命周期挂钩在初始化阶段执行。
当我在父组件 app.vue
文件
router-view
时
app.vue
<router-view :key="this.$route.path"></router-view>
现在对我来说效果很好。希望这对 Vue 开发人员有所帮助!
您可以只使用此代码:
watch: {
$route(to, from) {
// react to route changes...
}
}