柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • 前端必备

  • 技术拓展

  • 前端技巧

  • Vue

    • Vue-认识
    • Vue-生命周期
    • Vue-选项
    • Vue-组件
    • Vue-插槽
    • Vue-指令
    • Vue-属性
    • Vue-路由
      • 路由导航
        • 声明式导航
        • 编程式导航
      • 路由传参
        • 声明式
        • 编程式
        • 组件props属性路由传参
        • Vue3
      • Redirect重定向
      • 路由激活样式
      • 路由嵌套
      • 命名视图
      • 路由监听
      • 导航守卫
    • Vue-状态管理
    • Vue-状态管理
    • Vue3-组合式(精简版)
  • 前端
  • Vue
柏竹
2022-09-18
目录

Vue-路由

让页面 构建单页应用变得简单 . 标签会根据不同url来显示不同的页面效果

CDN : https://lib.baomitu.com/vue-router/4.0.14/vue-router.cjs.js (opens new window)

API : https://router.vuejs.org/ (opens new window)

关键字 : router 、routes

脚手架 : Vue-Cli 路由应用

工作原理 :

前端路由 , 指的是 Hash 地址与组件之间的对应关系

  • 用户点击了页面上的路由链接

  • 导致了 URL 地址栏中的 Hash 值发生了变化

  • 前端路由监听了到 Hash 地址的变化

  • 前端路由把当前 Hash 地址对应的组件渲染都浏览器中

注意

  • js库引入顺序 优先引入vue后则引入vue-router(基于vue运行的)
  • 路由的参数传递 需要到 $route对象 (opens new window) 进行传递参数
  • router-link标签 渲染默认是 a标签 , 如有想渲染其他标签 , 可通过 tag属性值 为指定的标签名

应用步骤:

  1. 引入 vue 和 vue-router库

  2. 设置 HTML内容

    <div id="app">
        <!-- router-link 最终会被渲染成a标签 , to指定路由的跳转地址 -->
    	<router-link to="/users">用户管理</router-link>
    	<router-link to="/home">首页展示</router-link>
    	<!-- 路由匹配到的组件将渲染在这里 -->
    	<router-view></router-view>
    </div>
    
  3. 创建 路由对应的Vue组件的模板

    let Home = {
    	template: '<div>这是Home内容</div>'
    };
    let Users = {
    	template: '<div>这是用户管理内容</div>'
    };
    
  4. 配置路由规则 routes不建议更变 (在实例对象中 , 如果更变了名称则匹配不到该对象

    let routes = [
    	{ path: '/users', component: Users }
    	{ path: '/home', component: Home }
    ];
    
  5. 实例路由对象 router不建议更变 (在实例对象中 , 如果更变了名称则匹配不到该对象

    let router = new VueRouter({
        routes
    })
    
  6. router实例 挂载到 vue实例上

    new Vue({
    	el: '#app',
    	router
    })
    

示例

<div id="app">
    <!-- 2. 设置HTMl内容 -->
    <!-- router-link 最终会想渲染成a标签 , to指定路由的跳转地址 -->
    <router-link to="/home">主页</router-link>
    <router-link to="/top">热点</router-link>
    <router-link to="/abouts">关于</router-link>
    <!-- <显示的内容> -->
    <router-view></router-view>
</div>
<!-- 1. 引入库 -->
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<script>
    // 4. Vue组件
    let Home = {
        template:"<div>主页内容</div>"
    }
    let Top = {
        template:"<div>热点内容</div>"
    }
    let Abouts = {
        template:"<div>关于内容</div>"
    }
    
    // 3. 设置路由规则
    let router = new VueRouter({
        routes: [
            {path:"/home",component: Home },
            {path:"/top",component: Top },
            {path:"/abouts",component: Abouts }
        ]
    });
    
    // 5. 把router实例挂载到vue实例上
    new Vue({
        el: "#app",
        router
    });
</script>

# 路由导航

官方说明 : https://router.vuejs.org/ (opens new window)

# 声明式导航

路由的 to属性 可提高路由的利用和便捷

  1. 常规跳转 <router-link to="/aaa">aaa</router-link>

  2. 变量值 <router-link :to="aaa">aaa</router-link>

  3. 对象name跳转 <router-link :to="{name:'aaa'}">aaa</router-link>

  4. 对象path跳转 <router-link :to="{path:'/aaa'}">aaa</router-link>

  5. 带参数跳转 <router-link :to="{name:'aaa',params:{id:1,name:'张三'}}">aaa</router-link>

示例

    <div id="app">
        <!-- 常规 -->
        <router-link to="/aaa">aaa</router-link>
        <!-- 变量 -->
        <router-link :to="bbb">bbb</router-link>
        <!-- 对象name -->
        <router-link :to="{name:'ccc'}">ccc</router-link>
        <!-- 对象path -->
        <router-link :to="{path:'/ddd'}">ddd</router-link>
        <!-- 带参数跳转 -->
        <router-link :to="{name:'eee',params:{id:1,name:'张三'}}">eee</router-link>
        <br>
        <router-view></router-view>
    </div>
    ...
    <script>
        let AAA = {
            template:'<div>AAA</div>'
        }
        let BBB = {
            template:'<div>BBB</div>'
        }
        let CCC = {
            template:'<div>CCC</div>'
        }
        let DDD = {
            template:'<div>DDD</div>'
        }
        let EEE = {
            template:'<div>EEE<br>参数: {{$route.params.id}} : {{$route.params.name}} </div>'
        }
        
        let router = new VueRouter({
            routes:[{
                path:"/aaa",
                component: AAA
            },{
                path:"/bbb",
                component: BBB
            },{
                name:"ccc",
                path:"/ccc",
                component: CCC
            },{
                path:"/ddd",
                component: DDD
            },{
                name:"eee",
                path:"/eee",
                component: EEE
            }]
        })
        new Vue({
            el:"#app",
            data:{
                bbb:'/bbb'
            },
            router
        })
    </script>

# 编程式导航

以 点击事件形式 来点击某一标签 , 实现路由跳转功能

关键字:this.$router.push(...)

在 Vue容器添加方法用于 事件响应 , 执行 this.$router.push对象

<方法名>() {
    this.$router.push({
        path:<路由地址>
            });
            }

也可通过以下方式进行导航

import {useRouter} from "vue-router";
const router = useRouter();
// 事件触发
router.push(Object);

示例(按钮实现路由AAA

<div id="app">
<router-link to="/aaa">aaa</router-link>
<button @click="toAAA">aaa编程式</button>
<router-view></router-view>
</div>
...
<script>

let AAA = {
  template:'<div>AAA</div>'
}

let router = new VueRouter({
  routes:[{
    path:'/aaa',
    component:AAA
  }]
});

new Vue({
  el:"#app",
  data:{},
  methods:{
    toCCC() {
      this.$router.push({
        path:"/aaa"
      });
    }
  },
  router
});
</script>

当你点击 <router-link> 时 , 这个方法会在内部调用 , 所以说 , 点击 <router-link :to="..."> 等同于调用 router.push(...) .

# 路由传参

动态路由 是 通过在跳转过程对参数的一个携带过程 , 在当中有两种方式进行传递数据

  • 原生URL
  • 动态路由Path携带 (REST风格)

# 声明式

  1. 设置HTML内容 , 并引入参数 (假如传递参数 : =={name: '张三', age: 23}==

    <!-- 原生URL传参 -->
    <router-link to="/item?name=张三&age=23">张三1</router-link>
    <!-- 动态路由传参 -->
    <router-link to="/item/张三/23"></router-link>
    
  2. 动态路由规则 动态参数进行接收 , 接收方式 :<参数名> (参数的属性名称随意

    new VueRouter({
        routes:[
            {path:'/item/:name/:age',component: ...}
        ]
    })
    

    **PS:**原生URL传递无需经通过第二步骤进行 Path路由地址的设置

  3. 三种传递方式接收各有不同 (因 $route对象 (opens new window) 存储参数位置不一样

  • 原生URL : ==this.$route.query.<参数名>==
  • 动态路由 : ==this.$route.params.<参数名>==
  • 组件传递 : 点击跳转

**PS:**路由跳转时可在组件中添加 update()函数 , 在DOM重新渲染后 , 对数据进行打印

示例:

<div id="app">
    <router-link to="/item?id=23">小明</router-link>
    <router-link to="/item?id=23&name=小华">小华</router-link>
    <router-link to="/item/33/小军">小军</router-link>
    <router-view></router-view>
</div>
....
<template id="show">
    <div>
        <p>传递的数据查看</p>
        <ul>
            <li>params.id: {{this.$route.params.id}}</li>
            <li>params.name: {{this.$route.params.name}}</li>
            <li>params.age: {{this.$route.params.age}}</li>
            <li>query.id: {{this.$route.query.id}}</li>
            <li>query.name: {{this.$route.query.name}}</li>
            <li>query.age: {{this.$route.query.age}}</li>
        </ul>
    </div>
</template>
<script>

    let Items = {
        template: "#show",
        // DOM 重新渲染完成后被调用 (用于测试
        updated() {
            console.log(this.$route);
        }
    }

    let router = new VueRouter({
        routes: [
            {path: '/item/:id', component: Items},
            {path: '/item/:id/:name/:age', component: Items}
        ]
    })

    new Vue({
        el: "#app",
        router
    })
</script>

# 编程式

跳转方

const router = useRouter();

// 事件触发
router.push({
    path: '/user/list',
    // 传递的参数
    query: {...}
});

接收方

const route = useRoute();
console.log(route.query)

# 组件props属性路由传参

vue-router 允许在路由规则中开启 props 传参 , 才能以组件的形式进行接收参数

{ path: '/product/:id', component: Product, props: true }
<template>
    <h1>Product组件</h1>
    <!-- 获取动态的id值 -->
    <p>{{id}}</p>
</template>

<script>
    export default {
//   组件的名称
        name: 'Product',
        props : [id]
    }
</script>

# Vue3

不同页面传递数据

  1. url 跳转url携带query
  2. url 衔接形式(/team/:id)
  3. hash
  4. 全局变量

# Redirect重定向

当某个页面被强制中转时 , 采用 redirect 进行路由重定向

关键字:redirect

步骤: 在原有的路由组件里 添加新 属性 ==redirect : <路由地址>==

routes:[{
path : <默认路由地址>,
redirect : <重定向路由地址>
  }]

实例:(将 /bbb 路由强制中转至 /aaa

<div id="app">
<router-link to="/aaa">aaa</router-link>
<router-link to="/bbb">bbb</router-link>
<router-link to="/ccc">ccc</router-link>
<router-view></router-view>
</div>
....
<script>
let AAA = {
  template:'<div>AAA</div>'
}
let BBB = {
  template:'<div>BBB</div>'
}
let CCC = {
  template:'<div>CCC</div>'
}

let router = new VueRouter({
  routes:[{
    path:'/aaa',
    component:AAA
  },{
    path:'/bbb',
    redirect:"/aaa",
    component:BBB
  },{
    path:'/ccc',
    component:CCC
  }]
});

new Vue({
  el:"#app",
  data:{},
  router
});
</script>

# 路由激活样式

路由激活会产生样式 ==calss="router-link-exact-active router-link-active"== , 该类会伴随着激活出现

<a href="..." class="router-link-exact-active router-link-active">切换页面1</a>

以上的 激活样式的系统类名 , 一般不建议直接覆盖系统默认的样式 , 因此官方提供有方式修改其样式

自定义路由激活class样式 :在路由规则中 添加 linkActiveClass属性其值为 class名

路由激活渲染示例: (la-active为自定义样式的class名)

<a href="..." class="router-link-exact-active la-active">切换页面1</a>

# 路由嵌套

路由嵌套和二级菜单 类似 , 但二级路由的嵌套是通过组件模板中再次添加路由 , 从而实现路由嵌套的效果

关键字:children

应用步骤:

  1. 在一级路由组件的 component模板中 添加二级路由的模板
  2. 在一级路由的路由规则里 添加属性 children数组
  3. 在 childern数组 中配置二级路由规则与模板
let routes = [{
    path: <一级路由地址>,
        component: <一级路由模板>,
            children: [
            {path: <二级路由地址>, component: <二级路由模板>}
                [,{path: <二级路由地址>, component: <二级路由模板>}...]
                ]
                }
                [,{path:  <一级路由地址>, component: <一级路由模板2>}...]
                ]

注意

该路由为子路由 , 那么无需再次编辑一级路径地址 , 也可无需添加反斜杠

示例1

<div id="app">
<router-link to="/home">主页</router-link>
<router-link to="/music">音乐</router-link>
<router-view></router-view>
</div>
...
<script>
let Home = {
  template:'<div>Home---</div>'
}
let Music = {
  template: '<div>MUSIC---' +
      '<router-link to="/music/pop">流行</router-link>' +
      '<router-link to="/music/cal">古典</router-link>' +
      '<router-view></router-view>' +
      '</div>'
}
//二级组件
let Detail = {
  template: '<div>Detail--{{$route.params.name}}</div>'
}

let router = new VueRouter({
  routes:[{
    name:'default',
    path:'/',
    component: Home
  },{
    name:'home',
    path:'/home',
    component: Home
  },{
    name:'music',
    path:'/music',
    component: Music,
    // 子路由
    children:[{
      path:'/music/:name',
      component: Detail
    }]
  }]
});

new Vue({
  el:"#app",
  data:{},
  router
});
</script>

示例2

<style>

    .box-red {
        background: red;
        height: 200px;
    }

    .box-blue {
        background: blue;
        height: 200px;
    }

    .box-green {
        background: green;
        height: 200px;
    }
</style>
....
<div id="app">
    <router-link to="/one">路由页面1</router-link>
    <router-link to="/two">路由页面2</router-link>
    <router-view></router-view>
</div>
....
<template id="one">
    <div class="box-green">
        <p>一级one</p>
        <router-link to="/one/onesub1">路由页面1</router-link>
        <router-link to="/one/onesub2">路由页面2</router-link>
        <router-view></router-view>
    </div>
</template>
<template id="onesub1">
    <div class="box-red">
        <p>二级one</p>
    </div>
</template>
<template id="onesub2">
    <div class="box-blue">
        <p>二级one</p>
    </div>
</template>
<template id="two">
    <div class="box-green">
        <p>一级two</p>
    </div>
</template>
<script>
    let One = {
        template: "#one"
    }
    let Two = {
        template: "#two"
    }
    let OneSub1 = {
        template: "#onesub1"
    }
    let OneSub2 = {
        template: "#onesub2"
    }

    let routes = [
        {path: "/", redirect: '/one'},
        {
            path: "/one",
            component: One,
            children: [
                {path: "onesub1", component: OneSub1},
                {path: "onesub2", component: OneSub2}
            ]
        },
        {path: "/two", component: Two}
    ]

    let router = new VueRouter({
        routes
    })

    new Vue({
        el: "#app",
        router
    })
</script>

# 命名视图

命名视图 是让不同出口显示不同内容(和 具名插槽 类似)

当路由地址被匹配时同时制定多个出口 , 并且每个出口显示的内容不一样

应用步骤:

  1. 为 router-view标签 添加 name属性(指定出口类型的模板
  2. 在 路由规则配置中 将路由模板从 component属性 改为 components属性 (添加模板组
let router = new VueRouter({
    routes: [{
        path: <路由地址>,
            // key值 对应路由出口的 name属性值
            components: {
                <key>: <模板1>
                    [,<key>: <模板2>...]
                    }
                    }]
                    })

示例

<div id="app">
    <router-view></router-view>
    <router-view name="name1"></router-view>
    <router-view name="name2"></router-view>
</div>
....
<template id="one">
    <div>
        <p>第一个模板</p>
    </div>
</template>
<template id="two">
    <div>
        <p>第二个模板</p>
    </div>
</template>
<script>
    let One = {
        template: "#one"
    }
    let Two = {
        template: "#two"
    }

    // 首次打开网页URL路由地址为 '/'
    let routes = [{
        path: "/",
        components: {
            name1: One,
            name2: Two
        }
    }]

    let router = new VueRouter({
        routes
    })

    new Vue({
        el: "#app",
        router
    })
</script>

渲染结果:

<div id="app">
    <!---->
    <div><p>第一个模板</p></div>
    <div><p>第二个模板</p></div>
</div>

三个出口:

  1. 未指定出口名称因此没有显示
  2. 指定出口名称为 name1 -> One
  3. 指定出口名称为 name2 -> Two

# 路由监听

[watch属性](/vue/03/#watch 数据监听) 不仅仅能够监听数据的变化 , 还能够监听路由地址的变化

监听方式:

watch: {
    "$route.path"(newV, oldV) {
        console.log(newV, oldV)
    }
}

# 导航守卫

导航守卫可以控制路由的访问权限 . 全局导航守卫会拦截每个路由规则 , 从而对每个路由进行访问权限的控制

router.beforeEach 注册一个全局前置守卫 :

// to: 目标路由 & from 来自路由 & 执行跳转路由(下一个)
router.beforeEach((to, from, next) => {
    if (to.path === '/main' && !isAuthenticated) {
        next('/login')
    }
    else {
        next()
    }
})

在守卫方法中如果声明了 next 形参,则必须调用 next() 函数 , 否则不允许用户访问任何一个路由!

  • 直接放行 : next()
  • 强制其停留在当前页面 : next(false)
  • 强制其跳转到登录页面 : next('/login')
#Vue

← Vue-属性 Vue-状态管理→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式