密码输入框小眼睛的实现

发布时间 2023-10-10 11:12:42作者: 月豕

input

先回顾一下input标签常用的属性

常用属性

  • nameinput元素的名字,用于对提交到服务器后的表单数据进行标识
  • placeholder:默认显示文字,一般用来提示用户输入,输入后会被覆盖
  • disabled:禁用
  • checked:选中
  • value:元素的值,,此初始值可以更改,并且在提交表单时,value属性的值会发送给服务器
  1. input type="text"、 "password"、 "hidden"时,定义为输入字段的初始值
  2. input type="button"、 "reset"、 "submit"时,定义为按钮上显示的文本
  3. input type="checkbox"、 "radio"、 "image"时,value的值在提交表单时会发送给服务器
  • typeinput的类型
    常用:
    1. text:默认属性
    2. password:密码框,输入的字符将变成小圆点隐藏
    3. checkbox:复选框,用户可以进行多个选项,其中value属性中的值用来设置用户选中改项目后提交到数据库中的值,拥有相同name属性的复选框为同一组。
    4. radio:单选框,其中value属性中的值用来设置用户选中改项后提交到数据库中的值,拥有相同name属性的单选框为同一组

密码框的实现

要点

  1. 添加睁眼和闭眼的图标
  2. 默认睁眼图标,点击闭眼睁眼切换
  3. 睁眼的同时type类型变为text,闭眼变为password

input.vue组件结构

  • 组件由div大盒子+input框+span放置两个icon组成
    <div class="mio-input">
    	<input class="mio-input__inner"></input>
    	<span class="mio-input__suffix">
    			<mio-icon iconClass="open-eyes"></mio-icon>
    			<mio-icon iconClass="close-eyes"></mio-icon>
    		</span>
    </div>
    

input框需要接收的属性

  1. type:字符串类型,在text和password之间切换
  2. value: 字符串类型,默认为空
  3. placeholder:字符串类型,一般设置为“请输入密码”
  • props中定义:

    props: {
    	type: {
    		type: String,
    		default: 'text'
    	},
    	value: {
    		type: String,
    		default: ''
    	},
    	placeholder: {
    		type: String,
    		default: ''
    	},
    }
    
  • App.vue中使用组件并传值
    使用v-model双向绑定value的值,取名为password,并在该组件定义value的默认值为空

    <mio-input type="password" placeholder="请输入密码" v-model="password">
    </mio-input>
    ···
    data() {
    	return {
    		password: ''
    	}
    }
    
  • input.vue组件中使用props定义的值

    <div class="mio-input">
    	<input
    		class="mio-input__inner"
    		:type="type"
    		:value="value"
    		:placeholder="placeholder"
    	></input>
    	<span class="mio-input__suffix">
    			<mio-icon iconClass="open-eyes"></mio-icon>
    			<mio-icon iconClass="close-eyes"></mio-icon>
    		</span>
    </div>
    

眼睛的切换

因为input组件不单是实现密码框一个类型,所以需要设置一个属性showPassword来判断是否设置为密码框,该值为父组件传来的,需要通过props接收。
眼睛和文本框的类型的切换是同时实现的,type的类型是父组件传过来的,我们不能直接修改父组件传来的值,所以需要设置一个属性passwordVisibe来完成类型的切换,默认值则是true,就是睁眼+类型为text


	<div class="mio-input">
		<input
			class="mio-input__inner"
			:type="type"
			:value="value"
			:placeholder="placeholder"
		></input>

		<!-- 密码专属span,showPassword=true的时候显示 -->
		<span class="mio-input__suffix" v-if="showPassword">
				<mio-icon iconClass="open-eyes"></mio-icon>
				<mio-icon iconClass="close-eyes"></mio-icon>
			</span>
	</div>

	data() {
		return {
			passwordVisibe: true
		}
	},
	props: {
		type: {
			type: String,
			default: 'text'
		},
		value: {
			type: String,
			default: ''
		},
		placeholder: {
			type: String,
			default: ''
		},
		showPassword: {
			type: Boolean,
			default: ''
		}
	}

因为是点击眼睛切换类型,所以在span上设置一个click事件,来控制睁眼闭眼和type类型的切换

	<span class="mio-input__suffix"
            v-if="showPassword"
            @click="handleEyes"
			<!-- passwordVisibe为true显示睁眼的icon,反之显示闭眼的icon -->
			<mio-icon iconClass="open-eyes" v-if="passwordVisible"></mio-icon>
			<mio-icon iconClass="close-eyes" v-if="!passwordVisible"></mio-icon>
      >
	</span>
	···
	methods: {
		handleEyes() {
            this.passwordVisible = !this.passwordVisible
        },
	}

类型的切换通过三元表达式来设置,先判断是否为密码框,再判断passwordVisibe的值

<input
	class="mio-input__inner"
	:type="showPassword ? (passwordVisibe ? 'text' : 'password') : type"
	:value="value"
	:placeholder="placeholder"
>
</input>

代码

<template>
    <div
        class="mio-input"
       :class="[`mio-input--${iconType}`, { 'is-showPassword': showPassword }]">
		<input
			:type="showPassword ? (passwordVisible ? 'text' : 'password') : type"
			class="mio-input__inner"
			:placeholder="placeholder"
			:value="value"
			@input="handleInput"
		>
		    <!-- 密码 -->
			<span
				class="mio-input__suffix"
				v-if="showPassword"
				@click="handleEyes"
			>
				<mio-icon iconClass="open-eyes" v-if="passwordVisible"></mio-icon>
				<mio-icon iconClass="close-eyes" v-if="!passwordVisible"></mio-icon>
			</span>
    </div>
</template>
<script>
	export default {
		name: 'mio-input',
		data() {
			return {
				passwordVisible: true
			}
		},
		props: {
			//文本框类型
			type: {
				type: String,
				default: 'text'
			},
			//文本框默认显示文字
			placeholder: {
				type: String,
				default: ''
			},
			//文本框内容
			value: {
				type: String,
				default: ''
			},
			//密码框
			showPassword: {
				type: Boolean,
				default: false
			},
		},
		methods: {
			handleInput(e) {
				this.$emit('input', e.target.value)
			},
			handleEyes() {
				this.passwordVisible = !this.passwordVisible
				// this.inputType = this.eyes ? 'text' : 'password'
			},
		},
	}
</script>