[手把手教你]实现简单的登录跳转以及tab栏的动态渲染

news/2024/4/25 19:13:59/文章来源:https://blog.csdn.net/qq_54379580/article/details/129137010
需求:
  实现login登录页输入用户名和密码, 匹配失败显示提示信息, 成功则跳转到index主页
  index页面中各组件通过嵌套路由实现,点击一级菜单可以动态显示二级菜单

1.使用vite搭建项目

  • 安装初始化npm init vue@latest

  • 选择配置

  • 进入项目目录,安装模块npm i, 启动项目npm run dev

2.项目目录

删除项目中不需要的组件, 清空不需要的css 文件(将src/assets/main.css中的样式删除)

3. 实现登录页跳转

(1)创建登录页组件src / components / Login.vue ,创建Index.vue

  • <template>书写登录页html

  • <style>书写样式, 使用display: flex; 盒子自动变为行内块元素

  • <script>中data(){ return{ 保存数据 } }, methods:{ 内部书写各种函数}

  • 输入用户名和密码时, input表单元素, 需要通过v-model 进行双向数据绑定, 可通过修饰符 .trim 去除前后空格

  • 响应式数据, 保存在data函数中并通过return返回对象

  • 登录按钮绑定点击事件, 并触发login登录函数

login登录函数的实现:

获取输入框内容, 判断是否为空
为空: 显示提示信息
不为空: 判断用户名和密码是否正确
正确: 实现页面跳转, 使用this.$router.push()/replace()
 不正确: 显示提示信息
<template><div class="login"><div class="box"><h1>Login</h1><ul><li><label><span>用户名</span>:<!-- 1. 动态绑定    .trim去空 --><input type="text" v-model.trim="uname" placeholder="请输入用户名"></label></li><li><label><span>密码</span>:<input type="password" v-model.trim="password" placeholder="请输入密码"></label></li><li class="tips" v-show="isShow">{{ tips }}</li><li><button @click="login">登 录</button></li></ul></div></div>
</template>
<script>export default {data() {return {uname: '',password: '',tips: '',isShow: false, //控制tips是否显示, false默认不显示}},methods: {// 登录login() {// 2 .获取用户名和密码的值, 判断是否存在if (this.uname === '' || this.password === '') {// 3. 用户名或密码为空this.isShow = true //显示tipsthis.tips = '用户名或密码不能为空 ! ! !'} else {this.isShow = false//  4. 用户名或密码不为空 , 判断用户名和密码是否正确if (this.uname === 'mm' && this.password === '1111') {// 5. 用户名和密码正确, 跳转页面this.$router.push({path: '/index'})} else {// 6. 用户名或密码不正确this.isShow = true //显示tipsthis.tips = '用户名或密码错误 ! ! !'}}}}}
</script>
<style scoped>div.login {display: flex;height: 100%;justify-content: center;align-items: center;}div.login div.box {width: 30%;height: 40%;background-color: #ffede7;}div.login div.box h1 {margin-top: 30px;text-align: center;}div.login div.box ul {position: relative;text-align: center;font-size: 20px;}div.login div.box ul li {margin: 30px auto;width: 80%;}div.login div.box ul li label {width: 100%;}div.login div.box ul li label span {display: inline-block;margin-right: 5px;width: 80px;text-align: justify;text-align-last: justify;text-justify: distribute-all-lines;}div.login div.box ul li label input {width: 65%;height: 40px;font-size: 18px;outline: 0;text-indent: 5px;  /* 默认文本值距离左边的距离*/}div.login div.box ul li button {margin-top: 15px;padding: 0 35%;width: 90%;height: 40px;text-align: justify;text-align-last: justify;font-size: 20px;border: 0;cursor: pointer;background-color: #ffe3d5;}div.login div.box ul li.tips {color: deeppink;font-size: 16px;position: absolute;bottom: 20px;left: 35px;}
</style> 

页面效果:

(2)启动项目,直接进入Login页面

启动项目打开页面时, 直接进入Login页面, 尝试了一下两种方式

方式1: 将Login组件作为App.vue的子组件 (有问题)

  • 在App.vue中引入组件

  • 通过components:{}注册组件, 使用大驼峰命名规则

  • 将组件作为标签来使用,  与注册组件名保持一致 <Login></Login>

问题:
     (1) 在地址栏中输入任何内容, 都会跳转至登录页面
     (2) 在页面进行跳转时, 地址栏中路径变化,但页面无法显示, 依旧为登录页面
      [ 无法获取到路由实例 this.$router, 可能是定义路由中history模式没写() ]
原因:  
      把Login.vue组件作为App.vue中模板的内容, App.vue是项目根组件,作为页面入口, 任何路径都需要从该入口进入
<script>import Login from './components/Login.vue'export default{components:{ Login  }}
</script>
<template><div><Login></Login></div>
</template>
<style scoped></style>

方式2: 通过路由实现(解决方式1带来的问题)

定义路由 router/index.js, 创建路由对象, 编写路径与组件的映射关系

import { createRouter, createWebHistory } from 'vue-router'
import Login from '../components/Login.vue'
import Index from '../components/Index.vue'const router = createRouter({
//history模式中 hash模式在地址栏中前边会有一个/# , 并且未被发送到服务器,不需要在服务器层面上进行任何特殊处理history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/login',name: 'Login',component: Login,alias: '/'}, {path: '/index',name: 'Index',component: Index,children: [{path: '/index/grade22',name: 'Grade22',component: Grade22,}, ]   //此处省略一些子路由的定义}]
})
export default router

在main.js中使用路由

import router from './router'
app.use(router)

在App.vue中使用路由占位符, 指定显示位置

<template><div> <!-- 路由显示的指定区域, 两种标签均可 --><!-- <RouterView></RouterView> --><router-view></router-view></div>
</template>

当输入无效路径时, 显示404页面 ( 创建404组件, 并定义路由 )

  • $route.params.paths 可获取动态路由参数

  •  $router 指当前活跃的路由实例对象

{// 404     将所有匹配到的路径存放在  $route.params.paths 下, 将非法路径的所有部分作为参数//   /:paths(.*)*   无效路径打印后 [ "index", "grade19", "aaa" ]   最后的 * 是将每一部分都分割了   //   /:paths(.*)     index/grade19/aaapath: '/:paths(.*)*',component: NotFount
}

4.实现主页

一级标签使用超链接(<a>), 点击a标签会造成整个页面的刷新, 性能较低

使用<router-link to="">导航路由完成, 改变地址栏路径, 页面不会重新渲染,性能较高

<template><div class="box"><div class="index"><ul class="title"><router-link to="/index/grade22"><li>2022级</li></router-link><router-link to="/index/grade21"><li>2021级</li></router-link><router-link to="/index/grade20"><li>2020级</li></router-link><router-link to="/index/grade19"><li>2019级</li></router-link></ul><router-view></router-view></div></div>
</template>

在router/index.js中定义路由

发现Index组件中的子组件模板基本一样, 故只创建一个组件, 通过参数传递的方式实现

使用嵌套路由实现, 将Grade.vue 组件的内容显示在Index.vue中

routes: [{path: '/',name: 'Login',component: Login,alias: '/login'},{path: '/index',name: 'Index',component: Index,// redirect: 'grade/22',children: [{path: '/index/grade/:id',name: 'Grade',component: Grade,children: [{path: 'grade/:id/spe',name: 'Specialty',component: Specialty,}]}, ]},{// 404     将所有匹配到的路径存放在  $route.params.paths 下, 将非法路径的所有部分作为参数//   /:paths(.*)*     无效路径打印后 [ "index", "grade19", "aaa" ]   最后的 * 是将每一部分都分割了// /:paths(.*)     index/grade19/aaapath: '/:paths(.*)*',component: NotFount}]

Grade.vue组件中使用命名路由

<template><div class="specialty"><ul><router-link to="/index/grade/22/spe"><li>计算机</li></router-link><router-link to="/index/grade/21/spe"><li>信管</li></router-link><router-link to="/index/grade/20/spe"><li>信计</li></router-link><router-link to="/index/grade/19/spe"><li>数学</li></router-link></ul><router-view ></router-view></div>
</template>

5.实现点击一级菜单, 动态渲染二级菜单

将导航数据存储在Data.js中

在组件中获取参数, 可通过$route.pramas获取, 也可通过 props:[ ]接收参数

根据参数不同, 加载不同的菜单

<template><div class="specialty"><ul><router-link v-for="item of list" :to="{ name:'specialty', params:{id} }"><li>{{ item }}</li></router-link></ul><router-view></router-view></div>
</template>
<script>import data from '../Data.js';export default {data() {return {list: []}},props: ['id'],// 钩子函数mounted() {const id = this.$route.params.id;//做初始化this.list = data.filter(item => item.id == id)[0].items;},updated() {const id = this.$route.params.id;//更新时也要更新listthis.list = data.filter(item => item.id == id)[0].items;}}
</script>
<style scoped>div.specialty ul {display: flex;background-color: #fff;}div.specialty ul li {padding: 10px 20px 10px 10px;}
</style>

效果图:

源代码放在这里啦~~~(大家帮忙提提点击量呗^^)

https://download.csdn.net/download/qq_54379580/87473605

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

S5P6818_系统篇(2)源码编译及烧录

源码获取 源码获取和操作流程 1.下载liunux下的系统制作脚本&#xff0c;可以烧录系统和构建镜像 git clone https://github.com/friendlyarm/sd-fuse_s5p6818.git 如果出现git错误可使用如下方法&#xff1a; git config --global http.sslverify false 2.阅读该工具rea…

软件测试5年,一路走来的艰辛路程

前言 不论你是什么时候开始接触测试这个行业的&#xff0c;你首先听说的应该是功能测试。通过一些测试手段来验证开发做出的代码是否符合产品的需求&#xff1f;当然你也有自己对功能测试的理解&#xff0c;但是最近两年感觉功能测试好像不太受欢迎&#xff0c;同时不少同学真的…

Linux 基础知识之文件系统

目录一、文件系统1.文件种类2.Linux和Windows文件后缀的不同3.查看文件类型3.绝对路径与相对路径二、系统分区三、目录结构一、文件系统 1.文件种类 Linux中一切皆文件。目光所及&#xff0c;皆是文件。文件的种类共有七种&#xff0c;每种文件都有自己的独特标识&#xff1a;…

SCADA-1-组态前期需求调研篇

近期有朋友找到我&#xff0c;说scada组态系统开源的很少&#xff0c;不少开发者借此售卖这种软件&#xff0c;我回了句&#xff1a;这有什么难的&#xff0c;不就是拖拖拽拽&#xff0c;再绑定上数据源&#xff0c;实现动态效果嘛。。。&#xff08;先装了个X&#xff09;一、…

【C++】类和对象入门必知

面向过程和面向对象的初步认识类的引入类的定义类的访问限定符封装类的作用域类的实例化类对象模型this指针C语言和C实现Stack的对比面向过程和面向对象的初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解…

3717: yuyu学数数

描述yuyu开始学数数了&#xff0c;她要爸爸给他一些火柴棍&#xff0c;她要拼出很多数来。yuyu每次说要拼什么数字&#xff0c;爸爸就得想想要给她几根&#xff0c;好累啊&#xff0c;于是就只好写程序了。输入输入数据有多组&#xff0c;每组占一行&#xff0c;每行一个非负整…

版本控制软件SVN

SVN学习 1 版本控制软件定义及用途 版本控制软件是为适应软件配置管理的需要&#xff0c;控制软件的修改&#xff0c;减少混乱&#xff0c;提高软件生产效率&#xff0c;其是软件质量保证的重要环节软件配置管理是对软件修改进行标识、组织和控制的技术&#xff0c;用来协调和…

数据结构:循环队列的实现(leetcode622.设计循环队列)

目录 一.循环队列简单介绍 二.用静态数组实现循环队列 1.数组循环队列结构设计 2.数组循环队列的堆区内存申请接口 3.数据出队和入队的接口实现 4.其他操作接口 5.数组循环队列的实现代码总览 三.静态单向循环链表实现循环队列 1.链表循环队列的结构设计 2.创建静…

Linux服务:Nginx服务配置及相关模块

目录 一、Nginx配置文件 1、主配置文件解析 2、子配置文件启用 二、子配置文件使用 1、创建虚拟主机实验 2、基于端口虚拟主机实验 三、Nginx模块 1、access模块 2、自定义错误页面 3、状态页开启 一、Nginx配置文件 1、主配置文件解析 ①yum安装主配置文件位置&…

攻击者失手,自己杀死了僵尸网络 KmsdBot

此前&#xff0c;Akamai 的安全研究员披露了 KmsdBot 僵尸网络&#xff0c;该僵尸网络主要通过 SSH 爆破与弱口令进行传播。在对该僵尸网络的持续跟踪中&#xff0c;研究人员发现了一些有趣的事情。 C&C 控制 对恶意活动来说&#xff0c;最致命的就是夺取对 C&C 服务…

Anaconda环境配置

1.进入清华大学镜像网站Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror&#xff0c;下载稳定版Anaconda3-5.2.0&#xff0c;如下图。2.放到整理好的文件夹中&#xff0c;双击安装包进行安装。3.安装过程中需要改变的默认值如下&#xff…

【数据库】redis数据持久化

目录 数据持久化 一&#xff0c; RDB 1&#xff0c; 什么是RDB 2&#xff0c;持久化流程 3&#xff0c; 相关配置 案例演示&#xff1a; 4&#xff0c; 备份和恢复 1、备份 2、恢复 3&#xff0c;优势 4&#xff0c; 劣势 二&#xff0c;AOF 1&#xff0c;什么是A…

说说 React 中 fiber、DOM、ReactElement、实例对象之间的引用关系

原生组件 fiber 原生组件 fiber&#xff0c;指的就是 type 为 “span”、“div” 的 fiber。 1.fiber.stateNode 指向真实 DOM 节点&#xff1b;2.node["__reactFiber$" randomKey] 指向对应 fiber&#xff0c;使用随机数是防止和业务代码的属性名冲突&#xff0c;…

Scala模式匹配详解(第八章:基本语法、模式守卫、模式匹配类型)(尚硅谷笔记)

模式匹配第 8 章 模式匹配8.1 基本语法8.2 模式守卫8.3 模式匹配类型8.3.1 匹配常量8.3.2 匹配类型8.3.3 匹配数组8.3.4 匹配列表8.3.5 匹配元组8.3.6 匹配对象及样例类8.4 变量声明中的模式匹配8.5 for 表达式中的模式匹配8.6 偏函数中的模式匹配(了解)第 8 章 模式匹配 Scal…

论文解读 | [AAAI2020] 你所需要的是边界:走向任意形状的文本定位

目录 1、研究背景 2、研究的目的 3、方法论 3.1 Boundary Point Detection Network(BPDN) 3.2 Recognition Network 3.3 Loss Functions 4、实验及结果 论文连接&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/6896 1、研究背景 最近&#xff0c;旨在…

深度解读 | 数据资产管理面临诸多挑战,做好这5个措施是关键

日前&#xff0c;大数据技术标准推进委员会&#xff08;中国通信标准化协会下&#xff08;CCSA&#xff09;的专业技术委员会&#xff0c;简称TC601&#xff09;发布《数据资产管理实践白皮书》&#xff08;6.0 版&#xff09;&#xff08;以下简称&#xff1a;报告&#xff09…

浏览器跨域问题

跨域问题什么是跨域问题如何解决跨域问题JSONPCORS方式解决跨域使用 Nginx 反向代理使用 WebSocket跨源请求是否能携带Cookie什么是跨域问题 跨域问题指的是不同站点之间&#xff0c;使用 ajax 无法相互调用的问题。跨域问题本质是浏览器的一种保护机制&#xff0c;它的初衷是为…

LQB01位操作说明

一个字节&#xff0c;包括了8位&#xff0c;可以对其中的8位的某一位进行读或者写&#xff1b; 比如char num12,如果用十六进制表示&#xff0c;就是0x0C&#xff0c;如果二进制表示&#xff0c;就是0000 1010 位操作函数&#xff0c;主要这里介绍&#xff0c;位读和位写0&am…

【消费战略方法论】认识消费者的恒常原理(一):消费者稳态平衡原理

“消费战略”是塔望咨询基于大量的战略与营销实践经验结合心理学、经济学、传播学等相关专业学科的知识应用进行提炼与创造形成的战略方法体系。消费战略强调以消费者为导向&#xff0c;进行企业、品牌战略、品牌营销的制订和落地&#xff0c;企业经营的每个环节和输出的每个动…

轻松搭建Redis缓存高可用集群

1. 安装单机Redis 安装步骤&#xff1a; 1.1 下载redis 官网下载3.0.0版本&#xff0c;之前几的版本不支持集群模式 下载地址&#xff1a;http://download.redis.io/releases/redis-3.0.0.tar.gz 1.2 首先需要安装gcc yum install gcc 1.3 创建目录 cd /usr/mkdir soft1.…