| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 | <template>	<view class="tui-code__input" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}" @tap="onClick">		<view class="tui-code__input" :style="{paddingLeft:gap+'rpx',paddingRight:gap+'rpx'}">			<view class="tui-cinput__item"				:style="{width:width+'rpx',height:height+'rpx',background:background,borderRadius:radius+'rpx',borderColor:activeIndex===index || inputVal[index]?activeColor:borderColor,borderTopWidth:(borderType==1?borderWidth:0)+'rpx',borderLeftWidth:(borderType==1?borderWidth:0)+'rpx',borderRightWidth:(borderType==1?borderWidth:0)+'rpx',borderBottomWidth:(borderType==1 || borderType==2?borderWidth:0)+'rpx'}"				@tap="onTap" v-for="(item,index) in inputArr" :key="index">				<text class="tui-cinput__text"					:style="{width:width+'rpx',height:height+'rpx',fontSize:size+'rpx',lineHeight:height+'rpx',color:color,fontWeight:fontWeight}">{{password?(inputVal[index] ? '●':''):(inputVal[index] || '')}}</text>				<text class="tui-cinput__placeholder"					:style="{fontSize:size+'rpx',fontWeight:fontWeight}">{{password?(inputVal[index] ? '●':''):(inputVal[index] || '')}}</text>				<view class="tui-cinput__cursor" :class="{'tui-cinput__cursor-ani':activeIndex===index && focus}"					v-if="cursor && !disabled" :style="{height:cursorHeight+'rpx',background:cursorColor}">				</view>			</view>		</view>		<input :value="val" :password="password" :type="type" class="tui-cinput__hidden"			:class="{'tui-cinput__ali':ali}" @input="onInput" @blur="onBlur" :focus="focus" :maxlength="length"			:disabled="disabled" @confirm="onConfirm" @focus="onTap" />	</view></template><script>	export default {		name: "tuiCodeInput",		emits: ['complete', 'focus', 'input', 'blur', 'confirm'],		props: {			//组件外层左右间距			gap: {				type: [Number, String],				default: 80			},			marginTop: {				type: [Number, String],				default: 0			},			marginBottom: {				type: [Number, String],				default: 0			},			//初始值,不可超过length长度			value: {				type: String,				default: ''			},			//H5不支持动态切换type类型			type: {				type: String,				default: 'text'			},			password: {				type: Boolean,				default: false			},			disabled: {				type: Boolean,				default: false			},			//获取焦点			isFocus: {				type: Boolean,				default: false			},			cursor: {				type: Boolean,				default: true			},			cursorColor: {				type: String,				default: '#5677fc'			},			cursorHeight: {				type: [Number, String],				default: 60			},			//输入框个数			length: {				type: Number,				default: 4			},			width: {				type: [Number, String],				default: 108			},			height: {				type: [Number, String],				default: 108			},			background: {				type: String,				default: 'transparent'			},			//1-显示所有边框 2-只显示底部边框,3-无边框			borderType: {				type: [Number, String],				default: 1			},			borderColor: {				type: String,				default: '#eaeef1'			},			activeColor: {				type: String,				default: '#5677fc'			},			borderWidth: {				type: [Number, String],				default: 2			},			radius: {				type: [Number, String],				default: 0			},			size: {				type: [Number, String],				default: 48			},			color: {				type: String,				default: '#333'			},			fontWeight: {				type: [Number, String],				default: 600			}		},		data() {			return {				inputArr: [],				inputVal: [],				focus: false,				activeIndex: -1,				ali: false,				val: ''			};		},		watch: {			length(val) {				const nums = Number(val);				if (nums !== this.inputArr.length) {					this.inputArr = this.getArr(nums)				}			},			value(val) {				this.focus = true;				val = val.replace(/\s+/g, "")				this.getVals(val)			},			isFocus(val) {				this.initFocus(val)			}		},		created() {			this.inputArr = this.getArr(Number(this.length))			let val = this.value.replace(/\s+/g, "")			this.getVals(val, true)		},		mounted() {			setTimeout(() => {				this.initFocus(this.isFocus)			}, 300)		},		methods: {			initFocus(val) {				if (this.disabled) return;				if (val && this.activeIndex === -1) {					this.activeIndex = 0				}				if (!this.value && !val) {					this.activeIndex = -1				}				this.$nextTick(() => {					this.focus = val				})			},			getArr(end) {				return Array.from(new Array(end + 1).keys()).slice(1);			},			getVals(val, init = false) {				this.val = val				if (!val) {					this.inputVal = []					this.activeIndex = init ? -1 : 0;				} else {					let vals = val.split('')					let arr = []					this.inputArr.forEach((item, index) => {						arr.push(vals[index] || '')					})					this.inputVal = arr					const len = vals.length;					this.activeIndex = len > this.length ? this.length : len;					if (len === this.length) {						this.$emit('complete', {							detail: {								value: val							}						})						this.focus = false;						uni.hideKeyboard()					}				}			},			onTap() {				if (this.disabled) return;				this.focus = true;				if (this.activeIndex === -1) {					this.activeIndex = 0				}				if (this.activeIndex === this.length) {					this.activeIndex--;				}				this.$emit('focus', {})			},			onInput(e) {				let value = e.detail.value;				value = value.replace(/\s+/g, "")				this.getVals(value)				this.$emit('input', {					detail: {						value: value					}				})			},			onBlur(e) {				let value = e.detail.value;				value = value.replace(/\s+/g, "")				this.focus = false				// #ifdef MP-ALIPAY				this.ali = false				// #endif				if (!value) {					this.activeIndex = -1;				}				this.$emit('blur', {					detail: {						value: value					}				})			},			onConfirm(e) {				this.focus = false;				uni.hideKeyboard()				this.$emit('confirm', e)			},			onClick() {				// #ifdef MP-ALIPAY				setTimeout(() => {					this.ali = true				}, 50)				// #endif			},			clear() {				this.val = ''				this.inputVal = []				this.activeIndex = -1;				this.$nextTick(() => {					this.onTap()				})			}		}	}</script><style scoped>	.tui-code__input {		position: relative;		/* #ifdef MP-BAIDU */		max-width: 100%;		overflow: hidden;		/* #endif */	}	.tui-code__input {		/* #ifndef APP-NVUE */		width: 100%;		display: flex;		box-sizing: border-box;		/* #endif */		flex: 1;		flex-direction: row;		align-items: center;		justify-content: space-between;	}	.tui-cinput__item {		/* #ifndef APP-NVUE */		display: flex;		box-sizing: border-box;		/* #endif */		flex-direction: row;		justify-content: center;		align-items: center;		border-style: solid;		position: relative;		overflow: hidden;	}	.tui-cinput__text {		position: absolute;		left: 0;		top: 0;		flex: 1;		display: flex;		flex-direction: row;		align-items: center;		justify-content: center;		text-align: center;	}	.tui-cinput__placeholder {		text-align: center;		opacity: 0;	}	.tui-cinput__cursor {		border-radius: 2px;		width: 0;	}	.tui-cinput__cursor-ani {		width: 2px;		animation: ani_cursor 1s infinite steps(1, start);	}	@keyframes ani_cursor {		0% {			opacity: 0;		}		50% {			opacity: 1;		}		100% {			opacity: 0;		}	}	.tui-cinput__hidden {		position: absolute;		left: 0;		top: 0;		/* #ifndef MP */		right: 0;		bottom: 0;		/* #endif */		/* #ifndef MP-WEIXIN || MP-QQ */		width: 100%;		height: 100%;		/* #endif */		z-index: 2;		/* #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO */		height: 0;		width: 0;		border: none;		/* #endif */		margin: 0;		padding: 0;		opacity: 0;		/* #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO */		font-size: 0;		/* #endif */		/* #ifdef MP-BAIDU */		transform: scaleX(2);		transform-origin: 100% center;		/* #endif */		color: transparent;	}	/* #ifdef MP-ALIPAY */	.tui-cinput__ali {		height: 0;		width: 0;	}	/* #endif */</style>
 |