VueJS 切换密码可见性而不改变“type”属性

Lov*_*ndy 1 passwords obfuscation vue.js vue-props

我有一个正在使用的基本输入组件,它作为type一个属性,到目前为止一直工作得很好。然而,尝试使用它作为密码并实施混淆有点棘手。

如何在不改变 prop 的情况下切换密码的隐藏/显示?我认为做到这一点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>
Run Code Online (Sandbox Code Playgroud)

应用程序.vue

<template>
  <div id="app">
    <PasswordInput type="password" />
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

Sui*_*pps 6

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

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

这是快速且容易修复的。首先,您将创建一个新的数据属性,并将其分配给默认值type

data(){
   return{
      fieldType:'text'
   }
}
Run Code Online (Sandbox Code Playgroud)

然后您将使用生命周期mounted钩子,并更新您的数据属性以匹配您的道具的值`

mounted(){
   this.fieldType = this.type;
}
Run Code Online (Sandbox Code Playgroud)

如果您知道type父组件的 prop 会发生变化,您还可以使用观察者进行更改并分配type

watch:{
   type(val){
      this.fieldType = val;
   }
}
Run Code Online (Sandbox Code Playgroud)

然后,您将更新您的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";
}
Run Code Online (Sandbox Code Playgroud)

最后,在您的模板中,您需要更改typefieldType

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

把它们放在一起

<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>
Run Code Online (Sandbox Code Playgroud)

这是CodeSandBox上的示例


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

if(this.type = 'password')
Run Code Online (Sandbox Code Playgroud)

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