眼睛的icon使用的是阿里的图标库www.iconfont.cn/
【思路分析】:
首先这个密码组件是input+icon完成的(也可以是img但是我很懒,不想写css)
对于input来说:要做2件事情
-
眼睛睁开:type是text,眼睛闭上:type是password
-
给父组件提交用户输入的值
对于图标来说:要做2件事
-
可以点击
-
保证 密码-闭眼 文本-睁眼 这个效果
【核心代码】:
-
flagType绑定动态的值 data中的flagType:'password', -
:class="[flag ? 'iconfont icon-yanjing_yincang_o': 'iconfont icon-yanjing_xianshi_o']"动态样式 -
toShowPassword函数,眼睛的点击事件<el-input v-model="value" :type="flagType" ref="password" @input="emitInput" > <i slot="suffix" class="el-input__icon eye-wrapper" :class="[flag ? 'iconfont icon-yanjing_yincang_o': 'iconfont icon-yanjing_xianshi_o']" @click="toShowPassword"> </i> </el-input>
【script代码】:
```js
data() {
return {
value: '',
flag: true,
flagType: 'password',
}
},
```
```js
methods: {
toShowPassword() {
this.flag = !this.flag
this.flagType = this.flag ? 'password' : 'text'
this.$nextTick(() => {
this.$refs.password.focus()
})
},
//提交数据
emitInput() {
this.$emit('input', this.value)
},
}
```
【父组件引用】:
我在父组件中设置了展示密码的按钮
<div style="width: 200px">
<h1>密码组件</h1>
<toggle-passowrd v-model="form.password"></toggle-passowrd>
<el-button @click="getPassword">展示密码</el-button>
</div>
在子组件中emitInput这个方法将子组件的数据提交到了父组件,父组件通过v-model就可以拿到这个值
这里其实还涉及一个知识点,就是v-model是怎么实现的?其实上面的代码可以进行原生的改下,请看下面的代码
<toggle-passowrd v-model="form.password"></toggle-passowrd>
// 原生
<toggle-passowrd @input="setPassword" :value="form.password"></toggle-passowrd>
原生需要的方法:
setPassword(val) {
this.form.password = val
},
这样知识就串联了起来,子组件通过emit将数据给了父组件,父组件通过子组件提交的input事件去取数据,而vue为此,提供了一个vue的指令,就是v-model,v-model就是获取数据,并赋值数据,实现绑定。
结合之前遇到的google会出现密码回填的问题,【封装了一个不会触发回填的密码子组件】
因为出现回填的根本原因就是type=“password”,所以使用text=“text”去规避这个问题,然后密文效果通过css去实现,最后封装了一个密码子组件可以参考
<!--
* @Author: Kvon
* @Date: 2023-09-14 20:56:57
* @Description:
-->
<template>
<div>
<el-input
v-model="value"
type="text"
ref="password"
@input="emitInput"
:class="['input-content', className, flag ? 'disc' : 'none']"
>
<i
slot="suffix"
class="el-input__icon eye-wrapper"
:class="[
flag
? 'iconfont icon-yanjing_yincang_o'
: 'iconfont icon-yanjing_xianshi_o'
]"
@click="toShowPassword"
>
</i>
</el-input>
</div>
</template>
<script>
export default {
name: 'PasswordCss',
data() {
return {
value: '',
flag: true
}
},
methods: {
/**
* @Author: Kvon
* @Date: 2023-09-14 21:14:30
* @Description: 展示密码
*/
toShowPassword() {
this.flag = !this.flag
this.$nextTick(() => {
this.$refs.password.focus()
})
},
/**
* @Author: Kvon
* @Date: 2023-09-14 22:52:13
* @Description: 提交子组件数据
*/
emitInput() {
this.$emit('input', this.value)
}
}
}
</script>
<style lang="less" scoped>
.disc {
/* Use -webkit-text-security if the browser supports it */
-webkit-text-security: disc;
}
.none {
/* Use -webkit-text-security if the browser supports it */
-webkit-text-security: none;
}
.eye-wrapper {
font-size: 16px;
-webkit-text-security: none;
}
</style>