153 lines
3.3 KiB
Vue
153 lines
3.3 KiB
Vue
<template>
|
|
<v-form @submit.prevent="$emit('submit', { username, password, rememberMe })">
|
|
<v-text-field
|
|
v-model="username"
|
|
bg-color="surface"
|
|
class="mb-6 mb-md-4"
|
|
color="primary"
|
|
density="comfortable"
|
|
hide-details
|
|
:placeholder="props.accPlaceholder"
|
|
variant="outlined"
|
|
></v-text-field>
|
|
|
|
<v-text-field
|
|
v-model="password"
|
|
:append-inner-icon="showPassword ? mdiEyeOff : mdiEye"
|
|
bg-color="surface"
|
|
class="mb-6 mb-md-4"
|
|
color="primary"
|
|
density="comfortable"
|
|
hide-details
|
|
:placeholder="props.passwPlaceholder"
|
|
:type="showPassword ? 'text' : 'password'"
|
|
variant="outlined"
|
|
@click:append-inner="showPassword = !showPassword"
|
|
></v-text-field>
|
|
|
|
<slot name="verify"></slot>
|
|
|
|
<div class="d-flex align-center justify-space-between mb-6 mb-md-4">
|
|
<v-checkbox
|
|
v-model="rememberMe"
|
|
color="primary"
|
|
density="compact"
|
|
hide-details
|
|
:label="props.rememberMeLabel"
|
|
></v-checkbox>
|
|
<a
|
|
class="text-body-2 text-primary text-decoration-none"
|
|
:href="props.forgotPasswordHref || '#'"
|
|
:target="props.forgotPasswordTarget"
|
|
@click="handleForgotPasswordClick"
|
|
>
|
|
{{ props.forgotPasswordText }}
|
|
</a>
|
|
</div>
|
|
|
|
<v-btn
|
|
block
|
|
class="mb-6 font-weight-bold"
|
|
color="primary"
|
|
elevation="0"
|
|
height="48"
|
|
size="large"
|
|
type="submit"
|
|
>
|
|
{{ props.submitText }}
|
|
</v-btn>
|
|
</v-form>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { mdiEye, mdiEyeOff } from '@mdi/js'
|
|
import { onMounted, ref, watch } from 'vue'
|
|
const username = ref('')
|
|
const password = ref('')
|
|
const showPassword = ref(false)
|
|
const rememberMe = ref(false)
|
|
|
|
const props = defineProps({
|
|
passwPlaceholder: {
|
|
type: String,
|
|
default: '請輸入6位數密碼',
|
|
},
|
|
accPlaceholder: {
|
|
type: String,
|
|
default: '請輸入帳號',
|
|
},
|
|
rememberMeLabel: {
|
|
type: String,
|
|
default: '記住帳號',
|
|
},
|
|
forgotPasswordText: {
|
|
type: String,
|
|
default: '忘記密碼?',
|
|
},
|
|
forgotPasswordHref: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
forgotPasswordTarget: {
|
|
type: String,
|
|
default: undefined,
|
|
},
|
|
submitText: {
|
|
type: String,
|
|
default: '登入',
|
|
},
|
|
rememberStorageKey: {
|
|
type: String,
|
|
default: 'sklogin.remember.username',
|
|
},
|
|
})
|
|
|
|
const emit = defineEmits(['submit', 'forgot-password'])
|
|
|
|
onMounted(() => {
|
|
const saved = localStorage.getItem(props.rememberStorageKey)
|
|
if (saved) {
|
|
username.value = saved
|
|
rememberMe.value = true
|
|
}
|
|
})
|
|
|
|
watch([rememberMe, username], ([nextRemember, nextUsername]) => {
|
|
if (!nextRemember) {
|
|
localStorage.removeItem(props.rememberStorageKey)
|
|
return
|
|
}
|
|
|
|
if (!nextUsername) {
|
|
localStorage.removeItem(props.rememberStorageKey)
|
|
return
|
|
}
|
|
|
|
localStorage.setItem(props.rememberStorageKey, nextUsername)
|
|
})
|
|
|
|
function handleForgotPasswordClick(e: MouseEvent) {
|
|
emit('forgot-password', e)
|
|
if (!props.forgotPasswordHref) {
|
|
e.preventDefault()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
:deep(.v-field--variant-outlined) {
|
|
border-radius: 8px;
|
|
}
|
|
|
|
:deep(.v-btn) {
|
|
text-transform: none;
|
|
border-radius: 8px;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
:deep(.v-checkbox .v-label) {
|
|
font-size: 14px;
|
|
opacity: 1;
|
|
}
|
|
</style>
|