【问题标题】:VueJS toggle password visibilty without mutating the "type" propertyVueJS 在不改变“类型”属性的情况下切换密码可见性
【发布时间】:2021-10-06 16:53:28
【问题描述】:

我有一个我正在使用的基本输入组件,它具有type 作为属性,并且到目前为止一直运行良好。但是,尝试将其用于密码并实施混淆有点棘手。

如何在不改变道具的情况下切换密码的隐藏/显示?我认为将type = 'password' 改为type = 'text 是最好的方法,但显然不是。

我已经创建了一个Codesandbox 来复制该组件的那一部分,但我们将不胜感激任何建议或指导!

密码输入.vue:

<template>
  <div>
    <input :type="type" />
    <button @click="obfuscateToggle" class="ml-auto pl-sm _eye">
      <div>
        <img :src="`/${eyeSvg}.svg`" alt="" />
      </div>
    </button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      passwordVisible: false,
      eyeSvg: "eye-closed",
    };
  },
  props: {
    type: { type: String, default: "text" },
  },
  methods: {
    obfuscateToggle() {
      if (this.eyeSvg === "eye-closed") {
        this.eyeSvg = "eye";
      } else this.eyeSvg = "eye-closed";
      // this.eyeSvg = "eye-closed" ? "" : (this.eyeSvg = "eye");
      if ((this.type = "password")) {
        this.type = "text";
      } else this.type = "password";
    },
  },
};
</script>

App.vue

<template>
  <div id="app">
    <PasswordInput type="password" />
  </div>
</template>

【问题讨论】:

    标签: vue.js passwords obfuscation vue-props


    【解决方案1】:

    唯一的方法是改变 type 属性。因为这就是浏览器决定将其呈现为文本框还是密码的方式。因此,您这样做是正确的

    您将遇到的一个问题是,您将在控制台中抛出错误,因为您试图改变一个道具。

    这很容易解决。首先,您将创建一个新的数据属性,并将其分配给默认值type

    data(){
       return{
          fieldType:'text'
       }
    }
    

    然后您将使用mounted lifecycle hook,并更新您的数据属性以匹配您的道具的值`

    mounted(){
       this.fieldType = this.type;
    }
    

    如果您知道 type 属性将从父组件更改,您也可以使用 watcher 进行更改并分配 type

    watch:{
       type(val){
          this.fieldType = val;
       }
    }
    

    然后您将更新您的 obfuscateToggle 方法以使用 fieldtype 变量:

    obfuscateToggle() {
      if (this.eyeSvg === "eye-closed") {
        this.eyeSvg = "eye";
      } else this.eyeSvg = "eye-closed";
    
    
      //You can simplify this by using this.fieldType = this.fieldType == "text" ? "password" : "text"
      if (this.fieldType == "password") {
        this.fieldType = "text";
      } else this.fieldType = "password";
    }
    

    最后,在您的模板中,您需要将 type 更改为 fieldType

    <template>
      <div>
        <input :type="fieldType" />
        <button @click="obfuscateToggle" class="ml-auto pl-sm _eye">
          <div>
            <img :src="`/${eyeSvg}.svg`" alt="" />
          </div>
        </button>
      </div>
    </template>
    

    把它们放在一起

    <script>
    export default {
      name: "HelloWorld",
      data() {
        return {
          passwordVisible: false,
          eyeSvg: "eye-closed",
          fieldType: "text"
        };
      },
      props: {
        type: { type: String, default: "text" },
      },
      methods: {
        obfuscateToggle() {
          if (this.eyeSvg === "eye-closed") {
            this.eyeSvg = "eye";
          } else this.eyeSvg = "eye-closed";
     
    
          //You can simplify this by using this.fieldType = this.fieldType == "text" ? "password" : "text"
          if (this.fieldType == "password") {
            this.fieldType = "text";
          } else this.fieldType = "password";
    
    
        },
      },
      watch:{
        type(val){
           this.fieldType = val;
        }
      },
      mounted(){
        this.fieldType = this.type;
      },
    };
    </script>
    

    这是CodeSandBox上的一个例子


    另外,您的 obfuscateToggle 方法中有一个小错字。

    if(this.type = 'password')
    

    这是分配 type 而不是将其与文字进行比较 :)

    【讨论】:

    • 哇!感谢您在这里的编辑和评论;你真的全力以赴。我今天确实学到了一些东西,这让我松了一口气,哈哈
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 2013-08-05
    • 2020-03-29
    • 2022-06-15
    • 2020-04-10
    • 1970-01-01
    相关资源
    最近更新 更多