vue-router基本流程及其案例分析

news2024/11/25 19:46:09

web发展历程

1.后端实现路由

在这个阶段,前端基本上只写界面,也就是html,css,js那些东西,然后在界面中挖槽用来接后端数据,包括路由也由后端负责,在这个阶段中,web开发非常依赖后端,常见的后端框架有python中的flask。

2.前后端分离阶段 

在这个阶段,前端和后端的耦合性很低,它不像flask一样,后端传过来的数据需要在前端对应好,这样前后端需要时时刻刻对接,非常不方便(写flask应该只能前后端全干?)。在前后端分离阶段,前端一般用react,angular,vue等前端框架部署页面,这时我们只需要向服务器发送请求获取数据,然后把数据转化为前端能使用的数据,比如vue中请求的json文件可以进行解析然后再模板中渲染,这时前后端就不需要一一对应,只需要后端发送的数据符合格式,那么前端就能正确渲染。所以,前端可以更关注前端的逻辑,后端可以更关注后端的业务逻辑和数据库申请等后端操作。这就实现了前后端分离。

3.SPA(single page application) 

 SPA与前后端分离的区别主要在于SPA可以在不重新刷新界面的同时切换url。

使用vue-router实现SPA

环境配置

进入项目后,在终端中(切到项目目录下,因为vue-router这种第三方插件需要打包)

键入 pnpm install vue-router -D

在实现SPA前,我们先要了解一下SPA是如何实现的:

SPA原理

要实现SPA,本质上就是实现在不刷新界面的同时切换掉url

 url的hash

 URL的hash也就是锚点(#), 本质上是改变window.location的href属性,我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新。我们也可以使用histroy接口实现。

 vue-router使用

接下来我会结合一个案例来讲讲vue-router是如何使用的。

src/Views 组件文件夹

 

Home.vue

<template>
  <div class="sub-nav">
    <ul class="nav-bar">
      <li @click="recommendLiClick">推荐</li>
      <li @click="rankingLiClick">排行榜</li>
      <li>歌单</li>
      <li>主播电台</li>
    </ul>
  </div>
  <router-view></router-view>
</template>

<script setup>
import { useRouter } from 'vue-router';
const router = useRouter()

function recommendLiClick(){
  router.push({
    path:"/home/recommend",
    query:{}
  })
}
function rankingLiClick(){
  router.push({
    path:"/home/ranking",
    query:{}
  })
}

</script>

<style lang="less" scoped>
.sub-nav {
  
  .nav-bar{
    list-style-type: none;
    display: flex;
    margin: 0;
    padding: 0;
    text-align: center;
    height: 44px;
    width: 100%;
    line-height: 44px;
    

    li{
      flex: 1;
      background-color: rgb(173, 29, 29);
      color: whitesmoke;
      font-size: 12px;
      font-weight: bold;
      cursor: pointer;
    }
  }
}
</style>

About.vue

<template>
  <div class="about">
    <div class="container">
      <div class="header"><span>关于我们</span></div>
      <div class="content">
        <div class="info">
          <p> Name: {{ $route.query.name }}</p>
          <p> Age: {{ $route.query.age }}</p>
          <p> Sex: {{ $route.query.sex }}</p>
        </div>
        
      </div>
    </div>
  </div>
  
  <button @click="backBtnClick">back</button>
</template>

<script setup>
import { useRouter } from 'vue-router';
const router = useRouter()
function backBtnClick(){
    router.back()
}
</script>

<style lang="less" scoped>
.about{
  background-color: #f5f5f5;
  height: 900px;
  .container{
    background-color:#ffff;
    height: 900px;
    width: 55%;
    margin: 0 auto;
    padding: 55px 40px;
    letter-spacing: 2px; 
    .header{
      font-size: 22px;
      font-weight: bold;
      width: 100%;
      border-bottom: 2px solid rgb(173, 29, 29);
    }
    .content{
      width:100%;
      height: 200px;
      border: 2px solid black;
      margin-top: 20px;
      
      .info{
        padding: 20px 30px;
      }
      
    }
  }
}
</style>

Ranking.vue

 

<template>
  <div class="ranking">
    <div class="aside">
      <div class="header">云音乐特色榜</div>
      <div class="items">
        <ul class="item">
          <li>飙升榜</li>
          <li>新歌榜</li>
          <li>原创榜</li>
          <li>热歌榜</li>
        </ul>
      </div>
      <div class="header">全球媒体榜</div>
      <div class="items">
        <ul class="item">
          <li>云音乐说唱榜</li>
          <li>云音乐古典榜</li>
          <li>云音乐电音榜</li>
          <li>云音乐ACG榜</li>
        </ul>
      </div>
    </div>
    
    <div class="content">
      内容区域
    </div>
  </div>
</template>

<script setup>

</script>

<style lang="less" scoped>
.ranking{
  display: flex;
  width: 60%;
  height: 1000px;
  margin: 0 auto;
  background-color:whitesmoke;
  .aside{
    margin-left: 30px;
    flex: 1;
    .header{
      padding-top: 20px;
      font-size: 16px;
      font-weight: bold;
    }
    .items{
      .item{
        list-style-type: none;
        li{
          margin-top: 20px;
        }
      }
    }
  }
  .content{
    border: 2px solid black;
    margin-top: 1px;
    flex: 3;
    color: red;
    font-size: 30px;
    line-height: 1000px;
    text-align: center;
  }
}
</style>

Recommend.vue

<template>
  <div class="home-recommend">
    <div class="rollplay">
      轮播图区域
    </div>
    <div class="recommended-list">
      <div class="title">⭕热门推荐</div>
      <div class="category">
        <ul class="category-list">
          <li><span>华语</span></li>
          <li><span>流行</span></li>
          <li><span>摇滚</span></li>
          <li><span>民谣</span></li>
        </ul>
        
      </div>
    </div>
    <div class="content">
      内容区域
    </div>
  </div>
</template>

<script setup>

</script>

<style lang="less" scoped>
.home-recommend{
  .rollplay{
    margin: 1px 0 0 0;
    width: 100%;
    height: 255px;
    font-size: 26px;
    text-align: center;
    line-height: 255px;
    border: 2px solid black;
  }
  .recommended-list{
    height: 100px;
    line-height: 100px;
    display: flex;
    border-bottom: 2px solid rgb(173,29, 29) ;

    .title{
      padding-left: 33px;
      font-size: 20px;
      font-weight: 500px;
      flex: 1;
    }
    .category{
      flex: 5;
      
      .category-list{
        margin:0 5px;
        list-style-type: none;
        display: flex;
        color: #727272;
        li{
          
          span{
            border-right: 1px solid #727272;
            padding: 0 10px;
            font-size: 12px;
          }
        }
      }
    }
    
  }
  .content{
    margin: 1px 0 0 0;
    width: 100%;
    height: 400px;
    font-size: 26px;
    text-align: center;
    line-height: 400px;
    border: 2px solid black;
  }
}
</style>

App.vue

<template>
  <div class="app">
    <div class="main-nav">
      <!-- <router-link to="/home" replace>首页</router-link>  replace 替换路径,不会记录历史路径--> 
      <!-- <router-link to="/home" active-class="link-class">首页</router-link> active-class指定选中的元素附带的className -->
      <ul class="nav-bar">
        <li @click="homeLiClick">首页</li>
        <li @click="aboutLiClick">关于</li>
        <li @click="userLiClick">用户</li>
      </ul>
    </div>
    <router-view></router-view> 
  </div>


  <!-- 编程式跳转页面 -->
  
</template>

<script setup>
import { useRouter } from 'vue-router';
const router = useRouter()



function homeLiClick(){
  router.push({
    path:"/home",
    query:{}
  })
}
function aboutLiClick(){
  router.push({
    path:"/about",
    query:{
      name:"Lisman",
      age:"18",
      sex:"male"
    }
  })
}
function userLiClick(){
  router.push({
    path:"/user",
    query:{}
  })
}


</script>

<style lang="less" scoped>
.main-nav {
  
  .nav-bar{
    list-style-type: none;
    display: flex;
    margin: 0;
    padding: 0;
    text-align: center;
    height: 44px;
    width: 100%;
    line-height: 44px;
    

    li{
      flex: 1;
      background-color: #454545;
      color: whitesmoke;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
    }
  }
}

</style>

src/router/index.js 路由配置文件

import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'

//导入组件
// import Home from '@/Views/Home.vue'
// import About from '@/Views/About.vue'


//以下为路由懒加载,import导入可以做到分包处理,webpackChunkName可以给包指定名字
// const Home = import(/* webpackChunkName: 'Home' */"../Views/Home.vue")
// const About = import(/* webpackChunkName: 'About' */"../Views/About.vue")

//创建路由:映射关系
const router = createRouter({
  //选择模式(Hash)
  // history: createWebHashHistory(),
  history: createWebHashHistory(),
  routes: [
    {
      path: "/home",
      component: () => import("../Views/Home.vue"),
      //嵌套路由
      children: [
        {
          path: "recommend",//相当于/home/recommend
          component: () => import("../Views/Recommend.vue")
        },
        {
          path: "ranking",
          component: () => import("../Views/Ranking.vue")
        },
        {
          path: "",
          redirect: "/home/recommend"
        }
      ]
    },
    { path: "/about", component: () => import("../Views/About.vue") },
    { path: "/user/:id", component: () => import("../Views/User.vue") },//动态路由
    { path: "/", redirect: "/home" },
    
  ]
})



//导出路由
export default router

 

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index.js'

const app = createApp(App)
app.use(router)
app.mount("#app")

实现效果如下:

2024-09-02 23-53-59

主要流程

 

 要建立组件与url的关系,局部分为三步:创建组件,创建路由,构建路由和组件的关系

创建组件自不必多说,创建路由和创建组件关系才是重点。

index.js

import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'

//导入组件
// import Home from '@/Views/Home.vue'
// import About from '@/Views/About.vue'


//以下为路由懒加载,import导入可以做到分包处理,webpackChunkName可以给包指定名字
// const Home = import(/* webpackChunkName: 'Home' */"../Views/Home.vue")
// const About = import(/* webpackChunkName: 'About' */"../Views/About.vue")

//创建路由:映射关系
const router = createRouter({
  //选择模式(Hash)
  // history: createWebHashHistory(),
  history: createWebHashHistory(),
  routes: [
    {
      path: "/home",
      component: () => import("../Views/Home.vue"),
      //嵌套路由
      children: [
        {
          path: "recommend",//相当于/home/recommend
          component: () => import("../Views/Recommend.vue")
        },
        {
          path: "ranking",
          component: () => import("../Views/Ranking.vue")
        },
        {
          path: "",
          redirect: "/home/recommend"
        }
      ]
    },
    { path: "/about", component: () => import("../Views/About.vue") },
    { path: "/user/:id", component: () => import("../Views/User.vue") },//动态路由
    { path: "/", redirect: "/home" },
    
  ]
})



//导出路由
export default router

 通常我们会在src下创建一个router文件夹,然后在router文件夹下写路由的逻辑。

首先,我们导入vue-router中的createRouter()方法创建路由对象,我们传入一个对象作为参数,在这个对象中写入histroy,routes两个成员(当然还有更多)。

History: 可以选择url的模式,如果为createWebHashHistroy的话,那么url路径会以/*/分隔,如果为createWebHistroy的话就不会有/*/分隔,这样更容易阅读。

比如有路径

localhost:8080/*/home/recommend(Hash模式)

localhost:8080/home/recommend (History模式)

routes:这个就是用来配置url与组件关系的东西,比较简单,就是指定好path,然后再为其绑定一个组件,当在浏览器中访问该路径时会在合适的地方渲染这个组件。redirect为重定向,当浏览器访问目标路径时自动将其导向新的路径。关于children的话,这个涉及路由嵌套,可以这么认为:

这个在之后了解完route-view应该更好理解。可以这样理解:在根组件app.vue中,我们使用route-view来占位,当进入目标路径时,路由会根据这个url找到对应的组件并将其渲染在route-view中,而嵌套路由其实就是重复这个过程。在渲染的组件中在写入route-view,在进入下一级路径时再次找到对应的组件将其渲染在组件中的route-view中。

最后,返回路由。到此为止,路由创建和url和组件间的绑定就告一段落了。

接下来,我们要开始配置路由(使用返回的router)

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index.js'

const app = createApp(App)
app.use(router)
app.mount("#app")

使用app.use(router)使用该路由就可以了。

本文没有使用router-link,而是使用script来实现跳转。 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2100672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系列精选 |【梧桐数据库】产品架构层次解析-总述

梧桐数据库中秋特别活动免费领取大闸蟹 抽奖免费领取大闸蟹 以下是正文 在浩瀚的数据世界里&#xff0c;梧桐数据库犹如一颗璀璨的星辰&#xff0c;它的设计如同一首细腻的诗歌&#xff0c;每一个层次都是优美的韵律&#xff0c;为我们构建了一个强大而灵动的数据天地。 梧桐数…

西中区2024年度安全知识竞赛活动方案

为有效预防安全生产事故的发生&#xff0c;深化西中区全体员工对安全生产的认识&#xff0c;切实提升全体人员的安全意识和自我保护能力&#xff0c;夯实安全知识基础&#xff0c;丰富安全文化内涵&#xff0c;推动安全生产工作更加规范化、系统化&#xff0c;根据西中区安全生…

<数据集>遥感航拍飞机和船舶和识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;19973张 标注数量(xml文件个数)&#xff1a;19973 标注数量(txt文件个数)&#xff1a;19973 标注类别数&#xff1a;2 标注类别名称&#xff1a;[ship,plane] 序号类别名称图片数框数1ship17575416292plane239815…

简单好用的SD卡克隆软件:轻松克隆SD卡

想更换SD卡以提升性能&#xff0c;但不知道如何进行SD卡克隆&#xff1f;不用担心&#xff0c;本文推荐了一款好用SD卡克隆软件&#xff0c;轻松帮你解决问题&#xff01; 为什么要克隆SD卡&#xff1f; SD卡广泛应用于游戏机、手机及其他便携设备。用户常用SD卡存储个人数据…

2024/9/3黑马头条跟学笔记(一)

D1 视频链接 Day1-05-nacos环境搭建_哔哩哔哩_bilibili 内容介绍 搭建微服务开发环境&#xff0c;登录接口包含注册中心和nacos配置中心 服务端用户…微服务。网关负载均衡转发接口请求 实现微服务间互相通信 接口测试 前后端联调 前置知识 背景介绍 类似今日头条&#x…

权威解读:社交类APP都需要办理哪些资质?

今天小编给大家讲讲社交类APP都需要办理哪些资质&#xff1f; 我们先来看下微信小程序对社交类目是怎么分类以及需要哪些资质许可证&#xff1f; 微信小程序社交类目许可资质 微信小程序对社交类目做了一些细分&#xff0c;它把社交分为陌生人交友、熟人交友、社区/论坛、直播…

log4j 控制台和文件输出乱码问题解决

一个小问题&#xff0c;却让我感觉到&#xff0c;现在真正动脑的人很少。。我来说说吧。 今天遇到一个小问题&#xff0c; log4j输出到文件乱码&#xff0c;控制台正常。显然是编码问题导致。Google一搜&#xff0c;几乎一水的说&#xff1a; 项目中log4j在英文版linux下输出中…

气膜水产养殖:打造高效、可持续的水产养殖新模式—轻空间

随着全球对高质量水产品需求的不断增加&#xff0c;传统的水产养殖方式面临着诸多挑战&#xff0c;如环境污染、气候变化以及水源短缺等问题。在这种背景下&#xff0c;气膜水产养殖作为一种创新的养殖模式&#xff0c;逐渐引起了广泛关注。通过结合气膜结构建筑与现代化养殖技…

【测试】系统测试用例编写案例模板(Word原件)

1编写目的 2使用范围 3文档概述 4术语和缩略语 5编写规范 5.1编写目的 5.2编写范围 5.3编写规范 6参考文档 软件全套精华资料包清单部分文件列表&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需…

从UGC到PGC:3C品牌与TikTok达人合作的内容优化策略

在数字营销新时代&#xff0c;内容的创作和传播方式正在经历快速的变革。3C品牌与TikTok达人的合作正逐渐从用户生成内容&#xff08;UGC&#xff09;向专业生成内容&#xff08;PGC&#xff09;转变。这一转变不仅改变了内容的生产方式&#xff0c;也提升了品牌营销的效果。本…

三种权限模型该如何选择

在构建企业级平台或复杂应用系统时&#xff0c;权限管理是一个至关重要的环节。它决定了哪些用户可以访问哪些资源&#xff0c;以及可以进行哪些操作&#xff0c;一个健全的权限管理架构&#xff0c;在确保系统正常运行的同时&#xff0c;也能有效防止数据泄露和非法访问&#…

antd:手写走马灯vue组件

在使用ant-design-vue做走马灯的时候,封装的组件的自由度太低,难以实现想要的效果,于是本人自己写了一个走马灯组件,以方便代码复用。本文将介绍如何在vue框架中,使用ant-design-vue手动实现走马灯组件效果。 结果如下图所示, 一、使用说明 使用时,直接创建一个组件,…

.NET 最好用的验证组件 FluentValidation

目录 前言 项目介绍 项目使用 1、安装FluentValidation 2、Program.cs 3、Startup.cs 4、版本兼容 5、支持的验证器 6、可扩展 7、Swagger 模型和验证器 8、包含验证器 高级用法 1、异步验证 2、条件验证 3、自定义验证规则 4、自定义错误消息 项目地址 总结 …

comfyui替换电商模特工作流,模特们要真的要失业了吗?

前言 comfyui生态的丰富绝对是电商行业的福利&#xff0c;有助于电商老板们开源节流&#xff0c;废话不多说本着追求进步进一步理解comfyui工作流的搭建逻辑&#xff0c;我们来拆解电商模特替换这个工作流&#xff01; 老规矩一句话说工作流原理&#xff0c;1.借助XL-tile修改…

Funsound: 快速为你的视频加上字幕

Funsound是基于阿里达摩院funasr开发的中文语音识别工具&#xff0c;其paraformer非自回归解码速度超快&#xff0c;同时预训练模型识别精度业界领先。本文将简要介绍funsound下如何快速为你的视频添加字幕&#xff0c;十分简单方便。 1. 上传音视频识别 & 导出SRT 打开fu…

无人机之飞行速度篇

无人机的飞行速度是一个复杂且多变的参数&#xff0c;它受到多种因素的影响。以下是对无人机飞行速度及其影响因素的详细分析&#xff1a; 一、无人机飞行速度概述 无人机的飞行速度通常以其在不同飞行模式下的水平飞行速度来衡量&#xff0c;如平稳挡&#xff08;Cine&#x…

关于武汉高芯coin417G2红外机芯的二次开发

文章目录 前言一、外观和机芯参数二、SDK的使用1、打开相机2、回调函数中获取全局温度和图像3、关闭相机 前言 最近工作中接触了一款基于武汉高芯科技有限公司开发的红外模组,即coin417g2(测温型)9.1mm镜头.使用此模组,开发了一套红外热成像检测桌面应用程序.下面简单记录下该…

踩坑记录(序列化与反序列化)

问题描述 实体类中设定字段名称为 sValue和yValue 返回给前段后,变成了svalue,yvalue 字段设置 测试结果:与字段不符,匹配失败 解决方法 在字段上添加JsonProperty("字段名")注解

乌班图部署若依(nginx)

Nginx 什么是Nginx Nginx&#xff08;发音为"engine x"&#xff09;是由俄罗斯开发者Igor Sysoev创建的一款轻量级、高性能的Web服务器。它首次发布于2004年&#xff0c;如今已成为全球最受欢迎的Web服务器之一。Nginx以其卓越的性能和灵活性而闻名&#xff0c;适用…

[240903] Qwen2-VL: 更清晰地看世界 | Elasticsearch 再次拥抱开源!

目录 Qwen2-VL: 更清晰地看世界Elasticsearch 再次拥抱开源&#xff01; Qwen2-VL: 更清晰地看世界 历经一年研发&#xff0c;阿里云推出新一代视觉语言模型 Qwen2-VL&#xff0c;支持多语言、长视频理解、视觉推理及智能体交互&#xff0c;性能超越 GPT-4o 等模型&#xff0c…