vue-router 导航守卫

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <script type="text/javascript" src="../vue.min.js"></script>
        <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
        <script src="../node_modules/axios/dist/axios.js"></script>
        <script type="text/javascript">
            // 导航完成后获取数据,这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。
            var Index = {
                template: `
                    <div>我是首页</div>
                `
            };

            var Post = {
                data() {
                    return {
                        loading: false,
                        error: null,
                        post: null
                    }
                },
                template: `
                    <div>
                        <div class = 'loading' v-if = 'loading'>
                            loading.....
                        </div>
                        <div v-if="error" class = 'error'>
                            {{error}}
                        </div>
                        <div class = 'content' v-if = 'post'>
                            <h2>{{post.title}}</h2>
                            <p>{{post.body}}</p>
                        </div>
                    </div>
                `,
                created() {
                    // 组件创建完成后获取数据
                    // 此时data已经被监听了
                    this.fetchData();

                },
                watch: {
                    '$route': 'fetchData'
                },
                methods: {
                    fetchData() {
                        this.error = null;
                        this.post = null;
                        this.loading = true;
                        this.$axios.get('http://127.0.0.1:8888/post')
                            .then(res => {
                                this.loading = false;
                                console.log(res.data);
                                this.post = res.data;
                            })
                            .catch(err => {
                                this.error = err.toString();
                            })
                    }
                }
            }

            var router = new VueRouter({
                routes: [{
                        path: '/index',
                        name: 'index',
                        component: Index
                    },
                    {
                        path: '/post',
                        name: 'post',
                        component: Post
                    }
                ]
            });

            var App = {
                template: `
                    <div>
                        <router-link :to = "{name:'index'}">首页</router-link>
                        <router-link :to = "{name:'post'}">我的博客</router-link>

                        <router-view></router-view>
                    </div>
                `
            };
            Vue.prototype.$axios = axios;
            new Vue({
                el: "#app",
                data: {

                },
                components: {
                    App
                },
                template: `<App />`,
                router
            });
        </script>
    </body>
</html>

导航完成之前获取参数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <script src="vue.js"></script>
        <script type="text/javascript" src="vue-router.js"></script>
        <script type="text/javascript" src="axios.js"></script>
        <script>
            Vue.use(VueRouter)
            var User = {
                data() {
                    return {
                        user: '',
                        error: null,
                        timer: null,
                        num: 0,
                        msg: '', //输入框中输入的内容
                        msg1: '', //页面中展示的数据
                        confir: true
                    }
                },
                template: `
                    <div>
                        <div>{{num}}</div>
                        <input type="text" v-model = 'msg' />
                        <p>{{msg1}}</p>
                        <button @click='save'>保存</button>
                        <div v-if="error" class = 'error'>
                            {{error}}
                        </div>
                        <div class='user' v-if = 'user'>
                            <h2>{{user}}</h2>
                        </div>
                    </div>
                `,
                methods: {
                    setDatas(user) {
                        this.user = user;

                    },
                    setError(err) {
                        this.err = err;
                    },
                    save() {
                        this.msg1 = this.msg;
                        this.msg = '';
                        this.confir = true;
                    }
                },
                created() {
                    this.timer = setInterval(() => {
                        console.log(this.num)
                        this.num += 1;
                    }, 1000)
                },
                beforeRouteEnter(to, from, next) {
                    // 在渲染该组件的对应路由被 confirm 前调用
                    // 不!能!获取组件实例 `this`
                    // 因为当守卫执行前,组件实例还没被创建
                    console.log(to);
                    axios.get(`http://127.0.0.1:8888/user/${to.params.id}`)
                        .then(res => {
                            next(vm => vm.setDatas(res.data));
                        })
                        .catch(err => {
                            next(vm => vm.setError(err))
                        })

                },
                beforeRouteUpdate(to, from, next) {
                    console.log(to)
                    // 在当前路由改变,但是该组件被复用时调用
                    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
                    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
                    // 可以访问组件实例 `this`

                    this.user = null;

                    this.$axios.get(`http://127.0.0.1:8888/user/${to.params.id}`)
                        .then(res => {
                            this.setDatas(res.data);
                            next();
                        })
                        .catch(err => {
                            this.setError(err);
                            next();
                        })

                },
                beforeRouteLeave(to, from, next) {
                    // 导航离开该组件的对应路由时调用
                    // 可以访问组件实例 `this`
                    clearInterval(this.timer);
                    console.log('离开了');

                    if (this.confir == true && this.msg) {
                        //证明用户输入了内容 需要提示用户 保存重要信息
                        this.confir = confirm('请保存重要信息'); //用户点击了取消按钮 返回值为false

                        next(false);
                    } else if (this.confir == false) {
                        alert('请保存次信息后退出');
                        next(false);
                    } else {
                        next(); //放行路由
                    }

                }
            }


            //我是测试组件
            var Test = {
                template: `
                    <div>我是测试组件</div>
                `
            }

            // 路由的配置
            var router = new VueRouter({
                routes: [{
                    path: '/user/:id',
                    name: 'user',
                    component: User,

                }, {
                    path: '/test',
                    name: 'test',
                    component: Test
                }]
            });
            //入口组件
            var App = {
                template: `
                    <div>
                        <router-link :to = "{name:'test'}">测试</router-link>
                        <router-link :to = "{name:'user',params:{id:1}}">我的用户1</router-link>
                        <router-link :to = "{name:'user',params:{id:2}}">我的用户2</router-link>

                        <router-view></router-view>
                    </div>
                `
            };

            Vue.prototype.$axios = axios;
            new Vue({
                el: "#app",
                data: {

                },
                components: {
                    App
                },
                template: `<App />`,
                router
            });
        </script>
    </body>
</html>
原文地址:https://www.cnblogs.com/jwen1994/p/10993756.html