vue 记住密码功能

   <template>
    <div class="bg">
        <div style="position: relative;margin-left:300px;margin-top:250px;">
            <div class="logo"></div>
            <div class="name">
                XXXX平台
            </div>
            <div class="beian">
                XXXXX科技有限公司 丨 京ICP备XXXX号-X
                <p>增值电信业务经营许可证 京XXXX</p>
            </div>
        </div>
        <!--登录-->
        <div class="form" style="position: absolute;right:300px;top:100px;" v-if="navIndex == 0">
            <div class="title2">欢迎登录</div>
            <div class="tips2">账号密码登录</div>
            <div class="tips3"></div>
            <div class="formField">
                <v-form ref="signInForm" style="margin-top: 100px;">
                    <v-text-field :label="$t('username')" :rules="formRules.account" clearable
                                  v-model="formData.account"
                                  variant="underlined"></v-text-field>
                    <v-text-field :append-inner-icon="passwordInputType === 'password' ? 'visibility' : 'visibility_off'" :label="$t('password')" :rules="formRules.password"
                                  :type="passwordInputType" @click:append-inner="passwordInputType = passwordInputType === 'password' ? 'text' : 'password'" @keyup.enter="submit" clearable
                                  v-model="formData.password"
                                  variant="underlined"></v-text-field>
                </v-form>
                <div class="text-red" v-if="errorMsg">{{ errorMsg }}</div>
                <div class="mt-5 d-flex justify-space-between">
                    <div class="container">
                        <input @click="remberPassWord" color="primary" type="checkbox" v-model="rememberMe" variant="text">记住密码
                        <v-btn @click="navIndex= 1" color="primary" variant="text">手机号注册</v-btn>
                    </div>
                    <div @click="submit" class="btn" loading="submitting" style="color: #ffffff !important;">登录</div>
                </div>
            </div>
        </div>
        <!--注册-->
        <div class="form" style="position: absolute;right:300px;top:100px;" v-if="navIndex == 1">
            <div class="title2">账号注册</div>
            <div style="margin-top:20px;">
                <v-form ref="signUpForm">
                    <v-text-field :error-messages="fieldErrors.phone" :label="$t('手机号码')"
                                  :rules="formRules2.phone"
                                  @update:modelValue="handleFieldUpdate('phone')" clearable
                                  v-model="formData2.phone"
                                  variant="underlined"></v-text-field>
                    <v-text-field :error-messages="fieldErrors.password" :label="$t('password')"
                                  :rules="formRules2.password"
                                  @update:modelValue="handleFieldUpdate('password')" clearable
                                  v-model="formData2.password"
                                  variant="underlined"></v-text-field>
                    <v-text-field :error-messages="fieldErrors.password2" :label="$t('confirmPassword')"
                                  :rules="formRules2.password2"
                                  @update:modelValue="handleFieldUpdate('password2')" clearable
                                  v-model="formData2.password2"
                                  variant="underlined"></v-text-field>
                    <v-text-field :error-messages="fieldErrors.activationCode" :label="$t('激活码')"
                                  :rules="formRules2.activationCode"
                                  @update:modelValue="handleFieldUpdate('activationCode')" clearable
                                  v-model="formData2.activationCode"
                                  variant="underlined"></v-text-field>
                </v-form>
                <div class="text-red" v-if="errorMsg">{{ errorMsg }}</div>
                <div class="mt-5 d-flex justify-space-between">
                    <v-btn @click="navIndex = 0" color="primary" variant="text">返回登录</v-btn>
                    <div @click="submit2" class="btn" loading="submitting2" style="color: #ffffff !important;">提交注册
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>
    const {$i18n} = useNuxtApp();
    definePageMeta({
        layout: 'vuetify-app'
    });
    const formData = ref({
        account: '',
        password: ''
    });
    //记住密码属性
    const rememberMe = ref(false);
    const formData2 = ref({
        username: '',
        phone: '',
        activationCode: '',
        password: '',
        password2: '',
        code: '',
    });
    const fieldErrors = ref({
        username: '',
        phone: '',
        password: '',
        password2: '',
        code: '',
    });
    const formRules2 = ref({
        username: [
            v => !!v || $i18n.t('请输入你的昵称'),
            v => v.length >= 4 || $i18n.t('Username must be at least 4 characters')
        ],
        activationCode: [
            v => !!v || $i18n.t('请输入激活码'),
            v => v.length >= 19 || $i18n.t('Username must be at least 4 characters')
        ],
        phone: [
            v => !!v || $i18n.t('请输入你的手机'),
            v => /^1[3456789]\d{9}$/.test(v) || '手机号码格式不正确'
        ],
        password: [
            v => !!v || $i18n.t('请输入你的密码'),
            v => v.length >= 6 || $i18n.t('密码至少是6位数')
        ],
        password2: [
            v => !!v || $i18n.t('请输入你的密码'),
            v => v.length >= 6 || $i18n.t('密码至少是6位数'),
            v => v === formData2.value.password || $i18n.t('两次密码输入要一直')
        ],
        code: [
            v => !!v || $i18n.t('Please enter your code'),
        ],
    });
    const submitting2 = ref(false);
    const signUpForm = ref(null);
    //页面初始化加载,记住的用户名和密码,用户点击记住密码checkbox,系统将用户名和密码记录到localStorage
    onBeforeMount(() => {
        const savedLogin = localStorage.getItem('login');
        if (savedLogin) {
            formData.value = JSON.parse(savedLogin);
        }
        const savedRememberMe = localStorage.getItem('rememberMe');
        if (savedRememberMe) {
            rememberMe.value = savedRememberMe === 'true';
        }
    });
    const submit2 = async () => {
        errorMsg.value = null;
        const {valid} = await signUpForm.value.validate();
        if (valid) {
            if (submitting2.value == true) {
                // 如果已经点击过了,不再执行后续操作并返回
                console.log("请勿重复点击");
            } else {
                submitting2.value = true;
                const {data} = await useMyFetch('/api/register', {
                    method: 'POST',
                    body: JSON.stringify(formData2.value)
                });
                if (data.value.status === 200) {
                    errorMsg.value = data.value.msg;
                    setTimeout(() => {
                        setUser();
                        navigateTo('/account/signin')
                    }, 500)
                } else {
                    errorMsg.value = data.value.msg;
                    submitting2.value = false;
                }
            }
        }
    };
    const handleFieldUpdate = (field) => {
        fieldErrors.value[field] = ''
    };
    const navIndex = ref(0);
    const formRules = ref({
        account: [
            v => !!v || $i18n.t('Username is required')
        ],
        password: [
            v => !!v || $i18n.t('Password is required')
        ]
    });
    const errorMsg = ref(null);
    const signInForm = ref(null);
    const submitting = ref(false);
    const route = useRoute();
    const passwordInputType = ref('password');
    const remberPassWord = async () => {
        //记住登录用户名和密码
        if (!rememberMe.value) {
            localStorage.setItem('login', JSON.stringify(formData.value));
            localStorage.setItem('rememberMe', true);
        } else {
            localStorage.removeItem('login');
            localStorage.removeItem('rememberMe');
        }
    }
    const submit = async () => {
        errorMsg.value = null;
        const {valid} = await signInForm.value.validate();
        if (valid) {
            submitting.value = true;
            const {data, error} = await useMyFetch('/api/login', {
                method: 'POST',
                body: JSON.stringify(formData.value)
            });
            submitting.value = false;
            console.log("登陆返回数据:", data.value);
            if (data.value.status === 200) {
                localStorage.setItem('token', data.value.data.token);
                localStorage.setItem('expires_time', data.value.data.expires_time);
                setUser(data.value.token);
                const callback = route.query.callback ? decodeURIComponent(route.query.callback) : '/';
                location.href = "/"
            } else {
                errorMsg.value = data.value.msg
            }
        }
    };
    let qrcodeData = ref();
    let qrcodeDialog = ref(false);
    let interval = ref('');
    let uuid = ref('');
</script>
<style scoped>
    * {
        color: #000 !important;
    }
    input, .formField >>> .v-application, .v-text-field input, .v-field__input {
        color: #000 !important;
    }
    button[type="submit"] {
        width: 100%;
        padding: 10px;
        border: none;
        background-color: #5cb85c;
        color: white;
        cursor: pointer;
        border-radius: 4px;
    }
    .bg {
        width: 100%;
        height: 100vh;
        background-image: url(../images/bg.jpg);
        background-position: left;
        background-size: cover;
        -webkit-filter: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
        filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#00FFFFFF", endColorstr="#FFFFFFFF", GradientType=1);
    }
    .form .btn {
        /* 矩形备份 2 */
        position: absolute;
        left: 40px;
        top: 510px;
        width: 320px;
        height: 44px;
        border-radius: 6px;
        opacity: 1;
        text-align: center;
        line-height: 44px;
        color: #fff;
        background: #2469F1;
    }
    .form {
        /* 矩形 */
        position: relative;
        padding: 20px;
        width: 400px;
        height: 575px;
        border-radius: 10px;
        opacity: 1;
        background: #FFFFFF;
        box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.06);
    }
    .title2 {
        /* 欢迎登录 */
        font-size: 24px;
        font-weight: 500;
        line-height: 29px;
        letter-spacing: 0px;
        color: #000000;
    }
    .tips2 {
        /* 账号密码登录 */
        position: absolute;
        left: 20px;
        top: 77px;
        width: 84px;
        height: 17px;
        opacity: 1;
        font-family: PingFang SC;
        font-size: 14px;
        font-weight: 500;
        line-height: 17px;
        letter-spacing: 0px;
        color: #000000;
    }
    .tips3 {
        /* 矩形 */
        /* 矩形 */
        position: absolute;
        left: 20px;
        top: 107px;
        width: 84px;
        height: 2px;
        opacity: 1;
        background: #2469F1;
    }
    .logo {
        position: absolute;
        left: 0px;
        top: 40px;
        width: 80px;
        height: 77px;
        opacity: 1;
        background: url(../images/yuzhouxiong.png);
        background-size: 100%;
    }
    .name {
        position: absolute;
        left: 95px;
        top: 55px;
        width: 517px;
        height: 56px;
        opacity: 1;
        font-family: PingFang SC;
        font-size: 56px;
        font-weight: 600;
        line-height: 56px;
        letter-spacing: 4px;
        color: #000000;
    }
    .beian {
        position: absolute;
        left: 0px;
        top: 385px;
        width: 415px;
        height: 48px;
        opacity: 1;
        font-family: PingFang SC;
        font-size: 14px;
        font-weight: normal;
        line-height: 24px;
        letter-spacing: 0px;
        color: #666666;
    }
    .container {
        height: 100px;
        border: 0px solid #000;
        font-size: small;
    }
</style>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值