1313 :class =" { 'auth-code-input__input--filled': allFilled }"
1414 @keyup =" handleKeyUp"
1515 @keydown =" handleKeyDown"
16+ @paste =" pasteAt(1, $event)"
1617 />
1718 <input
19+ ref =" input2"
1820 v-model =" number2"
1921 type =" text"
2022 maxlength =" 1"
2325 :class =" { 'auth-code-input__input--filled': allFilled }"
2426 @keyup =" handleKeyUp"
2527 @keydown =" handleKeyDown"
28+ @paste =" pasteAt(2, $event)"
2629 />
2730 <input
31+ ref =" input3"
2832 v-model =" number3"
2933 type =" text"
3034 maxlength =" 1"
3337 :class =" { 'auth-code-input__input--filled': allFilled }"
3438 @keyup =" handleKeyUp"
3539 @keydown =" handleKeyDown"
40+ @paste =" pasteAt(3, $event)"
3641 />
3742 <input
43+ ref =" input4"
3844 v-model =" number4"
3945 type =" text"
4046 maxlength =" 1"
4349 :class =" { 'auth-code-input__input--filled': allFilled }"
4450 @keyup =" handleKeyUp"
4551 @keydown =" handleKeyDown"
52+ @paste =" pasteAt(4, $event)"
4653 />
4754 <input
55+ ref =" input5"
4856 v-model =" number5"
4957 type =" text"
5058 maxlength =" 1"
5361 :class =" { 'auth-code-input__input--filled': allFilled }"
5462 @keyup =" handleKeyUp"
5563 @keydown =" handleKeyDown"
64+ @paste =" pasteAt(5, $event)"
5665 />
5766 <input
67+ ref =" input6"
5868 v-model =" number6"
5969 type =" text"
6070 maxlength =" 1"
6373 :class =" { 'auth-code-input__input--filled': allFilled }"
6474 @keyup =" handleKeyUp"
6575 @keydown =" handleKeyDown"
76+ @paste =" pasteAt(6, $event)"
6677 />
6778 </div >
6879</template >
@@ -87,6 +98,7 @@ export default {
8798 number5: ' ' ,
8899 number6: ' ' ,
89100 },
101+ hasEmitted: false ,
90102 }
91103 },
92104 computed: {
@@ -152,10 +164,25 @@ export default {
152164 return this .code .length === 6
153165 },
154166 },
167+ watch: {
168+ allFilled (isFilled ) {
169+ if (isFilled && ! this .hasEmitted ) {
170+ this .hasEmitted = true
171+ this .$emit (' all-filled' , this .code )
172+ }
173+ if (! isFilled) {
174+ this .hasEmitted = false
175+ }
176+ },
177+ },
155178 mounted () {
156179 this .reset ()
157180 },
158181 methods: {
182+ focusIndex (i ) {
183+ const el = this .$refs [` input${ i} ` ]
184+ if (el && typeof el .focus === ' function' ) el .focus ()
185+ },
159186 reset () {
160187 this .values .number1 = ' '
161188 this .values .number2 = ' '
@@ -164,6 +191,7 @@ export default {
164191 this .values .number5 = ' '
165192 this .values .number6 = ' '
166193 this .$refs .input1 .focus ()
194+ this .hasEmitted = false
167195 },
168196 sanitizeInput (value ) {
169197 const sanitized = value .replace (/ \D / g , ' ' ).slice (0 , 1 )
@@ -192,11 +220,31 @@ export default {
192220 if (nextInput && nextInput .tagName === ' INPUT' ) {
193221 nextInput .focus ()
194222 }
223+ }
224+ },
225+ pasteAt (startIndex , event ) {
226+ event .preventDefault ()
195227
196- if (this .allFilled ) {
197- this .$emit (' all-filled' , this .code )
198- }
228+ const raw =
229+ (event .clipboardData && event .clipboardData .getData (' text' )) ||
230+ (window .clipboardData && window .clipboardData .getData (' Text' )) ||
231+ ' '
232+
233+ const digits = raw .replace (/ \D / g , ' ' )
234+ const maxLen = 7 - startIndex
235+ const chunk = digits .slice (0 , maxLen)
236+
237+ for (let i = startIndex; i <= 6 ; i++ ) {
238+ this .values [` number${ i} ` ] = ' '
199239 }
240+
241+ for (let offset = 0 ; offset < chunk .length ; offset++ ) {
242+ const i = startIndex + offset
243+ this .values [` number${ i} ` ] = chunk[offset]
244+ }
245+
246+ const nextIndex = Math .min (startIndex + chunk .length , 6 )
247+ this .$nextTick (() => this .focusIndex (nextIndex))
200248 },
201249 },
202250}
0 commit comments