从上帝视角俯瞰vue2路由(简单易懂)

文章目录

路由原理(hash)

单页应用的路由模式有两种

  1. 哈希模式(利用hashchange 事件监听 url的hash 的改变)
  • 哈希模式的原理
    • 哈希模式下,哈希部分的改变不会触发浏览器向服务器发送新的请求,所有的路由都会发送到同一个HTML文件。这意味着,即使在前端进行页面导航,服务器也不需要额外的配置,因为所有的路由都会被前端路由器处理。

Video_2023-08-25_110736

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        头部
        <router-link to="ger">个人</router-link>
        <router-link to="login">登录</router-link>
        <button @click="logins">登录</button>
        <button @click="gers">个人</button>
        <br>
        <button @click="gersid">apl 带参数的个人</button>
        <router-link :to="{path:'/login',query:{id:queryid}}">带查询参数的登录link</router-link>
        <br>
        <router-link  :to="{name:'login',params:{id:queryid}}">路由参登录link</router-link>
        <button @click="gersidhs">apl 带参数的个人</button>
        <hr>
        <!-- 下面是路由出口 -->
        <router-view :key="$route.fullPath"></router-view>
        尾部
    </div>
</body>
<script src="../js/vue2.7.js"></script>
<script src="../js/vue-router.js"></script>

<script>
    //安装路由,前提要导入路由js
    Vue.use(VueRouter)

    //创建一个登录子组件
    var login={
        template:`
            <div>
                登录页面    
            </div>
        `,
        mounted(){
            console.log(this.$route.query.id);
            console.log(this.$route.params.id);
        }
    }

    //创建一个登录子组件
    var ger={
        template:`
            <div>
                个人页面    
            </div>
        `,
        mounted(){
            console.log(this.$route.query.id);
            console.log(this.$route.params.id);
        }
    }

    //创建路由配置实例,主要实现 路径和子组件时间的映射
    var myrouter =new VueRouter({
        routes:[
            {path:'/login',name:'login',component:login},
            {path:'/ger',name:'ger',component:ger}
        ]
    })

    var app=new Vue({
        el:"#app",
        router:myrouter,
        data(){
            return{
                queryid:1
            }
        },
        methods:{
            logins(){
                this.$router.push({path:'/login'});
            },
            gers(){
                this.$router.replace({
                    path:'/ger'
                })
            },
            gersid(){
                this.$router.push({path:'/ger',query:{id:this.queryid}})
            },
            gersidhs(){
                this.$router.push({name:'ger',params:{id:"6"}});
            }
        }

    })

</script>
</html>
  1. history模式(使用此模式需要后台配合把接口都打到我们打包后的index.html上)

    • hash模式的原理:
      • 核心是锚点值的改变,我们监听到锚点值改变了就去局部改变页面数据,不做跳转。跟传统开发模式url改变后 立刻发起请求,响应整个页面,渲染整个页面比路由的跳转用户体验更好
java 复制代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>单页面跳转的原理</title>
    </head>
    <body>
        <a href="#/login">登录</a>
        |
        <a href="#/register">注册</a>
        <div id="app"></div>

        <script type="text/javascript">
            var appDom = document.getElementById("app");
            window.addEventListener("hashchange",function(){
                console.log(location.hash);
                switch(location.hash){
                    case '#/login':
                    appDom.innerHTML = "登录";
                    break;
                    case '#/register':
                    appDom.innerHTML="注册";
                    break;
                }
            })
        </script>
    </body>
</html>

路由安装和使用(vue2)

  • 导入路由插件
java 复制代码
<script src="js/vue-router.js" type="text/javascript" charset="utf-8"></script>
  • 安装路由插件到Vue中
java 复制代码
Vue.use(VueRouter);
  • 创建VueRouter对象
java 复制代码
var Login = Vue.extends({
    template:`
        <div>
        我是登录页面
        </div>
    `
});
// 创建VueRouter对象,并配置路由
var myRouter = new VueRouter({
    // 配置路由
    routes:[
        // 指定路由链接、路由名称、路由页面(组件)
        {path:'/login',name:'login',component:Login}
    ]
});
  • 使用路由
java 复制代码
var myvue = new Vue({
    el:'#app',
    // 引入到vue 实例中,并在模板中使用<router-view>
    router:myRouter,
    template:`
        <div>
        	头部
        	<router-view></router-view>
        	尾部
        </div>
    `
})

路由跳转

路由的跳转有两种方式:

  1. 使用标签
java 复制代码
<router-link to='/login'></router-link>
  1. 编程式路由,使用js
java 复制代码
this.$router.push({path:'/login'});
this.$router.replace({path:'/login'});

说明:

  • this.$router.push(); 会向history中添加记录
  • this.$router.replace();不会向history中添加记录。
  • this.$router.go(-1)常用来做返回上一个地址。

路由中的对象:

  1. this.$route 路由信息对象,只读。
  2. this.$router 路由操作对象,只写。

路由的传参和取值

  • 查询参

    • 配置。查询参可以和path属性匹配,也可以和name属性匹配。
    java 复制代码
    <router-link :to="{path:'/login',query:{id:queryid}}"></router-link>

    或者

    java 复制代码
    <router-link :to="{name:'login',query:{id:queryid}}"></router-link>

    或者

    java 复制代码
    this.$router.push({path:'/login',query:{id:queryid}});
    • 取参
  • 路由参

    • 配置路由规则
    java 复制代码
    var router = new VueRouter({
    routers:[
        // 需要在配置路由规则时,使用冒号指定参数
        {name:'login',path:'/login/:id',component:LoginVue}
    ]
    });
    • 配置。意:在这里path和params两个参数不能同时使用
    java 复制代码
    <router-link :to="{name:'login',params:{id:paramId}}"></router-link>

    或者

    java 复制代码
    this.$router.push({name:'login',params:{id:this.paramId}});
    • 取参
    java 复制代码
    this.$route.params.id;

    注意:相同路由,但参数不同。造成页面不刷新的问题。

    java 复制代码
    <router-view :key="$route.fullPath"></router-view>

嵌套路由

  1. 路由间有层级关系。他们在模板中也有嵌套关系。
  2. 可以一次性配置多个路由。
java 复制代码
var Nav = {
        template:`
            <div>
                <router-link :to="{name:'nav.index'}">首页</router-link>
                <router-link :to="{name:'nav.personal'}">个人中心</router-link>
                <router-link :to="{name:'nav.message'}">消息</router-link>
                <router-view></router-view>
            </div>
        `
    };
    var Index = {
        template:`
            <div>
                首页
            </div>
        `
    }
    var Personal = {
        template:`
            <div>
                个人中心
            </div>
        `
    }
    var Message = {
        template:`
            <div>
                消息
            </div>
        `
    }
java 复制代码
var router = new VueRouter({
            routes:[
                {
                    path:'/nav',
                    name:'nav',
                    component:Nav,
                    children:[
                        {path:'',redirect:'/nav/index'},
                        {path:'index',name:'nav.index',component:Index},
                        {path:'personal',name:'nav.personal',component:Personal},
                        {path:'message',name:'nav.message',component:Message}
                    ]
                },
                {
                    path:'',
                    redirect:'/nav'
                }
            ]
        });
java 复制代码
var app01 = new Vue({
    el:'#app',
    template:`
        <div>
        	<router-view></router-view>
        </div>
    `,
    router
});

路由守卫

  • 可以做验证判断
  • 使用路由的钩子函数beforeEach实现
java 复制代码
let app = new Vue({
        el: '#app01',
        router:myRouter,
        mounted() {
            this.$router.beforeEach((to,from,next)=>{
                console.log(to);
                if(to.path=='/nav/index'){
                    // 跳转到目标路由
                    next();
                }else{
                    setTimeout(function(){
                        next();
                    },2000);
                }
            });
        }
    });

完整代码

Video_2023-08-28_105346

java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-view :key="$route.fullPath"></router-view>
    </div>
</body>
<script src="../js/vue2.7.js"></script>
<script src="../js/vue-router.js"></script>
<script>
    //安装路由,前提要导入路由js
    Vue.use(VueRouter)

    //导航子组件,以及路由
    var nav = {
        template:`
            <div>
                <router-link :to="{name:'nav.index'}">首页</router-link>
                <router-link :to="{name:'nav.personal'}">个人中心</router-link>
                <router-link :to="{name:'nav.message'}">消息</router-link>
                <router-view></router-view>
            </div>
        `
    };
    var Index = {
        template:`
            <div>
                首页
            </div>
        `
    }
    var Personal = {
        template:`
            <div>
                个人中心
            </div>
        `
    }
    var Message = {
        template:`
            <div>
                消息
            </div>
        `
    }

    var router=new VueRouter({
        routes:[
            {
                path:'/nav',
                name:'nav', 
                component:nav,
                children:[
                    {path:'',redirect:'/nav/index'},
                    {path:'index',name:'nav.index',component:Index},
                    {path:'personal',name:'nav.personal',component:Personal},
                    {path:'message',name:'nav.message',component:Message}
                ]
            },
            {
                path:'',
                redirect:'/nav'
            }
        ]
    });

    var app=new Vue({
        el:"#app",
        router,
        mounted() {
            this.$router.beforeEach((to,from,next)=>{
                console.log(to);
                if(to.path=='/nav/index'){//判断跳转的是否是首页,否延时2秒后跳转
                    // 跳转到目标路由
                    next();
                }else{
                    setTimeout(function(){
                        next();
                    },2000);
                }
            });
        }
    });
</script>
</html>
相关推荐
zqx_711 分钟前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己28 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称1 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色1 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2341 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河1 小时前
CSS总结
前端·css
BigYe程普2 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
余生H2 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍2 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
Mudrock__2 小时前
前后端传输文件(图片)
vue·.net