Vue 3+Vite+Eectron从入门到实战系列之(五)一后台管理登录页

news2024/11/25 0:38:40

前面已经讲了不少基础知识,这篇开始,我们进行实操,做个后台管理系统,打包成多端的,可安装的桌面app!!其中,登录,退出的提示信息用系统的提示,不使用elemengplus的弹窗提示!!

请添加图片描述

实现效果

请添加图片描述

核心代码实现

  • login.vue文件
<template>
  <div class="login-form animated puffIn">
    <div class="login-form__left"></div>
    <div class="login-form__right">
      <h2>荣耀科技财务管理系统</h2>
      <el-form
        :model="loginForm"
        ref="loginFormRef"
        size="large"
        show-message
        label-position="top"
        label-width="100px"
        :rules="rules"
        status-icon
      >
        <el-form-item label="用户名:" prop="username">
          <el-input
            v-model="loginForm.username"
            placeholder="请输入用户名"
          ></el-input>
        </el-form-item>
        <el-form-item label="密码:" prop="password">
          <el-input
            type="password"
            v-model="loginForm.password"
            placeholder="请输入密码"
          ></el-input>
        </el-form-item>

        <el-form-item>
          <el-button
            class="login-btn"
            type="primary"
            @keydown.enter="handleKeyDownLogin"
            @click.native.prevent="handleLogin"
            >登录</el-button
          >
        </el-form-item>
        <el-form-item>
          <el-button
            class="registry-btn"
            type="success"
            @click.native.prevent="handleRegister"
            >注册</el-button
          >
        </el-form-item>
        <el-form-item>
          <div class="login-ctrl">
            <el-checkbox
              label="记住我"
              v-model="loginForm.checked"
            ></el-checkbox>
            <el-link type="primary">忘记密码?</el-link>
          </div>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, toRaw, onMounted, onUnmounted } from 'vue'
import userStore from '@/store/user'
import { useRouter } from 'vue-router'

const loginFormRef = ref(null)
const router = useRouter()
const sysUser = userStore()
const rules = reactive({
  username: [
    { required: true, message: '用户名不能为空', trigger: 'blur' },
    { min: 3, max: 5, message: '用户名长度必须是3到5位', trigger: 'blur' }
  ],
  password: [
    {
      required: true,
      message: '密码不能为空',
      trigger: 'change'
    },
    { min: 6, max: 6, message: '用户名长度必须是6位', trigger: 'blur' }
  ]
})
const loginForm = ref({
  username: '',
  password: '',
  checked: false
})

const handleKeyDownLogin = (e) => {
  if (e.keyCode === 13) {
    handleLogin()
  }
}

onMounted(() => {
  window.addEventListener('keydown', handleKeyDownLogin)
})
onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDownLogin)
})

const handleLogin = async () => {
  const status = await loginFormRef.value.validate()
  if (status) {
    const data = toRaw(loginForm.value)
    const isLogin = await sysUser.sysLogin(data)
    // 跳转到首页
    if (isLogin) {
      router.push('/')
    } else {
      window.electronAPI.loginError()
    }
  } else {
  }
}
const handleRegister = () => {
  console.log('register')
  window.electronAPI.register()
}
</script>

<style scoped lang="scss">
.login-form {
  padding: 0 20px 0 0;
  border: 1px solid #f7f7f7;
  border-radius: 20px;
  box-shadow: 0 0 30px #c1c1c1;
  background: rgba(255, 255, 255, 0.5);
  position: absolute;
  top: 20%;
  right: 300px;
  display: flex;
  &__left {
    width: 480px;
    height: 500px;
    background: url(../../assets/images/bg1.png) no-repeat center center;
    background-size: 100% 100%;
  }
  &__right {
    width: 480px;
    height: 500px;
    padding: 20px;
    box-sizing: border-box;
    h2 {
      text-align: center;
      margin-bottom: 30px;
      font-size: 32px;
      font-weight: bold;
      color: #333;
    }
    .login-ctrl {
      display: flex;
      justify-content: space-between;
      width: 100%;
    }
    .el-button {
      width: 100%;
    }
    .login-btn {
      background: linear-gradient(
        147deg,
        #8ec5fc 13.33%,
        #1a2cab 46.22%,
        #610cb3 87.97%
      );
      border: none;
    }
  }
}
</style>
  • pinia的配置
import { createPinia } from "pinia";
const pinia = createPinia();

export default pinia;

登录退出功能的store

import { defineStore } from 'pinia'
const userStore = defineStore('user', {
  state: () => ({
    userInfo: {
      name: 'admin',
      avatar: '',
      roles: ['admin'],
      introduction: 'I am a super administrator'
    },
    token: window.localStorage.getItem('token')
  }),
  getters: {
    username() {
      return this.userInfo.name
    }
  },
  actions: {
    setToken(token) {
      this.token = token
    },
    setUserInfo(userInfo) {
      this.userInfo = userInfo
    },
    sysLogin(data) {
      return new Promise((resolve, reject) => {
        if (data.username === 'admin' && data.password === '123456') {
          window.electronAPI.loginSuccess(data)
          // 登录成功后,将token存入本地
          this.setToken(data.username)
          window.localStorage.setItem('token', data.username)
          resolve(true)
        } else {
          window.electronAPI.loginError()
        }
      })
    },
    sysLogout() {
      return new Promise((resolve, reject) => {
        window.electronAPI.logout()
        this.setToken('')
        window.localStorage.removeItem('token')
        resolve(true)
      })
    }
  }
})
export default userStore

菜单收起展开的store

import { defineStore } from "pinia";
const useSysStore = defineStore("sys", {
  state: () => ({
    collapse: false,
  }),
  getters: {
    isCollapse() {
      return this.collapse;
    },
  },
  actions: {
    toggleCollapse() {
      console.log(this.collapse);
      this.collapse = !this.collapse;
    },
  },
});
export default useSysStore;

打包

npm run ele:build

打包文件里面安装到本地即可以使用

在这里插入图片描述

注意事项

如果电脑系统是win10,很可能弹不出右下角的系统弹窗,是系统处于安全角度的考虑,但是mac和win11是没有问题的,这里贴出解决方案。
electron在win10不弹窗的bug

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

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

相关文章

Java生成图形验证码

1、加依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency> 2、写接口&#xff0c;这块不需要登录成功才能操作的&#xff0c;所以写controller就行了…

基于Hadoop的网购笔记本电脑大数据分析与可视化系统

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍数据采集过程数据预处理Hadoop大数据分析可视化展示每文一语 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 本项目首先通过爬虫获取京东…

【C++】产生拷贝构造的三种形式

目录 用已存在的类对象去初始化同类另一个对象当函数类的形参是对象&#xff0c;调用函数形参和实参进行结合当函数的返回值是对象&#xff0c;函数执行完成返回调用者时 用已存在的类对象去初始化同类另一个对象 Date d1; Date d2(d1); Date d3 d2; //也会调用拷贝构造注意赋…

谷粒商城实战笔记-168-缓存-SpringCache-整合体验@Cacheable

文章目录 一&#xff0c;168-缓存-SpringCache-整合&体验Cacheable1&#xff0c;引入Spring Cache依赖2&#xff0c;配置3&#xff0c;启用cache4&#xff0c;在查询数据库的方法上加上注解Cacheable5&#xff0c;测试 二&#xff0c;169-缓存-SpringCache-Cacheable细节设…

LeetCode_sql_day16(601.体育馆的人流量)

描述&#xff1a;601. 体育馆的人流量 - 力扣&#xff08;LeetCode&#xff09; 编写解决方案找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。 返回按 visit_date 升序排列 的结果表。 输入Stadium表: ----------------------------- | id | visit_date | peop…

Linux系统移植——系统移植初步介绍(一)

一、嵌入式Linux系统软件组成及分布 1.1 内核&#xff08;Kernel&#xff09; 功能&#xff1a;负责管理硬件资源、进程调度、内存管理、文件系统、网络等。分布&#xff1a;通常是定制的Linux内核&#xff0c;以适应特定的硬件平台和应用需求。 1.2 根文件系统&#xff08;…

sql实验代码整理:创建表文件Student、Course、Sc完成下列问题

使用SQL语句创建数据库students. create database students; 创建表文件Student、Course、Sc&#xff0c;表结构如表3-7~表3-9所示。 代码及运行结果&#xff1a; 代码及运行结果&#xff1a; 代码及运行结果&#xff1a; 为表Student 添加地址列Address&#xff0c;数据类型为…

14.3 Matplotlib与Seaborn数据可视化

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

汽车保养系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;门店信息管理&#xff0c;员工信息管理&#xff0c;配件信息管理&#xff0c;保养信息管理&#xff0c;管理员管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页…

k8s部署ingress-nginx

一、拉取ingress-nginx的安装代码 地址&#xff1a;https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/cloud/deploy.yaml 如果上面的地址访问不通的话&#xff0c;可以直接使用下面的内容&#xff1a; 由于官方镜像存放…

Keepalived详解

目录 1、高可用集群keepalived 高可用集群 VRRP 相关概念 keepalived 简介 2、基础实验环境搭建 3、keepalived的虚拟路由管理 全局配置 ​编辑 配置虚拟路由器 4、虚拟路由的通讯设置 5、keepalived的日志分离 6、实现独立子配置文件 7、keepalived的抢占模式和非抢占…

ubuntu 20 安装mysql workbench 过程

ubuntu 20 安装mysql workbench 过程_ubuntu 安装mysql workbench-CSDN博客 How To Install And Use MySQL Workbench On Ubuntu 18.04 or 20.04 MySQL :: Begin Your Download sudo apt install ./mysql-apt-config_0.8.32-1_all.deb snap install mysql-workbench-communi…

【鸿蒙学习】HarmonyOS应用开发者基础 - 从简单的页面开始

学完时间&#xff1a;2024年8月13日 我的纸飞机呀&#xff01;飞呀飞&#xff01;飞到了代码中&#xff01;&#xff01;&#xff01; 一、前言叨叨 今天是HarmonyOS学习教学课第一课的第五课内容了&#xff0c;课后练习的人数已经降到了4150人了&#xff0c;预测下到 ”Harmon…

Win10 去掉桌面右上角 了解有关此图片的信息

1. 进入注册表 Win R运行regedit 2. 找到以下路径 计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel 3. 新建 DWORD&#xff08;32位&#xff09;值&#xff08;D&#xff09; 右击 NewStartPanel新建 DWORD…

前端技术day01-HTML入门

一、前端介绍 技术描述HTML用于构建网站的基础结构的CSS用于美化页面的&#xff0c;作用和化妆或者整容作用一样JS实现网页和用户的交互Vue主要用于将数据填充到html页面上的Element主要提供了一些非常美观的组件 二、工具软件 VsCode 在前端领域&#xff0c;有一个公认好用…

C语言问答进阶--6、函数(1)

A&#xff1a;现在我们将研究函数这个概念。 其实这个概念很简单&#xff0c;和中学的时候学的yf(x)来对照着看&#xff0c;对于一个参数x&#xff0c;会得到一个值y&#xff0c;就会发现它和C中的函数是一个道理。 只是C函数中可以包含不传入任何参数的函数。 A&#xff1a;函…

自学嵌入式第十九天高级编程篇 文件2

标准IO的返回值判断 feof&#xff1a;判断文件流指针是否到达结尾。 feof(src) //如果文件流指针到达末尾&#xff0c;函数返回值为真 ferror&#xff1a;判断文件流指针是否出错。搭配clearerr使用可以跳过报错的地方&#xff0c;读取后面的数据 ferror(src) //如…

短视频SDK解决方案,良好的二次开发可扩展性

短视频已成为当代社交与内容消费的重要载体&#xff0c;其影响力与日俱增&#xff0c;面对这一蓬勃发展的市场&#xff0c;如何高效、创新地打造短视频应用&#xff0c;成为众多开发者和企业的核心关切。在此背景下&#xff0c;美摄科技凭借其深厚的技术积累与前瞻性的市场洞察…

奇异值分解(SVD)

1 奇异值分解(SVD)简介 Beltrami 和 Jordan 被认为是奇异值分解&#xff08;Singular Value Decomposition&#xff0c;SVD&#xff09;的共同开创者&#xff0c;二人于19世纪70年代相继提出了相关理论。奇异值分解主要解决的问题是数据降维。在高维度的数据中&#xff0c;数据…

什么是流批一体?怎样理解流批一体?

目录 一、流式处理与批量处理概述 1.流式处理 2.批量处理 3.流批一体的定义 二、流批一体的关键特点 三、流批一体的技术实现 四、应用场景 五、实施流批一体的考虑因素 流批一体听起来很简单&#xff0c;但内涵却十分复杂。它包含了计算语义、编程模型、API、调度、执行、shuf…