在 beforeRouteEnter 中访问应用程序
Accessing app inside beforeRouteEnter
我想在组件准备由 vue 路由器渲染时在应用程序根目录中显示一些加载动画。
已找到 this question, proposing the use of navigation guards, and ,其中接受的答案显示如何使用 beforeEach
守卫在 app
中设置变量,显示加载动画。
问题是这在深度linking到某些路由时不起作用(初始url包括路由路径,例如'someurl#/foo')。 beforeEach
守卫根本就不会被召唤。
所以我切换到加载组件的 beforeRouteEnter
守卫,这也允许我只显示某些组件的加载动画:
应用程序:
var app = new Vue({
el: '#app',
data: { loading: false }
router: router
});
组件:
var Foo = {
template: '<div>bar</div>',
beforeRouteEnter: function(to, from, next) {
app.loading = true; // 'app' unavailable when deep-linking
// do some loading here before calling next()...
next();
}
}
但后来我发现当对组件进行深度 link 时,app
在 beforeRouteEnter
中不可用,因为它在初始化过程的早期被调用。
我不想在应用程序数据声明中将 loading
设置为 true
,因为我可能会在某个时候决定将 deep-link 设置为另一条路线,其组件不需要加载动画。
使用 Vue.nextTick 找到解决方法:
beforeRouteEnter: function(to, from, next) {
Vue.nextTick(function(){
// now app is available
app.loading = true;
// some loading to happen here...
seTimeout(function(){
app.loading = false;
next();
}, 1000);
})
}
感觉有点老套,非常感谢您提供其他建议。
在此处查找此解决方案的演示:
https://s.codepen.io/schellmax/debug/aYvXqx/GnrnbVPBXezr#/foo
我相信,您的解决方案是正确的。但是,我建议改用 next() 函数。正如 vue-router 文档中所写。
https://router.vuejs.org/en/advanced/navigation-guards.html
The beforeRouteEnter guard does NOT have access to this, because the guard is called before the navigation is confirmed, thus the new entering component has not even been created yet.
However, you can access the instance by passing a callback to next. The callback will be called when the navigation is confirmed, and the component instance will be passed to the callback as the argument:
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$root.loading = true;
})
}
如何使用 beforeRouteLeave
触发加载,然后让组件在 mounted
中将其关闭?
对于应用程序的初始加载,您可以
应用:
var app = new Vue({
el: '#app',
data() => ({ loading: true }),
mounted() { this.loading: false },
router: router
});
然后为您的组件
分量:
var Foo = {
template: '<div>bar</div>',
mounted() {
app.loading = false;
},
beforeRouteLeave(to, from , next) {
switch(to){
case COMPONENT_TO_SHOW_LOADING_ON:
case OTHER_COMPONENT:
app.loading = true;
default:
}
}
}
我想在组件准备由 vue 路由器渲染时在应用程序根目录中显示一些加载动画。
已找到 this question, proposing the use of navigation guards, and beforeEach
守卫在 app
中设置变量,显示加载动画。
问题是这在深度linking到某些路由时不起作用(初始url包括路由路径,例如'someurl#/foo')。 beforeEach
守卫根本就不会被召唤。
所以我切换到加载组件的 beforeRouteEnter
守卫,这也允许我只显示某些组件的加载动画:
应用程序:
var app = new Vue({
el: '#app',
data: { loading: false }
router: router
});
组件:
var Foo = {
template: '<div>bar</div>',
beforeRouteEnter: function(to, from, next) {
app.loading = true; // 'app' unavailable when deep-linking
// do some loading here before calling next()...
next();
}
}
但后来我发现当对组件进行深度 link 时,app
在 beforeRouteEnter
中不可用,因为它在初始化过程的早期被调用。
我不想在应用程序数据声明中将 loading
设置为 true
,因为我可能会在某个时候决定将 deep-link 设置为另一条路线,其组件不需要加载动画。
使用 Vue.nextTick 找到解决方法:
beforeRouteEnter: function(to, from, next) {
Vue.nextTick(function(){
// now app is available
app.loading = true;
// some loading to happen here...
seTimeout(function(){
app.loading = false;
next();
}, 1000);
})
}
感觉有点老套,非常感谢您提供其他建议。
在此处查找此解决方案的演示: https://s.codepen.io/schellmax/debug/aYvXqx/GnrnbVPBXezr#/foo
我相信,您的解决方案是正确的。但是,我建议改用 next() 函数。正如 vue-router 文档中所写。 https://router.vuejs.org/en/advanced/navigation-guards.html
The beforeRouteEnter guard does NOT have access to this, because the guard is called before the navigation is confirmed, thus the new entering component has not even been created yet.
However, you can access the instance by passing a callback to next. The callback will be called when the navigation is confirmed, and the component instance will be passed to the callback as the argument:
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$root.loading = true;
})
}
如何使用 beforeRouteLeave
触发加载,然后让组件在 mounted
中将其关闭?
对于应用程序的初始加载,您可以
应用:
var app = new Vue({
el: '#app',
data() => ({ loading: true }),
mounted() { this.loading: false },
router: router
});
然后为您的组件
分量:
var Foo = {
template: '<div>bar</div>',
mounted() {
app.loading = false;
},
beforeRouteLeave(to, from , next) {
switch(to){
case COMPONENT_TO_SHOW_LOADING_ON:
case OTHER_COMPONENT:
app.loading = true;
default:
}
}
}