Vue -路由

后端路由,网站的所有超链接都是URL地址,所有URL地址都对应服务器上对应资源

前端路由,对于单页面程序来说,主要通过URL中的hash(#)来实现不同页面之间的切换,同时hash有个特点,HTTP请求中不会包含hash相关的内容,所以单页面程序中的页面跳转主要用hash实现,像a链接的锚点就是hash

单页面程序中,这种通过hash改变来切换页面的方式,称为前端路由

Vue构造单页面应用需要使用Vue Router,它是是Vue官方的路由管理器,和Vue核心深度集成,使用前要导包vue-router

基本应用,示例

<body>
<div id="app">
    <a href="#/login">登录</a>
    <a href="#/register">注册</a>
    <!--vue-router提供的元素,专门用来当作占位符,将来路由规则匹配到的组件会展示到这里-->
    <router-view></router-view>
</div>

<script>
    //组件的模版对象
    var login = {
        template: '<h3>登录界面</h3>'
    }
    var register = {
        template: '<h3>注册界面</h3>'
    }

    //创建一个路由对象,为构造参数传递一个配置对象
    var vueRouter = new VueRouter({
        //配置对象中的routes是路由匹配规则,每个路由规则都是一个对象
        routes: [
            {path: '/login', component: login},
            {path: '/register', component: register}
        ]
    })

    var vm = new Vue({
        el: '#app',
        //通过router属性注入路由对象,使整个应用都路由功能
        router: vueRouter
    })
</script>
</body>

导入vue-router包后,在window全局对象中,就有了一个路由的构造函数,叫VueRouter,在new路由对象时可为构造函数传递一个配置对象

配置对象中routes为路由规则数组,每个路由规则都是一个对象,这个对象有两个必须的属性:
属性1 path,表示监听哪个路由的链接地址
属性2 component,表示如果路由是前面匹配到的path ,则展示component属性对应的那个组件
注意: component 的属性值,必须是一个 组件的模板对象, 不能是组件的引用名称

过程一览:点击a标签(a标签地址要加#)后,URL地址会变修改,修改后的地址将被Vue实例上的路由对象监听到,然后进行路由规则的匹配,匹配上了就展示对应的组件,展示区域就是<router-view>

 

可用router-link标签来取代a标签,这样就可以省略#的书写,router-link在页面上默认会被渲染为一个a标签

即使通过tag属性变成了其他标签,依旧可以点击

<router-link to="/login">登录</router-link>

 

重定向到某个组件,匹配到根路径时重定向到登录页面,这里的redirect和后端的redirect是不同的,后端的redirect是服务器实现的302重定向,而这里的重定向应该只是组件的切换

{path:'/',redirect:'/login'}

 

设置选中路由高亮,被点击的router-link标签会被添加两个类,可以对router-link-active添加样式

如果想修改这个类的名字,可以通过路由的构造选项 linkActiveClass 来全局配置,甚至可以改成bootstrap的类

 

为路由切换添加动画

将<router-view>标签用<transition>包裹,之后一切按老套路设置

 

路由传参

query方式传递给路由参数,如果在路由中使用查询字符串(也就是问号传参方式)给路由传参,则不需要修改路由规则的path属性,照样能匹配上

组件实例会有个$route属性,是个对象,对象中有query对象,存放的就是查询字符数据

<div id="app">
    <router-link to="/login?id=10&name=Sam">登录</router-link>
    <router-link to="/register">注册</router-link>
    <router-view></router-view>
</div>

<script>
//组件的模版对象
var login = {
      //this可以省略,就像使用组件data数据时可直接调用属性名
  template: '<h3>登录界面,这是查询字符串的数据:{{this.$route.query}}</h3>',
  created() { //组件生命周期钩子
     console.log(this.$route)
  }
}

 

params方式传参

如果匹配规则是占位符形式

var vueRouter = new VueRouter({
    routes: [
        {path: '/login/:id/:name', component: login},
        {path: '/register', component: register}
    ]
})

 那传参就要以这种方式,并且要多少个参数就要传多少个,否则匹配不上

<router-link to="/login/18/Sam">登录</router-link>

此时传来的数据不在query中,而在params中

所以获取数据时只需要this.$route.params即可

 

路由嵌套

使用children属性实现子路由,不使用children则小组件显示时大组件会消失,并且地址栏是直接显示/login而不是/index/login

<body>
<div id="app">
    <router-view></router-view><!--大组件渲染的地方-->
</div>
<template id="templ">
    <div>
        <h1>++++++Index++++++</h1>
        <router-link to="/index/login">登录</router-link>
        <router-link to="/index/register">注册</router-link>
        <router-view></router-view><!--小组件渲染地方-->
    </div>
</template>

<script>
    //index为大组件,里面有两个小组件login和register
    var index = {
        template: '#templ'
    }
    var login = {
        template: '<h3>登录界面</h3>',
    }
    var register = {
        template: '<h3>注册界面</h3>'
    }

    //创建一个路由对象
    var vueRouter = new VueRouter({
        routes: [
            {
                path: '/index',
                component: index,
                //子路由的path前面不要带 / ,否则永远以根路径开始请求
                children: [
                    {path: 'login', component: login},
                    {path: 'register', component: register}
                ]
            }
        ]
    })

    var vm = new Vue({
        el: '#app',
        router: vueRouter
    })
</script>
</body>

 

 

命名视图实现经典布局

有时候想同时同级展示多个组件,而不是嵌套展示,这个时候命名视图就派上用场

可以在界面中拥有多个单独命名的组件,而不是只有一个单独的出口,如果 router-view 没有设置名字,那么默认为 default

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vue-router.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .header {
            height: 60px;
            background: #2c323b;
        }

        .container {
            display: flex;
            height: 500px;
        }

        .left {
            flex: 1;
            background: #ff4200;
        }

        .main {
            flex: 4;
            background: #3538ff;
        }
    </style>
</head>
<body>
<div id="app">
    <router-view></router-view>
    <div class="container">
        <router-view name="left"></router-view>
        <router-view name="mainBox"></router-view>
    </div>
</div>
<script>
    var header = {
        template: '<div class="header">header头部区域</div>'
    }
    var left = {
        template: '<div class="left">left侧边栏区域</div>',
    }
    var mainBox = {
        template: '<div class="main">mainBox主体内容区域</div>'
    }

    //创建一个路由对象
    var vueRouter = new VueRouter({
        routes: [
            {   //使用components来指定多个组件,default为没name属性的那个router-view标签
                path: '/', components: {
                    'default': header,
                    'left': left,
                    'mainBox': mainBox
                }
            }
        ]
    })

    var vm = new Vue({
        el: '#app',
        router: vueRouter
    })
</script>
</body>

结构构建好后再加上样式

猜你喜欢

转载自www.cnblogs.com/Grani/p/9643979.html