Skip to content

Commit 91d90fa

Browse files
committed
refactor(Login): 封装FluentUI的fluent-text-field和fluent-check-box,能够使用v-model进行双向绑定
1 parent a94635a commit 91d90fa

File tree

6 files changed

+131
-59
lines changed

6 files changed

+131
-59
lines changed

components.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ declare module 'vue' {
1111
ElIcon: typeof import('element-plus/es')['ElIcon']
1212
ElLink: typeof import('element-plus/es')['ElLink']
1313
ElText: typeof import('element-plus/es')['ElText']
14+
FluentCheckBox: typeof import('./src/components/fluent-ui/FluentCheckBox.vue')['default']
15+
FluentInput: typeof import('./src/components/fluent-ui/FluentInput.vue')['default']
16+
FluentUIButton: typeof import('./src/components/fluent-ui/FluentUIButton.vue')['default']
17+
FluentUIInput: typeof import('./src/components/fluent-ui/FluentUIInput.vue')['default']
1418
RouterLink: typeof import('vue-router')['RouterLink']
1519
RouterView: typeof import('vue-router')['RouterView']
1620
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!--
2+
author: 程旭
3+
description: 封装了的fluent-ui的CheckBox组件,为了能够使用v-model进行双向绑定
4+
date: 2025-04-06
5+
-->
6+
<template>
7+
<fluent-checkbox
8+
:checked="props.modelValue"
9+
:disabled="props.disabled"
10+
@change="onInput"
11+
>
12+
<slot></slot>
13+
</fluent-checkbox>
14+
</template>
15+
16+
<script lang="ts" setup>
17+
import { defineProps, defineEmits } from 'vue';
18+
19+
// 定义 emit 事件
20+
const emit = defineEmits(['change', 'update:modelValue']);
21+
22+
const props = defineProps({
23+
modelValue: {
24+
type: Boolean,
25+
default: false,
26+
},
27+
disabled: {
28+
type: Boolean,
29+
default: false,
30+
},
31+
});
32+
33+
// 处理 change 事件,更新 v-model
34+
const onInput = (event: Event) => {
35+
const checkboxValue = (event.target as HTMLInputElement).checked;
36+
emit('update:modelValue', checkboxValue); // 更新 v-model
37+
emit('change', checkboxValue); // 触发 change 事件
38+
};
39+
40+
// 禁用 console.warn 和 console.error
41+
console.warn = () => {}; // 禁用警告
42+
console.error = () => {}; // 禁用错误
43+
44+
</script>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!--
2+
author: 程旭
3+
description: 封装了的fluent-ui的Input组件,为了能够使用v-model进行双向绑定
4+
date: 2024-04-01
5+
-->
6+
<template>
7+
<div>
8+
<fluent-text-field
9+
:value="props.modelValue"
10+
@input="onInput($event)"
11+
@change="$emit('change', $event)"
12+
:placeholder="props.placeholder"
13+
:label="props.label"
14+
style="width: 100%;"
15+
/>
16+
</div>
17+
</template>
18+
19+
<script lang="ts" setup>
20+
import { defineProps, defineEmits } from 'vue';
21+
22+
const emit = defineEmits(['change', 'input', 'update:modelValue']);
23+
const props = defineProps({
24+
modelValue: {
25+
type: String,
26+
default: '',
27+
},
28+
placeholder: {
29+
type: String,
30+
default: '',
31+
},
32+
label: {
33+
type: String,
34+
default: '',
35+
},
36+
});
37+
38+
const onInput = (event: Event) => {
39+
const inputValue = (event.target as HTMLInputElement).value;
40+
emit('update:modelValue', inputValue);
41+
console.log('inputValue', inputValue);
42+
emit('input', event);
43+
};
44+
45+
// 禁用 console.warn
46+
console.warn = () => {}; // 禁用警告
47+
48+
</script>

src/route/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

22
import { createRouter,createWebHashHistory } from "vue-router";
33

4-
const routes = [
4+
import type { RouteRecordRaw } from "vue-router";
5+
6+
const routes: RouteRecordRaw[] = [
57
{
68
path:'/',
79
redirect:'/login'

src/types/ElectronRawApi.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
declare interface Window {
2+
electron: {
3+
setWindowFrameVisible: (visible: boolean) => void;
4+
setWindowTitle: (title: string) => void;
5+
resizeWindow: (width: number, height: number) => void;
6+
};
7+
}

src/view/Login.vue

Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,34 @@
1919
<!-- 登录表单 -->
2020
<div v-if="isLogin" class="login-form flex-column-all-center">
2121
<div class="input-field flex-column-justify-center">
22-
<fluent-text-field label="FM号" placeholder="请输入FM号" class="form-input"
23-
@input="handleLoginUserNameInput"></fluent-text-field>
24-
<fluent-text-field label="密码" type="password" placeholder="请输入密码" class="form-input"
25-
@input="handleLoginPasswordInput" />
22+
<FluentInput label="用户名" placeholder="请输入用户名" class="form-input" v-model="loginData.number">
23+
</FluentInput>
24+
<FluentInput label="密码" type="password" placeholder="请输入密码" class="form-input"
25+
v-model="loginData.password"></FluentInput>
2626
</div>
2727
<div class="tip" v-if="messageLoginTipShow">
2828
<el-text style="color: red;">{{ messageLogin }}</el-text>
2929
</div>
3030
<div class="tool">
31-
<fluent-checkbox class="remember-me" @input="handleLoginRememberMeInput">记住我</fluent-checkbox>
31+
<!--有问题,无法实现双向绑定-->
32+
<FluentCheckBox class="remember-me" v-model="loginData.isRemeberMe">记住我</FluentCheckBox>
33+
<!-- <fluent-checkbox class="remember-me" @input="handleLoginRememberMeInput">记住我</fluent-checkbox> -->
3234
<el-link class="register" @click="isLogin = !isLogin">注册</el-link>
3335
</div>
3436
<fluent-button class="login form-input" @click="login" appearance="accent">登录</fluent-button>
3537
</div>
3638
<!-- 注册表单 -->
3739
<div v-else class="register-form">
3840
<div class="input-field flex-column-justify-center">
39-
<fluent-text-field label="邮箱" placeholder="请输入邮箱地址" class="form-input"
40-
@input="handleRegisterEmailInput"></fluent-text-field>
41-
<fluent-text-field label="密码" type="password" placeholder="请输入密码" class="form-input"
42-
@input="handleRegisterPasswordInput" />
43-
<fluent-text-field label="再次输入密码" type="password" placeholder="请再次输入密码" class="form-input"
44-
@input="handleRegisterConfirmPasswordInput" />
41+
<FluentInput label="邮箱" placeholder="请输入邮箱地址" class="form-input"
42+
v-model="registerData.email"></FluentInput>
43+
<FluentInput label="密码" type="password" placeholder="请输入密码" class="form-input"
44+
v-model="registerData.password"></FluentInput>
45+
<FluentInput label="再次输入密码" type="password" placeholder="请再次输入密码" class="form-input"
46+
v-model="registerData.confirmPassword"></FluentInput>
4547
<div class="flex-row-space-between validate-code">
46-
<fluent-text-field label="验证码" placeholder="请输入验证码" class="form-input"
47-
@input="handleRegisterValidateCodeInput"></fluent-text-field>
48+
<FluentInput label="验证码" placeholder="请输入验证码" class="form-input"
49+
v-model="registerData.validateCode"></FluentInput>
4850
<fluent-button class="validate-code-btn" appearance="accent" @click="getVerificationCode"
4951
:disabled="verificating">{{ verificating ? `${timeLeft} 秒后重试` : '获取验证码' }}</fluent-button>
5052
</div>
@@ -63,10 +65,13 @@
6365
import { watch } from 'vue';
6466
import { onMounted, ref } from 'vue';
6567
import { toggleDark, isDark } from '../util/theme';
68+
69+
import FluentInput from '../components/fluent-ui/FluentInput.vue';
70+
import FluentCheckBox from '../components/fluent-ui/FluentCheckBox.vue';
6671
//状态
6772
6873
interface LoginData {
69-
number: number;
74+
number: string;
7075
password: string;
7176
isRemeberMe: boolean;
7277
}
@@ -90,7 +95,7 @@ const timeLeft = ref(5);
9095
const timer = ref<NodeJS.Timeout | null>(null);
9196
9297
const loginData = ref<LoginData>({
93-
number: 0,
98+
number: '',
9499
password: '',
95100
isRemeberMe: false
96101
})
@@ -147,7 +152,7 @@ const setMessage = (msg: string) => {
147152
const validateForm = () => {
148153
if (isLogin.value) {
149154
if (!loginData.value.number) {
150-
setMessage('用户名不能为空');
155+
setMessage('FM号不能为空');
151156
return false;
152157
}
153158
@@ -197,7 +202,7 @@ const validateForm = () => {
197202
setMessage('密码只能包含字母、数字和下划线');
198203
return false;
199204
}
200-
205+
201206
if (registerData.value.password.length > 20) {
202207
setMessage('密码长度不能大于20位');
203208
return false;
@@ -218,49 +223,11 @@ const validateForm = () => {
218223
return true;
219224
}
220225
221-
222-
const handleLoginUserNameInput = (event: Event) => {
223-
const target = event.target as HTMLInputElement;
224-
loginData.value.number= Number(target.value);
225-
}
226-
227-
228-
229-
const handleRegisterEmailInput = (event: Event) => {
230-
const target = event.target as HTMLInputElement;
231-
registerData.value.email = target.value;
232-
}
233-
234-
const handleRegisterPasswordInput = (event: Event) => {
235-
const target = event.target as HTMLInputElement;
236-
registerData.value.password = target.value;
237-
}
238-
239-
const handleRegisterConfirmPasswordInput = (event: Event) => {
240-
const target = event.target as HTMLInputElement;
241-
registerData.value.confirmPassword = target.value;
242-
}
243-
244-
const handleRegisterValidateCodeInput = (event: Event) => {
245-
const target = event.target as HTMLInputElement;
246-
registerData.value.validateCode = target.value;
247-
}
248-
249-
250-
const handleLoginPasswordInput = (event: Event) => {
251-
const target = event.target as HTMLInputElement;
252-
loginData.value.password = target.value;
253-
}
254-
255-
const handleLoginRememberMeInput = (event: Event) => {
256-
const target = event.target as HTMLInputElement;
257-
loginData.value.isRemeberMe = target.checked;
258-
}
259-
260226
const login = () => {
261227
if (!validateForm()) {
262228
return;
263229
}
230+
console.log('loginData', loginData.value);
264231
265232
}
266233
@@ -306,8 +273,8 @@ onMounted(() => {
306273

307274
<style lang="scss" scoped>
308275
.login-view {
309-
width: 300px; // 可以根据需要设置具体的宽度
310-
height: 400px; // 可以根据需要设置具体的高度
276+
width: 300px;
277+
height: 400px;
311278
display: flex;
312279
justify-content: center;
313280
align-items: center;

0 commit comments

Comments
 (0)