vue的路由

目录

1. 渲染函数

render(针对的是组件模板)

plugin

2. 路由机制

3. 动态路由匹配

4. 嵌套路由

5. 编程式导航

6. 路由组件传参

path-query 传参

name-params 传参

7. 路由模式

hash 模式

vue-router 使用的模式

8. 导航守卫 -——路由的改变会触发导航守卫

组件内部守卫

全局守卫

路由独享守卫


1. 渲染函数

render(针对的是组件模板)

        //组件模板:

        let myA = {

            template: `<div>123<div>`,

        //渲染函数 参数createElement是一个函数 创建节点的函数

            render(createElement) { createElement() }

        }

plugin

插件通常用来为 Vue 添加全局功能。Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
</head>

<body>
    <div id="app">
        {{msg}} {{msg | myFilter}}
    </div>
    <script>
        // 声明插件对象
        let myPlugin = {
            //install方法在Vue.use(myPlugin)会运行
            install(Vue, options) {
                // console.log(1);
                // 提供一些静态属性或者方法
                Vue.isVue = () => { }
                // 提供一些原型属性或者方法
                Vue.prototype.$sayVue = () => { }
                // 全局注册(组件/过滤器/指令/混入)
                Vue.filter('myFilter', (data) => {
                    return data.toUpperCase()
                })
            }
        };
        // console.log(Vue.isVue);
        // 使用插件,在new Vue之前使用
        Vue.use(myPlugin);
        // console.log(Vue.isVue);
        // Object.prototype.say = () => { }
        // let obj = new Object()
        // obj.say();

        let vm = new Vue({
            el: '#app',
            data: {
                msg: 'hello'
            },
            methods: {}
        })
        // console.log(vm.$sayVue);
    </script>
</body>

</html>

2. 路由机制

vue-router是vue的一个插件,用来提供路由功能。通过路由的改变可以动态加载组件,达到开发单页面程序的目的。

  • 安装:
  • 方式一 : CDN引入
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.0-beta.7/vue.cjs.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/4.0.10/vue-router.cjs.js"></script>
  • 方式二:本地引入
<script src='vue.js'></script>
<script src='vue-router.js'></script>
  • 方式三 : cnpm下载
 cnpm install vue-router
  • 使用:在html文件中使用时需要引入vueRouter(先引入vue.js,在引入vueRouter)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <!-- 4.路由使用 -->
        <router-link to='/a'>组件1</router-link>
        <router-link to='/b'>组件2</router-link>
        <!-- 为组件加载提供容器或窗口 -->
        <!-- 实现了组件之间的动态加载 -->
        <router-view></router-view>
    </div>
    <script>
        // 1.注册组件
        let com1 = {
            data() {
                return {}
            },
            template: `
            <div>
                组件1
            </div>
            `
        }
        let com2 = {
            data() {
                return {}
            },
            template: `
            <div>
                组件2
            </div>
            `
        }
        // 2.定义路由
        let router = new VueRouter({
            routes: [
                {
                    path: '/',
                    redirect: '/a'    //重定向
                },
                {
                    path: '/a',       //路径
                    component: com1,  //路径对应的组件
                    name: 'com1',     //路由命名
                    alias: '/A'       //路由(path)别名
                },
                {
                    path: '/b',
                    component: com2,
                    name: 'com2'
                }
            ]
        })
        let vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 3.路由注册
            router: router
        })

    </script>
</body>

</html>

3. 动态路由匹配

需要把某种模式匹配到的所有路由,全部映射到同一个组件。

例如 : 有一个user组件,对于所有id不同的用户,都要使用这个组件来渲染,那么可以在vue-router的路由路径中使用动态路径参数来达到这个效果。

复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch $route 对象,或者使用组件内部的导航守卫

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <!-- 4.路由使用 -->
        <router-link to='/user/1001'>组件1</router-link>
        <router-link to='/b'>组件2</router-link>
        <!-- 为组件加载提供容器或窗口 -->
        <!-- 实现了组件之间的动态加载 -->
        <router-view></router-view>
    </div>
    <script>
        // 1.注册组件
        let com1 = {
            data() {
                return {
                    id: null
                }
            },
            template: `
            <div>
                组件1
                {{id}}
            </div>
            `,
            created() {
                this.id = this.$route.params.id
                // console.log(this.$route.params);
            },
            watch: {
                // 使用监听器,来监听路由对象变化
                $route(to, from) {
                    console.log('$route变化', to, from);
                }
            }
        }
        let com2 = {
            data() {
                return {}
            },
            template: `
            <div>
                组件2
            </div>
            `
        }
        // 2.定义路由
        let router = new VueRouter({
            routes: [
                {
                    path: '/user/:id',
                    component: com1,
                    name: 'user',
                    alias: '/A'
                },
                {
                    path: '/b',
                    component: com2,
                    name: 'com2'
                }
            ]
        })
        let vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 3.路由注册
            router: router
        })
    </script>
</body>

</html>

4. 嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
    <style>
        header {
            height: 50px;
            background-color: rgba(153, 235, 137, 0.8);
        }

        main {
            display: flex;
        }

        .left {
            width: 150px;
            border: 3px solid orange;
            height: 700px;
            margin: 10px 10px 0 0;
        }

        .right {
            flex: 1;
            /* width: calc(100%-150px); */
            border: 3px solid blue;
            height: 700px;
            margin-top: 10px;

        }
    </style>
</head>

<body>
    <div id="app">
        <header>我是网站头部</header>
        <main>
            <div class="left">
                <router-link to='/user'>用户管理</router-link><br>
                <router-link to='/student'>学生管理</router-link><br>
                <router-link to='/class'>班级管理</router-link>
            </div>
            <div class="right">
                <!-- 为组件加载提供容器/窗口 -->
                <!-- 实现了组件之间的动态加载 -->
                <router-view></router-view>
            </div>
        </main>
    </div>
    <script>
        // 1.注册组件
        let com1 = {
            data() {
                return {}
            },
            template: `
            <div>
                用户管理
            </div>
            `
        }
        let com2 = {
            data() {
                return {}
            },
            template: `
            <div>
                学生管理
                <div>
                    <router-link to='/student/grade'>成绩管理</router-link>
                    <router-link to='/student/register'>学籍管理</router-link>
                </div>
                <router-view></router-view>
            </div>
            `
        }
        let com3 = {
            data() {
                return {}
            },
            template: `
            <div>
                班级管理
            </div>
            `
        }
        let comGrade = {
            data() {
                return {}
            },
            template: `
            <div>
                成绩管理
            </div>
            `
        }
        let comRegister = {
            data() {
                return {}
            },
            template: `
            <div>
                学籍管理
            </div>
            `
        }
        // 2.定义路由
        let router = new VueRouter({
            routes: [
                {
                    path: '/user',
                    component: com1
                },
                {
                    path: '/student',
                    component: com2,
                    children: [
                        { path: 'grade', component: comGrade },
                        { path: 'register', component: comRegister }
                    ]
                },
                {
                    path: '/class',
                    component: com3
                }
            ]
        })
        let vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 3.路由注册
            router: router
        })

    </script>
</body>

</html>

5. 编程式导航

除了使用 <router-link> 创建 a 标签来定义导航链接,还可以借助 router 的实例方法,通过编写代码来实现。this.$router.push()跳转到指定路由,会向history栈添加一个新的记录,当用户点击浏览器回退按钮的时候,可以回到跳转前的url。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
    <style>
        header {
            height: 50px;
            background-color: rgba(153, 235, 137, 0.8);
        }

        main {
            display: flex;
        }

        .left {
            width: 150px;
            border: 3px solid orange;
            height: 700px;
            margin: 10px 10px 0 0;
        }

        .right {
            flex: 1;
            /* width: calc(100%-150px); */
            border: 3px solid blue;
            height: 700px;
            margin-top: 10px;

        }
    </style>
</head>

<body>
    <div id="app">
        <header>我是网站头部</header>
        <main>
            <div class="left">
                <router-link to='/user'>用户管理</router-link><br>
                <router-link to='/student'>学生管理</router-link><br>
                <router-link to='/class'>班级管理</router-link>
            </div>
            <div class="right">
                <!-- 为组件加载提供容器/窗口 -->
                <!-- 实现了组件之间的动态加载 -->
                <router-view></router-view>
            </div>
        </main>
    </div>
    <script>
        // 1.注册组件
        let com1 = {
            data() {
                return {}
            },
            template: `
            <div>
                用户管理
            </div>
            `
        }
        let com2 = {
            data() {
                return {}
            },
            template: `
            <div>
                学生管理
                <div>
                    <button @click='clickHandler'>成绩管理</button>
                    <button @click='clickHandler'>学籍管理</button>
                    <button @click='$router.go(-1)'>返回</button>
                </div>
                <router-view></router-view>
            </div>
            `,
            methods: {
                clickHandler(e) {
                    if (e.target.innerText == '成绩管理') {
                        // 使用this.$router.push完成编程式导航
                        // this.$router.push({ path: '/student/grade' })
                        if (this.$route.fullPath != '/student/grade') {
                            // this.$router.push({ name: 'grade' })
                            // this.$router.push({
                            //   name: 'grade',
                            //   params: {
                            //     id: 1001,
                            //     name: 'zs'
                            //   }
                            // })
                            this.$router.replace('/student/grade')
                        }

                    } else {
                        // this.$router.push({ path: '/student/register' })
                        if (this.$route.fullPath != '/student/register') {
                            // this.$router.push({ name: 'register' })
                            // 使用path跳转,并且使用query传递参数
                            this.$router.push({
                                path: '/student/register',
                                query: {
                                    id: 1002,
                                    name: 'ls'
                                }
                            })
                        }
                    }
                }
            }
        }
        let com3 = {
            data() {
                return {}
            },
            template: `
            <div>
                班级管理
            </div>
            `
        }
        let comGrade = {
            data() {
                return {}
            },
            template: `
            <div>
                成绩管理
            </div>
            `,
            created() {
                console.log('params', this.$route.params);
            }
        }
        let comRegister = {
            data() {
                return {}
            },
            template: `
            <div>
                学籍管理
            </div>
            `,
            created() {
                console.log('query', this.$route.query);
            }
        }
        // 2.定义路由
        let router = new VueRouter({
            // 修改路由模式
            // mode: 'history',
            routes: [
                {
                    path: '/user',
                    component: com1
                },
                {
                    path: '/student',
                    component: com2,
                    children: [
                        { path: 'grade', component: comGrade, name: 'grade' },
                        { path: 'register', component: comRegister, name: 'register' }
                    ]
                },
                {
                    path: '/class',
                    component: com3
                }
            ]
        })
        let vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 3.路由注册
            router: router
        })
    </script>
</body>

</html>

6. 路由组件传参

路由传递是指,从A页面跳转到B页面时,将A页面中的变量传递给B页面使用,传递参数的方式有两种 :

path-query 传参

使用path与query结合的方式传递参数时,参数会被拼接在浏览器地址栏中,并且刷新页面后数据也不会丢失。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <router-link to="/user">user</router-link>
        <router-link to="/manager">manager</router-link>
        <router-view></router-view>
    </div>
    <script>
        let user = {
            template: `
                <div @click="userHandler">普通用户,点击此处可跳转至管理员页面</div>
            `,
            data() {
                return {
                    list: "hello",
                    obj: {
                        name: 'tom',
                        age: 3
                    }
                }
            },
            methods: {
                userHandler() {
                    // 跳转
                    this.$router.push({
                        path: '/manager',
                        query: {
                            list: this.list,
                            obj: JSON.stringify(this.obj)
                        }
                    })
                }
            },
        }
        let manager = {
            template: `
                <div>管理员 {{$route.query.list}}  {{$route.query.obj}}</div>
            `
        }
        let router = new VueRouter({
            routes: [{
                path: '/user',
                component: user
            }, {
                path: '/manager',
                component: manager
            }]
        })
        new Vue({
            el: "#app",
            router
        })
    </script>
</body>

</html>

name-params 传参

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <router-link to="/user">user</router-link>
        <router-link to="/manager">manager</router-link>
        <router-view></router-view>
    </div>
    <script>
        let user = {
            template: `
                <div @click="userHandler">普通用户,点击此处可跳转至管理员页面</div>
            `,
            data() {
                return {
                    list: "hello",
                    obj: {
                        name: 'tom',
                        age: 3
                    }
                }
            },
            methods: {
                userHandler() {
                    // 跳转
                    this.$router.push({
                        name: 'manager',
                        params: {
                            list: this.list,
                            obj: JSON.stringify(this.obj)
                        }
                    })
                }
            },
        }
        let manager = {
            template: `
                <div>管理员 {{$route.params.list}}  {{$route.params.obj}}</div>
            `
        }
        let router = new VueRouter({
            routes: [{
                path: '/user',
                component: user,
                name: 'user'
            }, {
                path: '/manager',
                component: manager,
                name: 'manager'
            }]
        })
        new Vue({
            el: "#app",
            router
        })
    </script>
</body>

</html>

7. 路由模式

hash 模式

hash模式的工作原理是hashchange事件,可以在window监听hash的变化。我们在url后面随便添加一个#xx触发这个事件。

window.onhashchange = function(event){ console.log(event);

// 打印出一HashChangeEvent事件对象,在该对象内有newURL和oldURL

// location.hash中也有相关的信息

// 假设hash值是个颜色值,通过location.hash来获取到对应的hash值,然后设置页面中的某个元素的背景颜色来改变页面 }

history模式

把window.history对象打印出来可以看到里边提供的方法和记录长度 history对象内有back(),forword(),go()等方法 前进,后退,跳转操作方法:

history.go(-3);//后退3次

history.go(2);//前进2次

history.go(0);//刷新当前页面

history.back(); //后退

history.forward(); //前进

vue-router 使用的模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。如果不想要很丑的 hash,可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。不过这种模式要玩好,还需要后台配置支持。

hash路由和history路由的区别:

1.hash路由在地址栏URL上有#,而history路由没有会好看一点

2.进行回车刷新操作,hash路由会加载到地址栏对应的页面,而history路由一般就404报错了(刷新是网络请求,没有后端准备时会报错)。

3.hash路由支持低版本的浏览器,而history路由是HTML5新增的API。

4.hash的特点在于它虽然出现在了URL中,但是不包括在http请求中,所以对于后端是没有一点影响的,所以改变hash不会重新加载页面,所以这也是单页面应用的必备。

5.history运用了浏览器的历史记录栈,之前有back,forward,go方法,之后在HTML5中新增了pushState()和replaceState()方法(需要特定浏览器的支持),它们提供了对历史记录进行修改的功能,不过在进行修改时,虽然改变了当前的URL,但是浏览器不会马上向后端发送请求。

8. 导航守卫 -——路由的改变会触发导航守卫

组件内部守卫

//定义组件内部守卫
        // 5.1组件内部前置守卫
        beforeRouteEnter(to, from, next) {
            console.log('路由进入之前', to, from);
            // 手动调用next()方法,确保路由跳转成功
            next()
        },
        // 5.2组件内部更新守卫
        beforeRouteUpdate(to, from, next) {
            console.log('路由更新之前', to, from);
            this.id = to.params.id;
            next()
        },
        // 5.3组件内部后置守卫
        beforeRouteLeave(to, from, next) {
            console.log('路由离开之前', to, from);
        }

全局守卫

// 5.配置全局守卫
        // 5.1配置全局前置守卫
        router.beforeEach((to, from, next) => {
            console.log('全局前置守卫', to, from);
            next()
        })
        // 5.2配置全局后置守卫
        router.afterEach((to, from, next) => {
            console.log('全局后置守卫', to, from);
        })

路由独享守卫

let router = new VueRouter({
            routes: [
                {
                    path: '/user/:id',
                    component: com1,
                    name: 'user',
                    // 5.1配置路由独享守卫
                    beforeEnter(to, from, next) {
                        console.log('路由进入之前', to, from);
                        next()
                    }
                },
                {
                    path: '/b',
                    component: com2,
                    name: 'com2'
                }
            ]
        })

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值