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

news2025/1/30 16:26:14
需求:
  实现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 //显示tips
                    this.tips = '用户名或密码不能为空 ! ! !'
                } else {
                    this.isShow = false
                    //  4. 用户名或密码不为空 , 判断用户名和密码是否正确
                    if (this.uname === 'mm' && this.password === '1111') {
                        // 5. 用户名和密码正确, 跳转页面
                        this.$router.push({
                            path: '/index'
                        })
                    } else {
                        // 6. 用户名或密码不正确
                        this.isShow = true //显示tips
                        this.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/aaa
   path: '/: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/aaa
            path: '/: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;
            //更新时也要更新list
            this.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.coloradmin.cn/o/363296.html

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

相关文章

【答疑现场】我一个搞嵌入式的,有必要学习Python吗?

【答疑现场】我一个搞嵌入式的&#xff0c;有必要学习Python吗&#xff1f; 文章目录1 写在前面2 一个结论3 Python在嵌入式领域能干啥事4 Python是用来干大事的5 友情推荐6 福利活动大家好&#xff0c;我是架构师李肯&#xff0c;一个专注于嵌入式物联网系统架构设计的攻城狮。…

FPGA纯vhdl实现MIPI CSI2 RX视频解码输出,OV13850采集,提供工程源码和技术支持

目录1、前言2、Xilinx官方主推的MIPI解码方案3、纯Vhdl方案解码MIPI4、vivado工程介绍5、上板调试验证6、福利&#xff1a;工程代码的获取1、前言 FPGA图像采集领域目前协议最复杂、技术难度最高的应该就是MIPI协议了&#xff0c;MIPI解码难度之高&#xff0c;令无数英雄竞折腰…

Hive---浅谈Hive

浅谈Hive 文章目录浅谈HiveHive文件映射Hive组件元数据&#xff08;Metadata&#xff09;元数据存储元数据服务&#xff08;Metastore&#xff09;Metastore配置方式Metastore远程模式Hive启动方式第一种&#xff08;本地&#xff09;第二种beelineHive Apache Hive作为一款大…

电子作业指导书系统能树立良好的生产形象

“制造”就是以规定的成本、规定的工时、生产出品质均匀、符合规格的产品。从全球新能源汽车的发展来看&#xff0c;其动力电源主要包括锂离子电池、镍氢电池、铅酸电池、超级电容器&#xff0c;其中超级电容器大多以辅助动力源的形式出现。那么&#xff0c;电子作业指导书系统…

吐血整理AutoSAR Com-Stack 的配置【基于ETAS】

总目录链接>> AutoSAR入门和实战系列总目录 文章目录01.软件组件和系统说明02.基本软件配置03.系统数据映射04.代码生成05.代码整合06.测试下图显示了基于 AUTOSAR 的 ECU SW 的结构。纵观BSW&#xff0c;大体分为三层。三层模块中&#xff0c;与通信相关的模块称为通信…

修改一个对象的所有者

警示&#xff1a;本文需要你懂点儿 “技术”。 修改一个对象(例如一个文件)的所有者看起来不是很复杂&#xff1a;你只需要调用 SetNamedSecurityInfo 并传入一个新的安全描述符就可以了&#xff0c;是的&#xff0c;就是这么简单。 难点在于&#xff0c;你如何到达这个调用时…

分布式之Quorum NWR算法

写在前面 假设现在我们实现了AP 系统&#xff0c;但是公司突然要对某些业务进行实时的数据计算&#xff0c;并且要求按照强一致性的方式来读取数据&#xff0c;此时作为系统设计这的我们该怎么办呢&#xff1f;单独为这部分业务实时抽出最新数据&#xff1f;还是修改原有系统&…

个人服务器+博客网站搭建

实现目标&#xff1a; 远程访问windows远程访问linux并在该环境开发&#xff08;ssh&#xff09;个人博客网站运 环境准备 准备一台性能较好的个人电脑&#xff0c;推荐台式机&#xff0c;仅在环境搭建初期需要显示器&#xff0c;后期使用基本不需要屏幕。规划好磁盘使用&…

从0探索NLP——神经网络

从0探索NLP——神经网络 1.前言 一提人工智能&#xff0c;最能想到的就是神经网络&#xff0c;但其实神经网络只是深度学习的主要实现方式。 现在主流的NLP相关任务、模型大都是基于深度学习也就是构建神经网络实现的&#xff0c;所以这里讲解一下神经网络以及简单的神经网络…

随想录二刷(数组二分法)leetcode 704 35 34 69 367

第一题 leetcode 704.二分查找 二分法的思路 二分法的思路很简单 数组必须有序先查找中间元素进行比较得出大小再考虑向左比较还是向右比较 代码实现 class Solution { public:int search(vector<int>& nums, int target) {int left 0;int right nums.size() -…

[oeasy]python0090_极客起源_wozniac_苹果公司_Jobs_Wozniac

极客起源 回忆上次内容 上次回顾了 DEC公司的兴起 从IBM的大型机 到DEC的小型机Mini Computer 再到DEC的终端 VT-100 计算机基础元器件发生了进化 从ENIAC的 电子管到PDP系列的 晶体管 新的器件 体积小了价格低了稳定性 提高了而且 连成了网络 ARPA网 就是 最初的Internet …

2023年度最新且最详细Ubuntu的安装教程

目录 准备ISO镜像 1.去官网下载镜像&#xff0c;或者找有镜像源的网站下载 阿里云镜像站 2. 如果服务器是打算直接把底层系统安装为Ubuntu的话还需制作系统U盘 安装 1.新建虚拟机调整基础配置 2.打开电源&#xff0c;进入安装界面&#xff08;到这一步就跟u盘安装步骤一致…

深度学习Week16-yolo.py文件解读(YOLOv5)

目录 简介 需要的基础包和配置 二、主要组件介绍 2.1 parse_model 2.2Detect类 2.3DetectionModel类 三、实验 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊…

JavaEE简单示例——动态SQL的<trim>属性

简单介绍&#xff1a; 在之前我们介绍过使用<where>和<set>可以帮我们动态的添加和删除一些关键字&#xff0c;但是这些只能操作特定的关键字&#xff0c;比如where和set&#xff0c;但是有一些时候我们需要操作的关键字并不是这些常见的关键字&#xff0c;而是一…

基于SSM的婴幼儿商城

基于SSM的婴幼儿商城 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; …

软件测试3年经验就能拿30K?

1.软件测试如何实现涨薪 首先涨薪并不是从8000涨到9000这种涨薪&#xff0c;而是从8000涨到15K加到25K的涨薪。基本上三年之内就可以实现。 如果我们只是普通的有应届毕业生或者是普通本科那我们就只能从小公司开始慢慢往上走。 有些同学想去做测试&#xff0c;是希望能够日…

springboot+vue员工宿舍报修系统 uniapp微信小程序开发的

目 录 目 录 III 第一章 概述 1 1.1 研究背景 1 1.2 开发意义 1 1.3 研究现状 1 1.4 研究内容 2 1.5 论文结构 2 第二章 开发技术介绍 1 2.2 微信开发者工具 1 2.3 mysql数据库介绍 1 2.4 MySQL环境配置 2 2.5 B/S架构 2 第三章 系统分析 1 3.1 可行性分析 1 3.1.1 技术可行性…

这次,我的CentOS又ping不通www.baidu.com了(gateway配置)

当我们保证了宿主机与虚拟机的ip地址在同一网段&#xff0c;并且我们使用虚拟机ping宿主机&#xff0c;与宿主机ping虚拟机都可以互相ping通的情况下虚拟机却ping不通外网了&#xff0c;由于涉及到了跨越网络访问&#xff0c;所以我们应该把问题聚焦在网关的配置上&#xff01;…

手工布署 java 项目

新建一个java springboot项目 maven 这是一个非常简易的 springBoot 的项目 使用 maven 的 package 工具进行打包 把包上传到 linux 的机器上&#xff0c; 确保 linux 机器上安装了 java jdk工具&#xff0c; 并且配置好了 JAVA_HOME 注意&#xff0c;helloworld 默认的是要使…

Rocky 9.1操作系统实现zabbix6.0的安装部署实战

文章目录前言一. 实验环境二. 安装zabbix过程2.1. 安装zabbix源2.2 安装zabbix相关的软件2.3 安装数据库并启动2.4 开始初始化数据库&#xff1a;2.5 创建数据库实例及对应的用户2.6 导入官网提供的数据2.7 配置zabbix 服务的配置文件2.8. 启动服务2.9 从网页进行安装2.10 登陆…