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

路由原理(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);
                }
            });
        }
    });

完整代码

扫描二维码关注公众号,回复: 16712304 查看本文章

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>

猜你喜欢

转载自blog.csdn.net/m0_65491952/article/details/132491138