Vue-Router

vue-router是vue的核心插件,vue+vue-router 主要来做 SPA(Single Page Application) 单页面应用

为什么要使用单页面应用?

传统的路由跳转,如果后端资源过多,会导致页面出现`白屏现象`,让前端来做路由,在某个生命周期的钩子函数中发送ajax,数据驱动。为了用户体验

官网

https://router.vuejs.org/zh/installation.html

 

安装

直接下载 / CDN

https://unpkg.com/vue-router/dist/vue-router.js

项目中下载指定版本

cnpm i vue-router@2 -S

 

 1.定义路由组件

    const Home = {
        data() {
            return {}
        },
        template: `<div>我是首页</div>`
    }

2.创建router实例,配置路由规则

 const router = new VueRouter({
        //定义路由规则
        mode:'history',
        routes: [
            {
              path:'/',
              redirect:'/home'
            },
            {
                path: '/home',
                component: Home
            },
            {
                path: '/course',
                component: Course
            }
        ]
    })

3.创建Vue实例,并挂载路由对象

    new Vue({
        el: '#app',
        //挂载 路由对象
        router,
        data() {
            return {}
        },
        template: `<App />`,
        components: {
            App
        }
    })

4.template中渲染router-link和router-view

    let App = {
        data() {
            return {}
        },
//        router-link和router-view 是vue-router 提供的两个全局组件
        //router-view  是路由组件的出口
        //router-link默认会被渲染成a标签,to属性默认被渲染成href
        template: `
            <div>

                <div class="header">
                    
                    <router-link to = '/home'>首页</router-link>
                    <router-link to = '/course'>免费课程</router-link>
                </div>
                <router-view></router-view>
            </div>
        `
    }
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app">

</div>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<script>
    //如果以后是模块化编程,Vue.proptotype.$VueRouter = VueRouter
    //    Vue.use(VueRouter)
    const Home = {
        data() {
            return {}
        },
        template: `<div>我是首页</div>`
    }
    const Course = {
        data() {
            return {}
        },
        template: `<div>我是免费课程</div>`
    }
    //创建路由
    const router = new VueRouter({
        //定义路由规则
        mode:'history',
        routes: [
            {
              path:'/',
              redirect:'/home'
            },
            {
                path: '/home',
                component: Home
            },
            {
                path: '/course',
                component: Course
            }
        ]
    })
    let App = {
        data() {
            return {}
        },
//        router-link和router-view 是vue-router 提供的两个全局组件
        //router-view  是路由组件的出口
        template: `
            <div>

                <div class="header">
                    <router-link to = '/home'>首页</router-link>
                    <router-link to = '/course'>免费课程</router-link>
                </div>
                <router-view></router-view>
            </div>

        `

    }
    new Vue({
        el: '#app',
        //挂载 路由对象
        router,
        data() {
            return {}
        },
        template: `<App />`,
        components: {
            App
        }
    })

</script>

</body>
</html>
vue-router的基本使用

 

命名路由

有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。

 要链接到一个命名路由,可以给 router-link 的 to 属性传一个对象:

注意需要绑定 :to

 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app">

</div>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<script>
    const Home = {
        data() {
            return {}
        },
        template: `<div>我是首页</div>`
    }
    const Course = {
        data() {
            return {
                categoryList:[]
            }
        },
        template: `<div>
        <span v-for = '(item,index) in categoryList'>{{item.name}}</span>


    </div>`,
        methods:{
          getCategroyList(){

          }
        },
        created(){
            //ajax 发送请求 数据获取
            this.getCategroyList();
        }
    }
    //创建路由
    const router = new VueRouter({
        //定义路由规则
        routes: [
            {
              path:'/',
              redirect:'/home'
            },
            {
                path: '/home',
                name:'Home',
                component: Home
            },
            {
                path: '/course',
                name:'Course',
                component: Course
            }
        ]
    })
    let App = {
        data() {
            return {}
        },
//        router-link和router-view 是vue-router 提供的两个全局组件
        //router-view  是路由组件的出口
        template: `
            <div>

                <div class="header">
                    <router-link :to = '{name:"Home"}'>首页</router-link>
                    <router-link :to = '{name:"Course"}'>免费课程</router-link>
                </div>
                <router-view></router-view>
            </div>

        `

    }
    new Vue({
        el: '#app',
        //挂载 路由对象
        router,
        data() {
            return {}
        },
        template: `<App />`,
        components: {
            App
        }
    })

</script>

</body>
</html>
命名路由

动态路由匹配

$route 路由信息对象

提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。

这里我们使用watch (监测变化) $route 对象:

$route(to,from) 这两个参数,to 代表到哪里去 , from 代表你从哪里来

 1.动态绑定参数

 

 

2.router-link绑定这个对象

 3.watch监听路由变化

 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app">

</div>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<script>
    //如果以后是模块化编程,Vue.proptotype.$VueRouter = VueRouter
    //    Vue.use(VueRouter)

    //路由范式:

    //http://127.0.0.1:8080/index/user
    //http://127.0.0.1:8080/user/1 params
    //http://127.0.0.1:8080/user/2
    //http://127.0.0.1:8080/user?user_id =1   query


    const User = {
        data() {
            return {
                user_id:null
            }
        },
        template: `<div>我是用户{{ user_id}}</div>`,
        created() {
            console.log(this.$route); //路由信息对象
//            提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
        },
        watch: {
            '$route'(to, from) {
                // 对路由变化作出响应...
                console.log(to.params.id);
                console.log(from);
                this.user_id = to.params.id;
                //发送ajax

            }
        }
    }

    //创建路由
    const router = new VueRouter({
        //定义路由规则
        routes: [

            {
                path: '/user/:id',
                name: 'User',
                component: User
            }

        ]
    })
    let App = {
        data() {
            return {}
        },
//        router-link和router-view 是vue-router 提供的两个全局组件
        //router-view  是路由组件的出口
        template: `
            <div>

                <div class="header">
                    <router-link :to = '{name:"User",params:{id:1}}'>用户1</router-link>
                    <router-link :to = '{name:"User",params:{id:2}}'>用户2</router-link>

                </div>
                <router-view></router-view>
            </div>

        `

    }
    new Vue({
        el: '#app',
        //挂载 路由对象
        router,
        data() {
            return {}
        },
        template: `<App />`,
        components: {
            App
        }
    })

</script>

</body>
</html>
动态路由匹配

query

 

 

编程式导航

$router 路由对象 VueRouter

标签绑定事件后,使用$router.push进行跳转

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="../vue.js"></script>
<script src="../vue-router.js"></script>
<div class="app">

</div>
<div></div>

<script>
    const Home = {
        data(){
            return{}
        },
        template: `<div>我是首页</div>
`
    };
    const User = {
        data(){
            return{
                user_id:null
            }
        },
        template: `<div>我是用户{{ user_id }}号
                    <button @click="clickHankler">跳转首页</button>
                    </div>
`,
        methods:{
            //编程式导航
          clickHankler (){
              this.$router.push({
                  name:'Home'
              })
          }
        },
        watch:{
             '$route'(to,from) {
                  // console.log(to);
                  console.log(from);
                  this.user_id = to.params.id
             }
        }
    };
    
    const router = new VueRouter({
        mode:"history",
        routes:[
            {
                path:'/user/:id',
                component: User,
                name:'user'
            },
            {
                path:'/home',
                component:Home,
                name:'Home'
            }
        ],

    });

    let App = {
        data(){
            return{}
        },
        template:`
            <div>
            <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>
        `
    };
    new Vue({
        el:'.app',
        router,
        data(){
            return{

            }
        },
        template:`<App/>`,
        components:{
            App
        }
    })
</script>

</body>
</html>
编程式导航

 

获取原生的DOM的方式

 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="../vue-router.js"></script>
<script src="../vue.js"></script>

<div id="app">

</div>

<div></div>

<script>

    Vue.component('Test', {
        data() {
            return {}
        },
        template: `<div>我是测试组件</div>
`
    });


    let App = {
        data() {
            return {}
        },
        template: `
           <div ref="abc">
           <Test ref="zzz"></Test>
</div>

        `,
        mounted() {
            // console.log(this.$refs);
            // console.log(this.$refs.abc);
            // console.log(this.$refs.zzz);
            //  console.log(this.$refs.zzz.$parent);
            //  console.log(this.$refs.zzz.$root);  //找到Vue实例对象
             // console.log(this.$refs.zzz.$children)
        }
    };
    new Vue({
        el: '#app',
        data() {
            return {}
        },
        components: {
            App
        },
        template:`
            <App></App>
        `

    })
</script>

</body>
</html>
refs属性

 

全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。

每个守卫方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象

  • from: Route: 当前导航正要离开的路由

  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

    • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

    • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

    • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

    • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

**确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。**这里有一个在用户未能验证身份时重定向到 /login 的示例:

 

 

 

posted @ 2020-11-10 17:11  断浪狂刀忆年少  阅读(156)  评论(0编辑  收藏  举报