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

本文详细介绍了Vue2中的路由原理,包括哈希模式(基于URLhash变化)的实现,路由的安装与使用,参数传递(查询参和路由参数),嵌套路由以及路由守卫的完整示例。同时对比了hash和history模式的工作方式。
摘要由CSDN通过智能技术生成

路由原理(hash)

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

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

Video_2023-08-25_110736

<!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改变后 立刻发起请求,响应整个页面,渲染整个页面比路由的跳转用户体验更好
<!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)

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

路由跳转

路由的跳转有两种方式:

  1. 使用标签
<router-link to='/login'></router-link>
  1. 编程式路由,使用js
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属性匹配。
    <router-link :to="{path:'/login',query:{id:queryid}}"></router-link>
    
    或者
    <router-link :to="{name:'login',query:{id:queryid}}"></router-link>
    
    或者
    this.$router.push({path:'/login',query:{id:queryid}});
    
    • 取参
  • 路由参
    • 配置路由规则
    var router = new VueRouter({
    routers:[
        // 需要在配置路由规则时,使用冒号指定参数
        {name:'login',path:'/login/:id',component:LoginVue}
    ]
    });
    
    • 配置。意:在这里path和params两个参数不能同时使用
    <router-link :to="{name:'login',params:{id:paramId}}"></router-link>
    
    或者
    this.$router.push({name:'login',params:{id:this.paramId}});
    
    • 取参
    this.$route.params.id;
    
    注意:相同路由,但参数不同。造成页面不刷新的问题。
    <router-view :key="$route.fullPath"></router-view>
    

嵌套路由

  1. 路由间有层级关系。他们在模板中也有嵌套关系。
  2. 可以一次性配置多个路由。
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 app01 = new Vue({
    el:'#app',
    template:`
        <div>
        	<router-view></router-view>
        </div>
    `,
    router
});

路由守卫

  • 可以做验证判断
  • 使用路由的钩子函数beforeEach实现
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

<!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>
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

困困的小熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值