前面已经讲了不少基础知识,这篇开始,我们进行实操,做个后台管理系统,打包成多端的,可安装的桌面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