• Vue(路由插件)


    一、介绍路由

    1. 路由就是一组key-value的对关系,多个路由需要经过路由器进行管理

    2. 主要应用在SPA(单页面应用) 

    • 在一个页面展示功能之间的跳转

    特点:

    • 当跳转时候不进行页面刷新
    • 路径随着变化
    • 展示区变化但是不开启新的页签      

     3. 跳转规则:

    • 点击指定模块 
    • 路径变化(加后缀)
    • router监测:路径变化
    • 展示对应的路径的组件内容
    • 如果不存在路由存储的路径,页面就不会进行展示

     二、路由使用(十之前使用的都是声明式路由导航)

    1. 安装路由

    vue-router4(默认版本)只能在vue3中使用

    vue-router3 对应 vue2

    此处使用vue2进行了解,所以基于vue2进行安装

    npm i vue-router@3

    2. 插件的引入和使用(入口文件中)

    1. // 引入vue-router
    2. import VueRouter from 'vue-router'
    3. //使用vue-router
    4. Vue.use(VueRouter)

    3.配置路由

    • 引入安装的路由
    • 引入各个组件
    • 暴露路由器:此处注意配置routes
    1. //该文件专门创建整个应用中路由器
    2. import VueRouter from "vue-router";
    3. // 引入组件
    4. import About from '../commponents/About'
    5. import Home from '../commponents/Home'
    6. // 创建并暴露一个路由器
    7. export default new VueRouter({
    8. routes: [
    9. {
    10. path: '/about',
    11. component:About
    12. },
    13. {
    14. path: '/home',
    15. component:Home
    16. },
    17. ]
    18. })

    4. 声明式导航进行展示(简单实现情况下使用)

    • router-link链接包裹需要导航的按钮或者模块(可以理解router-link就是a标签
    • to:表示从当前页面跳转到哪个组件中去:值是路由路径,因为to中的值都是js表达式,所以进行绑定
    • active-class:导航被激活时候的样式

    在不使用传参和name属性的情况下都不需要对to进行绑定

      class="list-group-item" active-class="active" to="/about">About
    • 链接路由路径之后进行展示:利用标签放在需要展示的部分
      

     

    三、使用路由的注意点

    1. 关于组件分类

    • 一般(公共)组件:放在components文件夹
    • 路由组件:由路由器渲染的组件叫做路由组件放在pages文件夹

    2. 路由组件的销毁和挂载

    • a组件切换成b组件
    • a组件被销毁
    • b组件完成挂载

    3. 路由组件都出现了路由和路由器

    • 路由就是自身相关的路由规则(每个路由都不同)
    • 路由器在每个路由组件理都有并且相同
    1. //配置代码的挂载之后取得路由
    2. //a路由组件的
    3. window.aboutRoute = this.$route
    4. window.aboutRouter = this.$router
    5. //b路由组建的
    6. window.homeRoute = this.$route
    7. window.homeRouter = this.$router

     四、嵌套路由(配置使用区别于基本使用)

    1. 基于安装路由并使用插件的基础上进行配置

    此处多出来一个新的子级配置项:children

    配置每个路由的路径和组件方式还是相同

    1. routes: [
    2. // about和home是一级路由
    3. {
    4. path: '/about',
    5. component:About
    6. },
    7. {
    8. path: '/home',
    9. component: Home,
    10. // 二级路由规则
    11. children: [
    12. {
    13. path: 'news',
    14. component:News
    15. },
    16. {
    17. path: 'message',
    18. component:Message
    19. },
    20. ]
    21. },
    22. ]

    2. 跳转路由:带爹路径

    • 在路由组件中进行链接子级路由
    • 注意此处router-link链接跳转的to不能直接写子级路径,需要带父级路径
     class="list-group-item " active-class="active" to="/home/news">News
     

    五、路由传参query

    • 当进行路由进行跳转的时候,如果某个路由组件需要传递参数,这时候就可以用到参数链接
    • 开发中:路由的嵌套一般只会到三四级,不会更多
    • 注意:如果一个组件中存在多个消息,每个消息都需要传递出来一个新的展示组件,这时候使用路由组件就比较麻烦

    1. 父组件进行遍历获取自身数据并展示在页面

    1. //模板遍历
    2. for="m in messageList" :key='m.id'>
  • //组件中的数据
  • data() {
  • return {
  • messageList:[
  • {id:'001',title:'消息001'},
  • {id:'002',title:'消息002'},
  • {id:'003',title:'消息003'},
  • ]
  • }
  • },
  • 2. 配置路由规则 

    1. //此处只展示三级路由规则
    2. {
    3. path: 'message',
    4. component: Message,
    5. // 三级路由进行传参
    6. children: [
    7. {
    8. path: 'detail',
    9. component:Detail
    10. }
    11. ]
    12. },

    3. 创建一个展示组件获取参数

    此处是利用$route的query参数进行接收和传递

    传递:在父级组件中链接路由路径的时候利用query添加参数

    • 字符串写法:注意获取到的参数使用模板字符串进行包裹
    • 对象写法:直接布置路径和query参数,一对象方式进行配置数据

    注意:此时路由链接展示在li标签中,可以直接获取到遍历的数据,但是to需要进行绑定才能识别js格式代码

    1. <li v-for="m in messageList" :key='m.id'>
    2. <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}router-link>
    3. <router-link :to="{
    4. path:'/home/message/detail',
    5. query:{
    6. id:m.id,
    7. title:m.title
    8. }
    9. }">{{m.title}}router-link>  
    10. li>

    获取:在获取参数组件中利用$route.query.name进行获取(每个组件中都有自己的route)

    1. //直接利用组件参数进行获取
      • <li>消息编号:{{$route.query.id}}li>
      • <li>消息标题:{{$route.query.title}}li>

    六、命名路由

    1. 给每一个路由起一个名字

    1. routes: [
    2. {
    3. name:'guanyu',
    4. path: '/about',
    5. component:About
    6. children: [
    7. {
    8. name:'xiangqing',
    9. path: 'detail',
    10. component:Detail
    11. }
    12. ]
    13. },
    14. ]
    15. },
    16. ]

    2. 路由通过名字进行链接

    1. //字符串写法
    2. <router-link :to="{name:'guanyu'}">Aboutrouter-link>
    3. //对象写法
    4. <router-link :to="{
    5. name:'xiangqing',
    6. query:{
    7. id:m.id,
    8. title:m.title
    9. }
    10. }">{{m.title}}router-link>

    七、params参数传递

    1. 配置路由声名接收params参数

    创建新的路由配置:注意path需要绑定传入的数据名字

    1. {
    2. path: '/home',
    3. component: Home,
    4. children: [
    5. {
    6. path: 'news',
    7. component:News
    8. },
    9. {
    10. path: 'message',
    11. component: Message,
    12. children: [
    13. {
    14. name: 'xiangqing',
    15. // 占位符声名接收参数
    16. path: 'detail/:id/:title',
    17. component:Detail
    18. }
    19. ]
    20. },
    21. ]
    22. },

    2. 传递参数

    注意传递的时候字符串写法直接使用路径方式写法进行写参数(不建议)

    建议写成对象格式:如果写成params参数传递对象格式,必须使用name,不能使用path

    1. <router-link :to="`/home/message/detail/666/你好啊`">固定参数跳转router-link>
    2. <router-link :to="{
    3. name:'xiangqing',
    4. params:{
    5. id:666,
    6. title:'你好'
    7. }
    8. }">{{m.title}}router-link>

    3. 接收参数

    1. $route.params.id
    2. $route.params.title

    八、路由组件如何读取传递进来的参数

    为什么关注以上问题:

    1. $route.params.id
    2. $route.params.title
    3. $route.params.id2
    4. $route.params.title2
    5. $route.params.id3
    6. $route.params.title3

    props:外部传给路由获取参数组件的方式

    首先传递参数,以下都会使用到此参数传递效果(第二种种通过params传递,最后函数式使用query进行传递)

    1. "{
    2. name:'xiangqing',
    3. params:{
    4. id:666,
    5. title:'你好'
    6. }
    7. }">{{m.title}}
    1. :to="{
    2. path:'/home/message/detail',
    3. query:{
    4. id:m.id,
    5. title:m.title
    6. }

    1. 在路由配置中添加新的配置并在获取参数组件处进行接收

    注意数据是由路由中props进行控制

    1. children: [
    2. {
    3. name: 'xiangqing',
    4. path: 'detail',
    5. component: Detail,
    6. // 第一种写法,值为对象,该对象的所有key-value都会通过props的形式传给detail组件
    7. props: {
    8. a:1,
    9. b:'hello'
    10. }
    11. }
    1. //组件中首先接收,然后在模板中直接使用
    2. props:['a','b'],//对象形式
    3. //使用
    4. <li>消息编号:{{a}}li>
    5. <li>消息标题:{{b}}li>

    使用较少,传递的是固定数据

    2. 在路由中配置布尔值(params参数传递)

    布尔值为真就会把该路由组件接收到的params参数,以props的形式传给组件

    1. children: [
    2. {
    3. name: 'xiangqing',
    4. // 占位符:声名接收参数
    5. path: 'detail/:id/:title',
    6. component: Detail,
    7. //第二种写法:布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给detail组件
    8. props:true
    9. }

    然后再组件中进行接收,直接接收到的就是绑定的数据

    并可以直接使用

    1. //首先进行接收
    2. props:['id','title'],//布尔值形式
    3. //模板中直接使用
    4. <li>消息编号:{{id}}li>
    5. <li>消息标题:{{title}}li>

    3. 路由匹配值中使用参数为函数式(query参数传递)

    1. children: [
    2. {
    3. name: 'xiangqing',
    4. path: 'detail',
    5. component: Detail,
    6. props() {
    7. return{id:'666',title:'你好'}
    8. }
    9. }
    1. children: [
    2. {
    3. name: 'xiangqing',
    4. path: 'detail',
    5. component: Detail,
    6. props($route) {
    7. return{
    8. id:$route.query.id,
    9. title:$route.query.title}
    10. }
    11. }
    1. children: [
    2. {
    3. name: 'xiangqing',
    4. path: 'detail',
    5. component: Detail,
    6. //结赋值连续写法:先解构参数来源query,再解构id和title
    7. props({query:{id,title}}) {
    8. return{id,title}
    9. }
    10. }

    此参数不仅动态,还可以路由添加

    九、路由组件的历史记录

    历史记录保存方式:栈的方式进行保存历史记录

    默认push保存方式:指针默认指向最上层

     replace保存方式:新的地址总是替换最上层的地址

     replace的书写方式:直接再router-link绑定路由处进行添加标签属性

    1. //此处对比了replace的两种写法和绑定路径和名字的方式
    2. "true" :to="{name:'guanyu'}">About
    3. <router-link replace to="/home">Homerouter-link>

    十、编程式路由导航

    声明式导航必须借助router-link的to属性进行跳转(router-link就是a标签):必须点击

    某种情况不能使用router-link:

    1. 使用导航模块按钮进行展示编程式导航

    此处使用了路由器($router)的历史记录方式

    然后将传递参数和链接路由路径/名字的对象方式相同

    1. //创建代码按钮:里面绑定事件和事件的回调
    2. <button @click="replaceShow(m)">replace查看button>
    1. //设置事件回调并传递参数
    2. methods: {
    3. pushShow(m){
    4. // 执行push历史记录
    5. this.$router.push({
    6. name:'xiangqing',
    7. query:{
    8. id:m.id,
    9. title:m.title
    10. }
    11. })
    12. },
    13. replaceShow(m){
    14. // 执行replace历史记录
    15. this.$router.replace({
    16. name:'xiangqing',
    17. query:{
    18. id:m.id,
    19. title:m.title
    20. }
    21. })
    22. }
    23. },

    十一、路由组件历史纪录的跳转api

     前进

    1. //方法
    2. forward(){
    3. this.$router.forward()
    4. },

    后退

    1. //方法
    2. back(){
    3. this.$router.back()
    4. },

    指定步数:此处指定后退2步

    1. //方法
    2. test(){
    3. // 注意此处的go需要使用参数(表示执行几步)
    4. this.$router.go(-2)
    5. }

    十二、缓存路由组件

    当路由组件进行切换之后,之前组件就会销毁

     如何让路由组件切换之后输入的内容还能保存

    1. 保持活跃标签(放置在最外层链接路由展示位置)

    :如果直接使用以上标签,后面会出现的路由组件都会缓存

     

    1. <router-view>router-view>

    2. 缓存指定组件:添加新的配置:include

    缓存指定路由组件,注意进行绑定,一位内使用的是js格式代码

    此处缓存的名字使用的是组件名字,而不是路由名字

    1. '["News","Message"]'>
    2. <router-view>router-view>

    十三、新的生命周期钩子(激活失活)

    挂载组件切换被销毁:实现路由组件缓存之后:

    使用激活和失活生命周期钩子(放在展示组件内)

    activated(切换查看的会激活)   /   deactivated(切走之后会失活)

    在展示组件内将不需要缓存的内容进行激活和失活操作

    1. // 激活
    2. activated() {
    3. // console.log('news组件被激活');
    4. this.timer = setInterval(() => {
    5. console.log('@');
    6. this.opacity -= 0.01;
    7. // 此处注意:js不会计算小数:如果opacity的值小于等于0
    8. if (this.opacity <= 0) this.opacity = 1;
    9. }, 16);
    10. },
    11. // 失活
    12. deactivated() {
    13. // console.log('news组件失活');
    14. clearInterval(this.timer)
    15. },

    十四、全局路由守卫(权限控制):路由器中进行配置router.beforeEach

    路由点击之后会展示不同的组件

    但是有的路由组件必须是指定账户或者信息才能进行查看

    配置前置路由守卫

    1. 首先将路由器中的规则进行命名
    2. 利用beforeEach-api全局前置路由组件守卫(开启就需要进行参数设置)
      1. 参数包含to,from,next
      2. to表示准备去哪个组件
      3. from来自于那个组件
    3. 暴露路由器
    4. 执行next方法:继续执行(就是在这里配置相关守卫通过信息)
    1. //命名规则
    2. const router = new VueRouter({}
    3. //配置全局前置路由守卫
    4. router.beforeEach((to, from, next) => {
    5. next()
    6. }
    7. //暴露路由器
    8. export default router

    前置路由守卫:router.beforeEach中进行判断什么时候放行并继续执行

    注意此处使用判断条件是准备去往的路径(此处自行设置)

    以及本地用户是否匹配

    1. router.beforeEach((to, from, next) => {
    2. if(to.path === '/home/news' || to.path === '/home/message'){
    3. //以上的判断语句也可以直接使用路由名字进行配置
    4. // if (to.name === 'xinwen' || to.path === 'xiaoxi')
    5. if (localStorage.getItem('school') === 'xlf') {
    6. next()
    7. } else {
    8. alert('学校名不对,无权限查看')
    9. }
    10. }
    11. }

    路由跳转条件如果有很多代码冗余问题(解决)

      meta: { isAuth: true, title:'详情'},  
    1. router.beforeEach((to, from, next) => {
    2. if(to.meta.isAuth){
    3. //以上的判断语句也可以直接使用路由名字进行配置
    4. // if (to.name === 'xinwen' || to.path === 'xiaoxi')
    5. if (localStorage.getItem('school') === 'xlf') {
    6. next()
    7. } else {
    8. alert('学校名不对,无权限查看')
    9. }
    10. }
    11. }

    后置路由守卫,没有next():使用在title属性和每个组件对应

    每次路由切换之后被调用

    1. router.afterEach((to, from) => {
    2. document.title = to.meta.title || '路由守卫系统'
    3. })

    十五、独享路由守卫(beforeEnter)

    某一个路由单独需要守卫

    直接在路由中进行配置(放在需要进入的路由组件原则内)

    1. beforeEnter: (to, from, next) => {
    2. if (to.meta.isAuth) {
    3. if (localStorage.getItem('school') === 'xlf') {
    4. next()
    5. } else {
    6. alert('学校名不对')
    7. }
    8. } else {
    9. next()
    10. }
    11. }

    如果还需要进行全局后置路由守卫,重新打开

    1. router.afterEach((to, from) => {
    2. document.title = to.meta.title || '路由守卫系统'
    3. })

    十六、组件内路由守卫

    顾名思义,在组件种单独设置路由守卫:

    都包含三个参数,每次执行当前跳转需求之后就添加next()继续往下

    添加权限设置组件内路由守卫

    注意前提就是路由规则配置了meta还有本地存储的信息是否合适

    1. beforeRouteEnter (to, from, next) {
    2. if (to.meta.isAuth) {//控制是否需要权限:注意需要在路由配置中设置路由基本配置项meta
    3. // 限制权限
    4. if (localStorage.getItem('school') === 'xlf') {
    5. next()
    6. } else {
    7. alert('学校名不对,无权限查看')
    8. }
    9. } else {
    10. // 不是指定位置直接可以获取组件
    11. next()
    12. }
    13. },
    14. // 通过路由规则进入该组件
    15. beforeRouteLeave (to, from, next) {
    16. // 独享离开路由守卫
    17. console.log('app--- beforeRouteLeave');
    18. next()
    19. }

    十七、路由器的两种工作模式

    #  :哈希

    #包括后面的路径是哈希值:不会随着http请求发给服务器

    比如:当访问一个服务器就会存在返回信息,但是哈希值存在就不会发送给服务器(只会获取到哈希值前的路径给服务器)

     

    默认开启哈希工作模式:

    可以在路由器配置中添加属性mode:默认hash,

    如果修改则可以使history:mode:history

    1. const router = new VueRouter({
    2. mode:'hash'
    3. //各种路由
    4. }

    区别

    两种工作模式呈现在页面路径的区别

    hash的兼容性略强(并且在上线之后可以通过路径进行跳转路由)

     

    十八、上线打包

    当代码完成之后执行打包然后交给后端首选需要打包

    打包:通过package.json中的buil语句运行

    执行之后机会将工程文件生成一个dist文件夹中,里面都是html,css,js等文件

        "build": "vue-cli-service build",

    上线:将打包生成的文件执行部署

    1. // 首先合法包
    2. npm init
    3. //包命名
    4. 随便自己命名
    5. //安装express
    6. npm i express
    7. //创建一个server.js服务器文件
    8. //引入express
    9. const express = require('express')
    10. const history = require('connect-history-api-fallback');
    11. const app = express()
    12. app.use(history())
    13. app.use(express.static(__dirname+'/static'))
    14. app.get('/person', (req,res) => {
    15. // 函数体
    16. res.send({
    17. name: 'tome',
    18. age:18
    19. })
    20. })
    21. app.listen(5005, (err) => {
    22. if(!err) console.log('服务器启动成功了');
    23. })

    如何即使用history又可以通过路径进行跳转

    connect-history-api-fallback - npmProvides a fallback for non-existing directories so that the HTML 5 history API can be used.. Latest version: 2.0.0, last published: a year ago. Start using connect-history-api-fallback in your project by running `npm i connect-history-api-fallback`. There are 1401 other projects in the npm registry using connect-history-api-fallback.https://www.npmjs.com/package/connect-history-api-fallback

    npm install --save connect-history-api-fallback
    1. //引入
    2. const history = require('connect-history-api-fallback');
    3. //使用
    4. app.use(history())

  • 相关阅读:
    十七、C语言内存函数
    导入导出问题
    Java的JDBC编程
    大学时光仅四年,疫情反反复复占几年
    三门问题-Swift测试
    你不知道的JavaScript---异步:现在与未来
    面试官:TCC解决方案是什么?如何解决TCC幂等问题?
    Jest + React 单元测试最佳实践
    endnote21软件 web page引用 求解答
    商场促销--策略模式
  • 原文地址:https://blog.csdn.net/weixin_57920269/article/details/130880063