最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Redirect to 404 page without modifying the URL in Vue.js - Stack Overflow

programmeradmin6浏览0评论

In my Vue.js project, I want to display my 404 page, if a route parameter is invalid. For now, I'm using the following code for that:

this.$router.replace({ path: '/404' });

Is there a way to do that without modifying the URL? I want the user to still be able to copy the browser's original URL line. Is there some kind of a silent: true parameter?

In my Vue.js project, I want to display my 404 page, if a route parameter is invalid. For now, I'm using the following code for that:

this.$router.replace({ path: '/404' });

Is there a way to do that without modifying the URL? I want the user to still be able to copy the browser's original URL line. Is there some kind of a silent: true parameter?

Share Improve this question asked Mar 4, 2020 at 10:40 André ReicheltAndré Reichelt 1,6311 gold badge22 silver badges59 bronze badges 2
  • Might be helpful: github./vuejs/vue-router/issues/977 – Farkhat Mikhalko Commented Mar 4, 2020 at 10:44
  • @FarkhatMikhalko Unfortunately no. I already found that discussion. In my case, the redirect should be initiated from the view itself. – André Reichelt Commented Mar 4, 2020 at 10:52
Add a ment  | 

4 Answers 4

Reset to default 7

With vue-router, the URL is the source of truth. If the URL changes, so does the rendering. You can't "pause" the router. (This is a flaw in vue-router that has been bugging me for ages, but I digress.)

You just have to display the 404 page without modifying the route. Have some display404 data property in your root ponent that you can set to display the 404 page manually in the template instead of the <router-view>, e.g:

<div>
  <my-404-page v-if="display404"/>
  <router-view v-else/>
</div>

To display the 404 page from any ponent:

this.$root.display404 = true

Of course this is just a basic example to demonstrate what I mean, you might want to use Vuex to share the state, or use an event bus, or you can display the 404 page in some other way that works for you, etc.

This was fixed in Vue Router 4 which you can see on the second example in the docs.

Build your NotFound route like this:

{ 
  path: '/:pathMatch(.*)*', 
  name: 'NotFound', 
  ponent: NotFound 
},

Then you can use a beforeEnter navigation guard on your dynamic Vue like so:

// In your router/index.js file...
{
  path: 'users/:id',
  name: 'User Detail',
  ponent: UserDetail,
  beforeEnter(to, from) {
    // See if that query exists in your data...
    const exists = data.users.find(
      user => user.id === parseInt(to.params.id)
    )
    if (!exists) {
      // THE IMPORTANT PART
      // Return your not found view...
      return {
        name: 'NotFound',
        // Match the path of your current page and keep the same url...
        params: { pathMatch: to.path.split('/').slice(1) },
        // ...and the same query and hash.
        query: to.query,
        hash: to.hash,
      }
    }
  }
}

Haven't tested this in a Component yet, but I'd assume it'd be the same logic in the beforeRouteEnter navigation guard.

Not 100% sure what you are asking, but is either of these any help?

A catch all route: From Vue.js docs "Catch all route"

Or if you are managing a response form a call (method/fetch/ etc): Use a bination of try/catch and a "loading" data value to change the display or what ponent is loaded.

Based on Decade Moon's solution, I did the following:

main.js

import Error404 from './views/error/404.vue'

Vue.ponent('error-404', Error404)

404.vue

<template>
    <div>
        <h1>Page not found</h1>
        <p>Whatever...</p>
    </div>
</template>

<script>
    export default {
        name: 'Page not found'
    }
</script>

router --> index.js

const PageNotFound = () => import('@/views/error/404')

function configRoutes() {
    return [
        {
            path: '/',
            name: 'Home',
            ponent: TheContainer,
            children: [
                // ...
                {
                    path: '404',
                    name: 'Page not found',
                    ponent: PageNotFound,
                    alias: '*'
                }
            ]
        }
    ]
}

My Page which should display the 404 error

<template>
    <div class="animated fadeIn" v-if="clientSettings">
        ...
    </div>
    <error-404 v-else></error-404>
</template>

<script>
    export default {
        name: 'Test',
        data() {
            return {
                clientSettings: null
            };
        },
        async created() {
            this.setClientConfig();
        },
        watch: {
            '$route.params.id': function (id) { this.setClientConfig(id);}
        },
        methods: {
            setClientConfig(id) {
                if (!id) {
                    id = this.$route.params.id;

                    // Redirect to the first valid list, if no parameter is proviced
                    if (!id) {
                        this.$router.push({ name: 'Test', params: { id: this.$root.clientConfiguration[0].name } });
                        return;
                    }
                }

                // Set client settings
                this.clientSettings = this.$root.clientConfiguration.find(cc => cc.name === id);
                // This will return null, if no entry was found, therefore the template will jump into the v-else
            }
        }
    }
</script>
发布评论

评论列表(0)

  1. 暂无评论