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

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

实现效果

核心代码实现

  • login.vue文件
html 复制代码
<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的配置
js 复制代码
import { createPinia } from "pinia";
const pinia = createPinia();

export default pinia;

登录退出功能的store

js 复制代码
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

js 复制代码
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;

打包

bash 复制代码
npm run ele:build

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

注意事项

  • win11的弹窗是正常显示

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

相关推荐
vim怎么退出7 分钟前
Dive into React——Diff 算法
前端·react.js·源码阅读
拾年2758 分钟前
别调 BERT 了:我用 Prompt 做了套 NLP 系统,20 分钟搞定
前端·人工智能
半个落月29 分钟前
别再死记变量提升了——从 V8 编译过程真正理解 JS 执行机制
前端
橘子星38 分钟前
别再懵圈!JS 执行机制的 “千层套路” 全揭秘
前端·javascript
GuWenyue38 分钟前
LeetCode 76 最小覆盖子串|JS 滑动窗口标准解法
前端·算法·面试
YHHLAI40 分钟前
前端 HTTP 请求 & LLM 接口开发
前端·网络协议·http
拾年27542 分钟前
__proto__ vs prototype:90% 的人分不清的 JavaScript 核心
前端·javascript·面试
国科安芯43 分钟前
国科安芯推出商业航天级抗辐照半双工 RS485 收发器 ASC485S2Y
前端·单片机·嵌入式硬件·架构·安全性测试
丑过三八线43 分钟前
Umi 运行时配置 app.tsx 详解
前端
提子拌饭1331 小时前
个人月事记录表应用 - 鸿蒙PC Electron框架完整实现指南
前端·javascript·华为·electron·前端框架·开源·鸿蒙系统