SOURCE

console 命令行工具 X clear

                    
>
console
// 0. 使用vue-router的步骤,对于模块化,需要先使用Vue.use(VueRouter);

// 0.1, 定义好各映射的组件
var ComponentA = {
    template: '<div>{{content}}</div>',
    data: function(){
        return {
            content: 'test component-a content'
        }
    }
};

var ComponentB = {
    template: '<div> {{ name }} </div>',
    data: function(){
        return {
            name: 'my name is component-b, hello!'
        }
    }
};

var ComponentC = {
    template: '<div> {{ $route.params.userId }} </div>',
    /*watch: {

    }*/
    data: function(){
        return {
            testThis: 'haha'
        }
    },
    beforeRouteEnter: function(to, from, next){
        // 组件内部的导航守卫,在激活即第一次进入组件时调用
        // 此时,组件还未被实例化,因此无法调用this,但是可以通过在next中指定回调函数,等组件实例化完后进行调用
        console.log('组件内部BeforeRouteEnter');
        next(function(vm){
            console.log('组件实例化后,执行回调', vm.testThis);
        });
    },
    beforeRouteUpdate: function(to, from, next){
        // 复用组件时进行更新之前,beforeRouteUpdate不会触发任何进入和离开的导航守卫
        console.log('组件内部的beforeRouteUpdate守卫');
        next();
    },
    beforeRouteLeave: function(to, from, next){
        console.log('组件内部的beforeRouteLeave守卫,在导航发生变化,该组件失活时调用');
        next();
    }
};

var ComponentD = {
    template: `
        <div class="nest-component">
            嵌套路由,即允许在任意一个组件内部再次进行路由映射,即可以在组件内部提供路由映射的视图router-view
           <div>
            <router-link :to="'/test/user/' + $route.params.userName + '/info'">用户C的个人信息模块</router-link>
            <router-link :to="'/test/user/' + $route.params.userName + '/technology'">用户C的技能模块</router-link>
           </div>
           
            <router-view></router-view>
        </div>
    `,
    beforeRouteLeave: function(to, from, next){
        console.log('组件D的beforeRouteLeave');
        next();
    }
};

var InforComponent = {
    template: `
        <div>
            <div>name: {{$route.params.userName}}</div>
            <div>sex: 女</div>
        </div>
    `,
};

var TecComponent = {
    template: `
        <div>
            <div>技能1</div>
            <div>技能2</div>
            <div>技能3</div>
        </div>
    `,
};

var UserDefaultComponent = {
    template: `
        <div>
            默认是个人首页
        </div>
    `,
};

var GrammerRouter = {
    template: `
        <div @click="clickRouter">
            点击后利用程序编程实现跳转{{userId}}
        </div>
    `,
    data: function(){
        return {
            userId: 'liangliang'
        };
    },
    methods: {
        clickRouter: function(){
            this.$router.push({name: 'userId', params: {
                userId: this.userId,
            }});
        },
    }
};

var NameRouter = {
    template: `
        <div>
            <div>命名视图,同级下有多个router-view,给view命名,分别做映射</div>
            <div>
                <router-link to="/namerouter">点击变换路径,然后多个router-view视图同时根据一个路由进行各组件的渲染</router-link>
            </div>

            <div>
                <router-view class="header" name="view1"></router-view>
                <router-view class="main" name='view2'></router-view>
                <router-view class="default"></router-view>
            </div>
        </div>
    `,
};

var View1Component = {
    template: '<div> 我是view1 </div>',
};

var View2Component = {
    template: '<div> 我是view2 </div>'
};

var DefaultViewComponent = {
    template: '<div> 我是默认view </div>'
};

// 1. 第一步,需要先定义路由,即定义好你的路由表,其中包括你的每个路由要映射到的组件
const routes = [
    {path: '/', component: ComponentA}, // 路由1,以及路由1映射到的某个组件
    {path: '/test', component: ComponentB}, // 路由2,以及路由2映射到的某个组件
    {
        path: '/test/:userId',
        name: 'userId', // 利用name给一个路由映射命名,从而方便使用
        component: ComponentC,
        beforeEnter: function(to, from, next){
            // 路由对象自身的独享钩子,即导航守卫
            console.log('路由userId的独享钩子beforeEnter', to );
            next();
        },
    }, // 路由3, 使用动态路由参数,可以将符合路由模式的所有路由映射到同一个组件上,但问题就是vue采用复用,导致动态参数变化时,那个组件不会销毁和重建,而是简单的复用原组件,所以不会再次调用组件的生命周期的钩子函数,因此可以选择利用动态参数作为组件的key值,以此来标识不是同一个节点,从而完成组件的销毁和重建,其次就是可以在组件中添加watch属性,通过$route来观测参数变化,或者是使用导航守卫beforeRouteUpdat.
    {
        path: '/test/user/:userName',
        component: ComponentD,
        children: [// 在一个路由中,使用children来指定嵌套路由的映射情况
            {path: 'info', component: InforComponent}, // 子路由1, 即/test/user/:userId/info
            {path: 'technology', component: TecComponent},// 子路由2, 即/test/user/:userId/technology
            {path: '', component: UserDefaultComponent}, // 提供一个空的默认情况下的渲染组件,即/test/user/:userId
        ]
    },
    {// 路由5, 命名视图,即一个路由在同级需要多个视图时,就需要给视图命名,然后在路由映射表中将不同名称的router-view映射成相应的组件
        path: '/namerouter',
        components: {
            'view1': View1Component,
            'view2': View2Component,
            default: DefaultViewComponent,
        }

    }
];

// 2. 第二步, 利用定义好的路由表实例化一个VueRouter
const router = new VueRouter({
    routes: routes,
});

// 全局导航守卫:定义在VueRouter实例上,在路由表中定义的每个路由对象都能执行
//(1)通过beforeEach来注册前置守卫;
//(2)通过beforeResolve守卫来进行导航resolve前的操作,
//(3)通过afterEach来注册后置守卫,在一个导航被resolve后,确认前执行

router.beforeEach(function(to, from, next){
    // to表示即将要跳向的目标路由对象
    // from表示即将要跳走的路由
    // next,一定要确保所有路由对象都能执行到next,也要避免next的重复执行
    // 因为next要结束掉即resolve当前的钩子,
    // 确保能进入下一个钩子函数,否则当前导航会一直在等待状态
    console.log('beforeEach守卫');
    next();
});


router.beforeResolve(function(to, from, next){
    console.log('beforeResolve守卫,导航被确认之前');
    next();
});

router.afterEach(function(to, from){
    console.log('afterEach 导航被确认之后 导航不可被修改');
});


// 3. 第三步,在整个应用的Vue实例上,挂载这个VueRouter实例,以便整个应用都可以使用该路由表做映射
new Vue({
    el: '#app',
    data: {
        test: 'test',
    },
    components: {
        'grammer-router': GrammerRouter,
        'name-router': NameRouter,
    },
    router: router,
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
    {{test}}

    <!-- 4. 第四步, 在html或者模板中,使用router-view,
    给渲染的内容一个视图(容器),不然路由不知道要把映射出的组件渲染到哪里-->
    <router-view></router-view>

    <!-- 5. 第五步,使用的时候,是利用router-link来完成导航-->
    <div>
        <!-- // 导航模块 -->
        <router-link to="/">首页</router-link>
        <router-link to="/test">测试模块</router-link>
        <router-link to="/test/userA">用户A</router-link>
        <router-link to="/test/userB">用户B</router-link>
        <router-link to="/test/user/chaochao">用户超超</router-link>
    </div>

    <div>
        使用编程式导航
        <grammer-router></grammer-router>
    </div>

    <div>
        命名视图
        <name-router></name-router>
    </div>
</div>