admin管理员组

文章数量:1292172

I'm using Vue and Vue Router in a SPA. In a view ponent I query a repository for a resource. If the resource is not found I want to show a 404 page whilst keeping the URL.

I.e. if I visit /foo/non-existant-id then a 404 page should be shown in place of the show page for the foo resource.

For clarity here is my router map:

router.map({
  '/foo/:id': {name: 'foo-show', ponent: FooShowPage},

  // Utilities
  '/': { name: 'home', ponent: HomePage },
  '*': { name: '404', ponent: NotFoundPage }
})

And in my FooShowPage I do the following:

ready () {
  // fetch the foo from the repo (app.foos)
  app.foos.fetchById(this.$route.params.id).then(foo => {
    this.foo = foo
  }).catch(e => {
    // foo is not found show a 404 page
    // using this.$route.router.go({name: '404'}) does not work as route is a wildcard 
    console.warn(e)
  })
}

Essentially it would probably involve replacing the FooShowPage in the router view with NotFoundPage, or redirecting to a defined 404 page whilst keeping the browser history untouched.

I'm using Vue and Vue Router in a SPA. In a view ponent I query a repository for a resource. If the resource is not found I want to show a 404 page whilst keeping the URL.

I.e. if I visit /foo/non-existant-id then a 404 page should be shown in place of the show page for the foo resource.

For clarity here is my router map:

router.map({
  '/foo/:id': {name: 'foo-show', ponent: FooShowPage},

  // Utilities
  '/': { name: 'home', ponent: HomePage },
  '*': { name: '404', ponent: NotFoundPage }
})

And in my FooShowPage I do the following:

ready () {
  // fetch the foo from the repo (app.foos)
  app.foos.fetchById(this.$route.params.id).then(foo => {
    this.foo = foo
  }).catch(e => {
    // foo is not found show a 404 page
    // using this.$route.router.go({name: '404'}) does not work as route is a wildcard 
    console.warn(e)
  })
}

Essentially it would probably involve replacing the FooShowPage in the router view with NotFoundPage, or redirecting to a defined 404 page whilst keeping the browser history untouched.

Share Improve this question asked Jul 14, 2016 at 14:16 harrygharryg 24.1k47 gold badges134 silver badges208 bronze badges 2
  • Did you solve this? I am currently looking into this and the provided answer doesnt work for me because I don't know which id is valid until I retrieve the result from the backend API – Tobias Beuving Commented Oct 3, 2017 at 8:36
  • I have the same question but can't find a solution anywhere. I don't know if dynamic params are valid until I make an api call and receive a 404. – Jeff Adams Commented Sep 7, 2018 at 21:15
Add a ment  | 

3 Answers 3

Reset to default 6

You need to set a route for 404 page and then redirect unmatched routes to it. I use a router.redirect after the map to do such things.

router.map({
  '/': { name: 'home', ponent: HomePage },
  '/foo/:id': {name: 'foo-show', ponent: FooShowPage},
  '/404': {name: 'not-found', ponent: NotFound}
})

router.redirect({
    '*': '/404'
})

All routes that are NOT listed in the map will then be redirected to /404

Found a solution at Vue.js forum — use navigation guard:

import store from '../store'

{
  path: '/lavori/:lavoro',
  name: 'lavoro',
  ponent: Lavoro,
  beforeEnter: (to, from, next) => {
    function isValid (id) {
      return store.getters.resourceByID(id) !== undefined
    }

    if (!isValid(to.params.id)) {
      next({ name: 'not-found' });
    }    
    next();
  }
},

Edit1: need to import store to get access to getters, from this Github issue and this question

Still a question how to leave same (requested) URL

The best I've figured out how to do is to use a global interceptor with Axios to redirect all 404 responses received through the API the 404 route. However that does change the url to /404 like @Leo's answer.

const http = axios.create({
  headers: {
    'X-Requested-With': 'XMLHttpRequest'
  }
});

// Add some global response intercepters
http.interceptors.response.use(function (response) {
  // For successes just continue as normal
  return response;

}, function (error) {
  // If we have a 404 redirect to the error page replacing the history
  if (error.response.status === 404) {
    return router.replace({ name: 'notfound' });
  }

  return Promise.reject(error);
});

export default http;

本文标签: javascriptIn Vue and Vue Router SPAshowing 404 for a not found resourceStack Overflow