vue3+TS+Pinia+Vite项目实战之一

news2025/1/21 22:11:07

文章目录

  • 一、创建项目
    • 1.1 使用脚手架创建项目
    • 1.2 初始化项目
  • 二、登录页面的开发
  • 三、使用vite-plugin-mock模拟后台接口返回数据
  • 四、前端调用后端接口使用axios
  • 五、首页layout
  • 六、动态菜单
  • 七、设置需要登录才能访问某些页面


一、创建项目

1.1 使用脚手架创建项目

npm init vue@latest

1.2 初始化项目

App.vue

<template>
  <RouterView />
</template>

<script setup lang="ts"></script>

<style scoped></style>

删除多余不要的组件
在这里插入图片描述
创建路由
src/router/index.ts

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

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/login',
      name: 'Login',
      component: () => import('../views/LoginView.vue')
    }
  ]
})

export default router

在src/views/LoginView.vue

<template>
  <div>Login</div>
</template>

<script setup lang="ts"></script>

<style lang="scss" scoped></style>

引入element-plus 可去官网查看如何引入
安装normalize.css

npm install normalize.css

在这里插入图片描述

二、登录页面的开发

安装sass

npm install sass

在这里插入图片描述
登录页的静态页面

<template>
  <div class="login-container">
    <h2>登录</h2>
    <el-form ref="ruleFormRef" :model="formData" status-icon :rules="rules">
      <el-form-item prop="userName">
        <el-input v-model="formData.userName" placeholder="userName" />
      </el-form-item>

      <el-form-item prop="password">
        <el-input v-model="formData.password" placeholder="password" type="password" />
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="submitForm(ruleFormRef)">登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
const ruleFormRef = ref<FormInstance>()
const formData = reactive({
  userName: '',
  password: ''
})

const rules = reactive<FormRules>({
  userName: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
})

const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid) => {
    if (valid) {
      console.log('submit!')
    } else {
      console.log('error submit!')
      return false
    }
  })
}
</script>

<style lang="scss" scoped>
.login-container {
  // 要加上100%
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  .el-form {
    width: 300px;
    .el-button {
      width: 100%;
    }
  }
}
</style>

三、使用vite-plugin-mock模拟后台接口返回数据

安装方法

npm i  mockjs -S
npm i vite-plugin-mock -D

配置vite-plugin-mock
在这里插入图片描述
开始使用mock使其返回数据
在这里插入图片描述

四、前端调用后端接口使用axios

安装axios

npm i axios -S

简单封装一下axios
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在mock中添加逻辑返回真实的数据
/mock/user.ts

import type { MockMethod } from 'vite-plugin-mock'

// 模拟用户账户
const tokens = {
  admin: 'admin-token',
  editor: 'editor-token'
}

export default [
    {
      // 请求到这里的路径我来接收处理
      url: '/user/login',
      method: 'post',
      // 响应回去请求的数据
      // {body} 解构出来body的数据
      response({body}){
        const userName = body.userName
        const token = tokens[userName]
        if(token){
          return {
            code: 200,
            data: token
          }
        }else{
          return {
            code: 400,
            message: '账号或密码不正确'
          }
        }
      }
    }
] as MockMethod[]

在axios响应拦截器中处理接口错误在页面提示
在这里插入图片描述
登录成功跳转到首页
在这里插入图片描述
添加首页路由
在这里插入图片描述
在src/views/HomeView.vue

五、首页layout

在这里插入图片描述
在这里插入图片描述
调整路由
在这里插入图片描述
在这里插入图片描述
调整layout的样式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
现在可以在element-plus中去复制一个菜单贴过来了。
LayoutSidebar.vue

<template>
  <div class="container">
    <el-menu
      background-color="#545c64"
      active-text-color="#ffd04b"
      text-color="#fff"
      default-active="1"
    >
      <el-menu-item index="1">首页</el-menu-item>
      <el-menu-item index="2">菜单2</el-menu-item>
    </el-menu>
  </div>
</template>

<script setup lang="ts"></script>

<style lang="scss" scoped>
.container {
  width: 200px;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  :deep(.el-menu) {
    height: 100%;
  }
}
</style>

六、动态菜单

现在的菜单是写死的,我们需要根据路由动态生成菜单。
将路由导出来使其在别的文件中能够使用。
调整src/router/index.ts

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

export const constantRoutes = [
  {
    path: '/login',
    name: 'Login',
    component: () => import('../views/LoginView.vue')
  },
  {
    path: '/',
    name: 'Home',
    component: () => import('../components/LayoutIndex.vue'),
    redirect: '/dashboard',
    children: [
      {
        path: 'dashboard', 
        component: () => import('@/views/DashboardView.vue')
      }
      
    ]
  }
]

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: constantRoutes
})

export default router

调整 src/components/LasyoutSidebar.vue
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当只有一个子路由,我们只显示子路由的调整
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击菜单并没有跳转,继续调整…
在这里插入图片描述
总结动态菜单:就是通过递归组件将路由中数据展示在动态菜单上。

七、设置需要登录才能访问某些页面

登录成功将token存起来
在这里插入图片描述
设置前置路由守卫,没token你就去/login页面吧
在这里插入图片描述
退出登录
LayoutNavbar.vue

<template>
  <div class="layout-navbar">
    <el-button @click="handleLogout" style="margin-left: auto" type="primary">退出登录</el-button>
  </div>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
const router = useRouter()
function handleLogout() {
  localStorage.removeItem('token')
  router.push('/login')
}
</script>

<style lang="scss" scoped>
.layout-navbar {
  height: 50px;
  border-bottom: 1px solid #ccc;
  box-sizing: border-box;
  padding: 0 16px;
  display: flex;
  align-items: center;
}
</style>

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

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

相关文章

【网络安全】SQL注入--报错注入

报错注入报错注入定义代码展示常用的报错语句1.获取数据库名称2.获取mysql账号密码3.获取表名4.获取字段名5.获取账号密码报错注入定义 报错注入&#xff1a;利用sql语句的不规范&#xff0c;获取相关sql提示信息 代码展示 常用的报错语句 select first_name, last_name FROM…

【小程序】django笔记2

templates路径除了在settings中的templates的DIR[]中申明还有什么别的方法&#xff1f;已知&#xff0c;django底层根据app注册顺序查找各app文件中的templates文件夹&#xff0c;在其中搜索目标模版文件。已知&#xff0c;app注册在settings中的INSTAll-APPS里。已知&#xff…

MyBatis基础增删改查

文章目录MyBatis1. MyBatis是什么&#xff1f;2. 为什么要学习MyBatis3. 第一个MyBatis环境搭建1)添加MyBatis框架支持2)配置MyBatis相关配置文件3)添加代码4. 解决类的属性名和数据表字段名不一致(resultMap)5. 增加操作1)返回受影响的行数2)返回自增的id6. 修改操作7. 删除操…

类和对象深入讲解(1)

目录 1.类和对象的初步认识 1.1面向过程和面向对象的区别 1.2类的引入 1.3内的定义 1.4类的访问限定符及封装 1.4.1访问限定符 1.4.2 封装 1.5类的作用域 1.6类对象模型 1.6.1如何计算类对象大小 1.类和对象的初步认识 1.1面向过程和面向对象的区别 C语言是面向过程的…

大模型混战,阿里百度华为谁将成就AI时代的“新地基”?

从算力基础到用户生态&#xff0c;群雄逐鹿大模型 自2022年stable diffusion模型的进步推动AIGC的快速发展后&#xff0c;年底&#xff0c;ChatGPT以“破圈者”的姿态&#xff0c;快速“吸粉”亿万&#xff0c;在全球范围内掀起了一股AI浪潮&#xff0c;也促使了众多海外巨头竞…

Golang每日一练(leetDay0030)

目录 88. 合并两个有序数组 Merge Sorted Array &#x1f31f; 89. 格雷编码 Gray Code &#x1f31f;&#x1f31f; 90. 子集 II Subsets II &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/…

为什么要创建FAQ?这篇文章告诉你

什么是FAQ 通过上述的引入大家应该也了解到了&#xff0c;FAQ是为了“解决问题”而存在的。FAQ是英文Frequently Asked Questions的缩写&#xff0c;中文意思就是“经常问到的问题”&#xff0c;或者更通俗地叫做“常见问题解答”。FAQ是当前网络上提供在线帮助的主要手段&…

小程序开发收费价目表

小程序作为一种新兴应用形式&#xff0c;正在逐渐成为企业和个人推广、运营的重要手段。然而&#xff0c;小程序开发的价格因项目规模和复杂程度差异较大&#xff0c;令不少人望而却步。本文将从小程序开发的相关因素入手&#xff0c;探讨小程序开发的价格范围和算法。 一、小…

【JLink仿真器】盗版检测、连接故障、检测不到芯片问题

【JLink仿真器】盗版检测、连接故障、检测不到芯片问题一、问题描述二、解决方法1、降低驱动&#xff08;解决非法问题以及连接故障&#xff09;2、SWD引脚被锁&#xff08;解决检测不到芯片&#xff09;三、说明一、问题描述 盗版检测&#xff1a;the connected probe appear…

【Linux】Mysql之索引的基本操作

一、为什么要使用索引 索引就是根据表中的一列或若干列按照一定顺序建立的列值与记录行之间的对应关系表&#xff0c;实质上是一张描述索引列的列值与原表中记录行之间一 一对应关系的有序表。 索引是 MySQL 中十分重要的数据库对象&#xff0c;是数据库性能调优技术的基础&…

GraphCL方法介绍(Graph Contrastive Learning with Augmentations)

论文链接&#xff1a;https://arxiv.org/pdf/2010.13902.pdf 附录链接&#xff1a;https://yyou1996.github.io/files/neurips2020_graphcl_supplement.pdf 代码链接&#xff1a;https://github.com/Shen-Lab/GraphCL 1 图的数据增强 我们专注于图级扩充。给定 M 个图的数…

【分布式】熔断、降级傻傻分不清楚-熔断和降级的真实关系

文章目录前言降级熔断什么是服务熔断熔断和降级的关系降级方式1、熔断降级&#xff08;不可用&#xff09;2、超时降级3、限流降级总结前言 刚开始我以为熔断和降级是一体的&#xff0c;以为他们必须配合使用&#xff1b; 只不过名字不一样而已&#xff0c;但是当我经过思考过…

[架构之路-164]-《软考-系统分析师》-3-操作系统基本原理-文件系统(文件的逻辑组织、文件的物理组织、硬盘空间管理、分布式文件系统)

目录 3 . 4 文件系统 3.4.1文件的组织结构 1 . 逻辑结构 2 . 物理结构 3 . 树形文件结构 3.4.2 硬盘存储空间管理 1 . 空闲文件目录 2 . 空闲块链 3 . 位示图法 4 . 成组链接法 3.4.3分布式文件系统 1. D F S 的特点 2. DFS 的组成 3. DFS 的架构 3 . 4 文件系统…

腾讯云服务器TencentOS系统安装宝塔Linux面板命令

腾讯云服务器TencentOS Server操作系统安装宝塔Linux面板命令选择CentOS安装脚本即可&#xff0c;TencentOS用户态环境与CentOS保持兼容&#xff0c;在CentOS上开发的应用程序可直接在TencentOS Server上运行。腾讯云百科分享腾讯云服务器TencentOS操作系统安装宝塔Linux面板命…

客户端ack模块的实现

文章目录背景第一版设计第二版设计第三、四版设计写在最后背景 所谓客户端ack模块是在我们推送服务中一个技术需求&#xff0c;本文主要介绍其迭代过程。 首先简单介绍下推送服务的架构&#xff0c;如下图。用户请求ws服务&#xff0c;建立ws长连接&#xff0c;并通过login和…

类和对象(C++11)

目录 一、类的定义 1.定义与声明放一起 2.定义与声明分开 二、类的访问限定符及封装 1.类的访问限定符 2.类的封装 三、类的实例化 四、类对象 1.类对象的存储方式 2.计算类对象的大小 面试题 1.结构体怎么对齐&#xff1f; 为什么要进行内存对齐&#xff1f; 2.如…

Python数据结构与算法-树

一、树的概念详情见 https://blog.csdn.net/little_limin/article/details/129845592 Python数据结构与算法-堆排序&#xff08;NB组&#xff09;—— 一、树的基础知识二、树的实例&#xff1a;模拟文件系统1、树的存储树结构也是链式存储的&#xff0c;与链表的结构相似&…

java通过URLClassLoader类加载器加载外部jar

相信在实际工作中&#xff0c;大家可能会遇到这种需求&#xff0c;这个jar是外部的&#xff0c;并没有添加到项目依赖中&#xff0c;只能通过类加载器加载并调用相关方法。 这种jar加载&#xff0c;其实也简单&#xff0c;我们通过普通的URLClassLoader就可以加载。代码如下所示…

netfilter filter表

iptables是linux下常用的一个防火墙软件&#xff0c;可以实现对网络访问的各种限制。iptables相当于防火墙的客户端&#xff0c;与用户进行交换&#xff0c;其后台依赖于内核的netfilter模块。iptables的各种配置&#xff0c;最终都是netfilter模块来实现的。 iptables分为4个…