浏览器自动填充登录用户名和密码,如何清除

文章目录

    • 刷新网页的时候浏览器会自动填充用户名和密码
    • 刷新之后效果图
    • 解决方案
      • 完整的login.vue代码
      • 核心代码原理(添加 readonly 和监听 focus 事件)

刷新网页的时候浏览器会自动填充用户名和密码

在这里插入图片描述

刷新之后效果图

在这里插入图片描述

解决方案

完整的login.vue代码

<template>
  <div class="login">
    <el-card>
      <h2 class="title"  style="text-align: center; font-weight: bold; color: #707070;">数字化监管平台</h2>
      <el-tabs v-model="activeName" @tab-click="handleClick" stretch>
        <el-tab-pane label="机构和姓名登录" name="first">
          <div class="form-container">
            <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">

            <el-form-item label="" prop="deptId">
              <treeselect class="el-treeselect" v-model="loginForm.deptId" :options="deptOptions" :show-count="true"
                          placeholder="请选择归属机构"/>
              <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
            </el-form-item>

            <el-form-item prop="nickName">
              <el-input
                v-model="loginForm.nickName"
                type="text"
                auto-complete="off"
                placeholder="姓名"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="password">
              <el-input
                v-model="loginForm.password"
                type="password"
                auto-complete="off"
                placeholder="密码"
                @keyup.enter.native="handleLogin"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="code" v-if="captchaEnabled">
              <el-input
                v-model="loginForm.code"
                auto-complete="off"
                placeholder="验证码"
                style="width: 63%"
                @keyup.enter.native="handleLogin"
              >
                <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
              </el-input>
              <div class="login-code">
                <img :src="codeUrl" @click="getCode" class="login-code-img"/>
              </div>
            </el-form-item>
            <el-form-item style="width:100%;">
              <el-button
                :loading="loading"
                size="medium"
                type="primary"
                style="width:100%;"
                @click.native.prevent="handleLoginByOrg"
              >
                <span v-if="!loading">登 录</span>
                <span v-else>登 录 中...</span>
              </el-button>
            </el-form-item>
          </el-form>
          </div>
        </el-tab-pane>

        <el-tab-pane label="用户名登录" name="second">
          <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
            <el-form-item prop="username">
              <el-input
                v-model="loginForm.username"
                type="text"
                auto-complete="off"
                placeholder="账号"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="password">
              <el-input
                v-model="loginForm.password"
                type="password"
                auto-complete="off"
                placeholder="密码"
                @keyup.enter.native="handleLogin"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="code" v-if="captchaEnabled">
              <el-input
                v-model="loginForm.code"
                auto-complete="off"
                placeholder="验证码"
                style="width: 63%"
                @keyup.enter.native="handleLogin"
              >
                <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
              </el-input>
              <div class="login-code">
                <img :src="codeUrl" @click="getCode" class="login-code-img"/>
              </div>
            </el-form-item>
            <el-form-item style="width:100%;">
              <el-button
                :loading="loading"
                size="medium"
                type="primary"
                style="width:100%;"
                @click.native.prevent="handleLogin"
              >
                <span v-if="!loading">登 录</span>
                <span v-else>登 录 中...</span>
              </el-button>
              <div style="float: right;" v-if="register">
                <router-link class="link-type" :to="'/register'">立即注册</router-link>
              </div>
            </el-form-item>
          </el-form>
          <!--  底部  -->
          <!-- <div class="el-login-footer">
            <span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>
          </div> -->
        </el-tab-pane>
      </el-tabs>
    </el-card>

  </div>

</template>

<script>
  import {getCodeImg} from "@/api/login";
  import Cookies from "js-cookie";
  import {encrypt, decrypt} from '@/utils/jsencrypt';
  import {deptTreeSelect} from "@/api/system/user";
  import Treeselect from "@riophae/vue-treeselect";
  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  import {Message} from 'element-ui'

  export default {
    name: "Login",
    components: {Treeselect},
    data() {
      return {
        codeUrl: "",
        loginForm: {
          username: "",
          password: "",
          rememberMe: false,
          code: "",
          uuid: ""
        },
        loginRules: {
          username: [
            {required: true, trigger: "blur", message: "请输入您的账号"}
          ],
          password: [
            {required: true, trigger: "blur", message: "请输入您的密码"}
          ],
          code: [{required: true, trigger: "change", message: "请输入验证码"}]
        },
        loading: false,
        // 验证码开关
        captchaEnabled: true,
        // 注册开关
        register: false,
        redirect: undefined,
        activeName: 'first',
        // 部门树选项
        deptOptions: undefined,
        isReadOnly: true
      };
    },
    watch: {
      $route: {
        handler: function (route) {
          this.redirect = route.query && route.query.redirect;
        },
        immediate: true
      }
    },
    created() {
      this.getDeptTree();
      this.getCode();
    },
    methods: {
      getCode() {
        getCodeImg().then(res => {
          this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
          if (this.captchaEnabled) {
            this.codeUrl = "data:image/gif;base64," + res.img;
            this.loginForm.uuid = res.uuid;
          }
        });
      },
      handleLogin() {
        this.$refs.loginForm.validate(valid => {
          if (valid) {
            this.loading = true;
            if (this.loginForm.rememberMe) {
              Cookies.set("username", this.loginForm.username, {expires: 30});
              Cookies.set("password", encrypt(this.loginForm.password), {expires: 30});
              Cookies.set('rememberMe', this.loginForm.rememberMe, {expires: 30});
            } else {
              Cookies.remove("username");
              Cookies.remove("password");
              Cookies.remove('rememberMe');
            }
            this.$store.dispatch("Login", this.loginForm).then(() => {
              this.$router.push({path: this.redirect || "/"}).catch(() => {
              });
            }).catch(() => {
              this.loading = false;
              if (this.captchaEnabled) {
                this.getCode();
              }
            });
          }
        });
      },
      handleLoginByOrg() {
        //校验
        if (!this.loginForm.nickName) {
          Message.info("用户名称不能为空!");
          return;
        }
        if (!this.loginForm.deptId || this.loginForm.deptId === undefined) {
          Message.info("请选择机构名称!");
          return;
        }
        if (!this.loginForm.password) {
          Message.info("密码不能为空!");
          return;
        }

        this.$refs.loginForm.validate(valid => {
          if (valid) {
            this.loading = true;
            if (this.loginForm.rememberMe) {
              Cookies.set("deptId", this.loginForm.deptId, {expires: 30});
              Cookies.set("nickName", this.loginForm.nickName, {expires: 30});
              Cookies.set("username", this.loginForm.username, {expires: 30});
              Cookies.set("password", encrypt(this.loginForm.password), {expires: 30});
              Cookies.set('rememberMe', this.loginForm.rememberMe, {expires: 30});
            } else {
              Cookies.remove("nickName");
              Cookies.remove("username");
              Cookies.remove("password");
              Cookies.remove('rememberMe');
            }
            this.$store.dispatch("LoginByOrg", this.loginForm).then(response => {
              console.log('response', response);
              Message.info(response)
              this.$router.push({path: this.redirect || "/"}).catch(() => {
              });
              this.loading = false;
            }).catch(() => {
              this.loading = false;
              if (this.captchaEnabled) {
                this.getCode();
              }
            });
          }
        });
      },
      handleClick(tab, event) {
        console.log(tab, event);
      },
      /** 查询部门下拉树结构 */
      getDeptTree() {
        deptTreeSelect().then(response => {
          this.deptOptions = response.data;
        });
      },
      handleFocus(event) {
        this.isReadOnly = false;
        // 可能还需要在某些情况下重新聚焦,以确保输入框获得焦点
        // event.target.blur();
        // event.target.focus();
      },
    }
  };
</script>

<style rel="stylesheet/scss" lang="scss">
  .login {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    background-image: url("../assets/images/login-new.png");
    background-size: cover;
  }

  .el-tabs {
    background-color: #ffffff; /* 设置底色为白色 */
  }

  .login-form {
    border-radius: 6px;
    background: #ffffff;
    width: 400px;
    padding: 25px 25px 5px 25px;

    .el-input {
      height: 38px;

      input {
        height: 38px;
      }
    }

    .input-icon {
      height: 39px;
      width: 14px;
      margin-left: 2px;
    }
  }

  .login-tip {
    font-size: 13px;
    text-align: center;
    color: #bfbfbf;
  }

  .login-code {
    width: 33%;
    height: 38px;
    float: right;

    img {
      cursor: pointer;
      vertical-align: middle;
    }
  }

  .login-code-img {
    height: 38px;
  }

  .form-container {
    overflow-y: auto;
  }


</style>

核心代码原理(添加 readonly 和监听 focus 事件)

用户名和密码字段即使没有赋值也出现浏览器自动填充的情况,可以采用以下方法来禁止这一行为:

  1. 使用 auto-complete 属性(实测并没有生效):
    对于 el-input 组件,你应该将 auto-complete 属性设置为 "new-password",即使对于非密码字段也是如此,因为某些浏览器可能对常见的字段名有所识别并尝试自动填充。例如:

    <el-input v-model="username" auto-complete="new-password"></el-input>
    <el-input v-model="password" type="password" auto-complete="new-password"></el-input>
    
  2. 添加 readonly 和监听 focus 事件 (实测有效):
    初始时设置输入框为只读(readonly),并在获得焦点时移除只读属性,这可以阻止某些浏览器的自动填充功能。需要在组件的 focus 事件中移除 readonly

    <el-input
      v-model="username"
      auto-complete="new-password"
      :readonly="isReadOnly"
      @focus="handleFocus"
    ></el-input>
    
    <script>
    export default {
      data() {
        return {
          username: '',
          isReadOnly: true,
        };
      },
      methods: {
        handleFocus(event) {
          this.isReadOnly = false;
          // 可能还需要在某些情况下重新聚焦,以确保输入框获得焦点
          // event.target.blur();
          // event.target.focus();
        },
      },
    };
    </script>
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/764774.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB将两个折线图画在一个图里

界面如图 输入行数和列数&#xff0c;点击开始填入数据&#xff0c;其中第一列为x值&#xff0c;后面几列&#xff0c;每一列都是y坐标值&#xff0c;填好后点击画在同一张图里即可。点击置零就把所有数变成0&#xff0c;另外也可以选择节点样式。 .mlapp格式的文件如下 夸克…

助力消费品牌,打造3D立体互动购物体验!

随着3D、VR、AR等技术的飞跃发展&#xff0c;传统网络购物的界限被彻底打破&#xff0c;消费者不再局限于文字、图片或视频的二维体验&#xff0c;而是能够沉浸于3D构建的立体世界中&#xff0c;享受3D看房、虚拟逛街的全新购物模式。 51建模网作为国内3D互动展示领域的佼佼者…

如果这时你还不清理C盘,那只能眼睁睁看着电脑越来越卡 直到系统崩溃

如果这时候你还不清理C盘&#xff0c;那只能眼睁睁看着电脑越来越卡 直到系统崩溃。很多人就是想偷懒&#xff0c;当然这是人的天性&#xff0c;明明知道自己的C盘空间就那么大&#xff0c;一天天看着C盘空间越来越小&#xff0c;还不去清理C盘。 这样的人有两种&#xff0c;一…

Hadoop3:Yarn常用Shell命令

一、查看任务 1、查看所有任务 yarn application -list2、根据状态查看任务 语法 yarn application -list -appStates &#xff08;所有状态&#xff1a;ALL、NEW、NEW_SAVING、SUBMITTED、ACCEPTED、RUNNING、FINISHED、FAILED、KILLED&#xff09;例如 yarn application…

启动react项目遇到的问题

保证node和npm已安装 遇到的问题一&#xff1a; 解决&#xff1a;npm init -f 问题二&#xff1a; 解决&#xff1a;npm install formidable --save 遇到的问题三&#xff1a;npm install卡住了 解决&#xff1a;更换镜像源

深度学习原理与Pytorch实战

深度学习原理与Pytorch实战 第2版 强化学习人工智能神经网络书籍 python动手学深度学习框架书 TransformerBERT图神经网络&#xff1a; 技术讲解 编辑推荐 1.基于PyTorch新版本&#xff0c;涵盖深度学习基础知识和前沿技术&#xff0c;由浅入深&#xff0c;通俗易懂&#xf…

13 Redis-- 数据一致性模型、MySQL 和 Redis 的数据一致性

数据一致性模型 根据一致性的强弱分类&#xff0c;可以将一致性模型按以下顺序排列&#xff1a; 强一致性 > 最终一致性 > 弱一致性 数据一致性模型一般用于分布式系统中&#xff0c;目的是定义多个节点间的同步规范。 在这里&#xff0c;我们将其引入数据库和缓存组…

试用笔记之-免费的汇通总账财务软件

首先下载免费汇通总账财务软件 http://www.htsoft.com.cn/download/htcaiwu.rar

【Python】已解决:NameError: name ‘unichr’ is not defined

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;NameError: name ‘unichr’ is not defined 一、分析问题背景 在使用Python进行编程时&#xff0c;有时会遇到“NameError: name ‘unichr’ is not defined”…

每日一题——Python实现蓝桥杯 单词分析(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码分析 时间复杂度分析 空间复杂度分析 总结 我要更强 方法一&#x…

拥抱智能化,WMS系统让仓库管理精细化与人性化结合-亿发

在当今竞争激烈的市场环境中&#xff0c;仓库管理不再是简单的货物存储和流通&#xff0c;而是一个复杂而精细的管理系统。仓库管理系统&#xff08;Warehouse Management System, WMS&#xff09;作为现代仓库管理的核心技术&#xff0c;通过“有过程”的管理理念&#xff0c;…

【postgresql】数据库操作

创建数据库 使用 CREATE DATABASE SQL 语句来创建 语法&#xff1a; CREATE DATABASE dbname; 使用 createdb 命令来创建 语法&#xff1a; createdb [option...] [dbname [description]] 参数说明&#xff1a; dbname&#xff1a;要创建的数据库名。 description&…

使用gitlab的CI/CD实现logseq笔记自动发布为单页应用

使用gitlab的CI/CD实现logseq笔记自动发布为单页应用 使用gitlab的CI/CD实现logseq笔记自动发布为单页应用如何实现将logseq的笔记发布成网站使用 logseq-publish-docker 实现手动发布使用gitlab的CI/CD实现自动发布过程中的问题及解决参考资料 使用gitlab的CI/CD实现logseq笔记…

中国社科院-英国斯特灵大学双证管理学博士之英方斯特灵大学介绍

中国社科院-英国斯特灵大学双证管理学博士之英方斯特灵大学介绍 斯特灵大学&#xff08;University of Stirling&#xff09;是位于英国苏格兰斯特灵市的一所公立大学&#xff0c;1967 年以埃斯利城堡为中心建成。 斯特灵大学坚信教育的历史使命&#xff0c;开设高质、灵活的…

独家专访|格行随身WiFi创始人——刘永先 格行随身wifi如何成为行业的领跑品牌?

随着移动互联网的普及和消费者对网络依赖性的增强&#xff0c;随身WiFi市场迎来了前所未有的发展机遇。然而&#xff0c;这一市场的迅速扩张也伴随着一系列问题&#xff0c;其中最为显著的就是市场乱象丛生。近日&#xff0c;有幸邀请到行业领跑品牌格行随身WiFi的刘总&#xf…

电驱失效类型和风险分析,如何用精益思维提升电驱可靠性?

在电动车日益普及的今天&#xff0c;电驱系统作为电动车的“心脏”&#xff0c;其可靠性直接关系到整车的性能与用户体验。然而&#xff0c;电驱失效问题却一直困扰着电动车行业&#xff0c;如何提升电驱可靠性成为了业内关注的焦点。今天&#xff0c;深圳天行健精益管理咨询公…

能自动铲屎的养猫救星?带你了解热门爆款智能猫砂盆的真实体验!

在谈论猫咪的日常生活时&#xff0c;我和朋友最经常聊的话题就是在各种各样的紧急情况下如何狼狈地赶回去给猫咪铲屎&#xff0c;毕竟猫砂盆里的屎但凡停留那么几小时&#xff0c;就要开始发臭了&#xff0c;一下班回去实在受不了那个味道&#xff0c;每次下班在家门口都想带个…

深入剖析高并发服务架构设计的探索与性能分析(1)

深入剖析多线程、协程与事件驱动IO模型的探索与性能分析 Web并发应用场景网站&#xff08;Website&#xff09;并发处理场景特点复杂业务逻辑功能点与页面处理高效应对IO并发需求缓存优化处理控制 大浏览量系统的静态改造静态系统通常有如下几方面的特征几种静态化方案的设计及…

构建RAG+nebula graph(知识图谱KG)

目标&#xff1a;通过利用 LlamaIndex 和 NebulaGraph 为费城费城人队&#xff08;Philadelphia Phillies&#xff09;构建一个RAG流程&#xff0c;深入探讨知识图谱。 NebulaGraph 是市场上最好的知识图谱数据库之一。它是开源的、分布式的&#xff0c;并且能够处理具有亿万边…