VueJS 在不改变 "type" 属性 的情况下切换密码可见性
VueJS toggle password visibilty without mutating the "type" property
我有一个正在使用的基本输入组件,它具有 type
作为 属性,并且到目前为止一直运行良好。但是,尝试将其用于密码并实施混淆有点棘手。
如何在不改变 prop 的情况下切换 hide/show 密码?我认为将 type = 'password'
变为 type = 'text
是最好的方法,但显然不是。
我已经制作了一个 Codesandbox 来复制组件的那部分,但是任何建议或指导将不胜感激!
PasswordInput.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>
唯一的方法是改变类型属性。因为这就是浏览器决定将其呈现为文本框还是密码的方式。因此,您这样做 的方式是正确的。
您将遇到的一个问题是,您将在控制台中抛出错误,因为您正试图改变一个道具。
修复起来既快速又容易。首先,您将创建一个新数据 属性,并将其分配给默认值 type
data(){
return{
fieldType:'text'
}
}
然后您将使用 on mounted
lifecycle hook,并更新您的数据 属性 以匹配您的道具的价值`
mounted(){
this.fieldType = this.type;
}
如果您知道 type
道具将从父组件更改,您还可以使用 watcher 进行更改并分配 type
watch:{
type(val){
this.fieldType = val;
}
}
然后您将更新 obfuscateToggle
方法以使用字段类型变量:
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
而不是将其与文字进行比较 :)
我有一个正在使用的基本输入组件,它具有 type
作为 属性,并且到目前为止一直运行良好。但是,尝试将其用于密码并实施混淆有点棘手。
如何在不改变 prop 的情况下切换 hide/show 密码?我认为将 type = 'password'
变为 type = 'text
是最好的方法,但显然不是。
我已经制作了一个 Codesandbox 来复制组件的那部分,但是任何建议或指导将不胜感激!
PasswordInput.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>
唯一的方法是改变类型属性。因为这就是浏览器决定将其呈现为文本框还是密码的方式。因此,您这样做 的方式是正确的。
您将遇到的一个问题是,您将在控制台中抛出错误,因为您正试图改变一个道具。
修复起来既快速又容易。首先,您将创建一个新数据 属性,并将其分配给默认值 type
data(){
return{
fieldType:'text'
}
}
然后您将使用 on mounted
lifecycle hook,并更新您的数据 属性 以匹配您的道具的价值`
mounted(){
this.fieldType = this.type;
}
如果您知道 type
道具将从父组件更改,您还可以使用 watcher 进行更改并分配 type
watch:{
type(val){
this.fieldType = val;
}
}
然后您将更新 obfuscateToggle
方法以使用字段类型变量:
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
而不是将其与文字进行比较 :)