您好,登錄后才能下訂單哦!
前言
大部分人在看到這篇文章的標題時第一時間可能有點懵,我先簡單介紹一下背景:
公司有一個基于Vue實現的登錄中心是我負責維護的,頁面上是一個常規的登錄界面,用戶名輸入框、密碼輸入框和登錄按鈕各一個
今天有個同事(之后簡稱A)過來找我問到這么一個問題:
他負責的應用將登錄中心集成到了APP端,他接到的需求是希望在APP端拉起登錄頁面時,自動將用戶帳號和密碼填入,然后自動點擊登錄。
開始正題
我們把登錄頁面簡化成以下代碼
<template> <div> <input name="username" type="text" v-model="account.username"> <input name="password" type="password" v-model="account.password"> <button class="login-button" @click="login">LOGIN</button> </div> </template> <script> export default { name: 'app', components: { }, data () { return { account: { username: '', password: '' } } }, methods: { login () { $ajax({ method: 'POST', url: '/api/login', data: this.account }) } } } </script>
APP端在拉起登錄頁面時,可以傳入js代碼并在當前頁面執行,拋開MVVM框架Vue的影響,在前端的遠古時代這其實是個很簡單的問題
const usernameInput = document.querySelector('input[name=username]') const passwordInput = document.querySelector('input[name=password]') const button = document.querySelector('.login-button') usernameInput.value = 'test@dji.com' // 修改用戶名輸入框的值 passwordInput.value = 'xxxxxxxx' // 修改密碼輸入框的值 button.click() // 觸發按鈕點擊事件
上面也正是同事A所嘗試的方法,然而他在實際測試中發現,運行js后,雖然頁面上的input框正確變更為修改后的值,但發起的ajax請求中 username 和 password 均為空字符串,于是將問題反饋到了我這邊
原理
其實如果對Vue的響應式數據原理有一定理解的話,就可以很快的想到這個問題的原因。問題的根源就在 v-model 的原理上:
v-model 其實是vue為了方便使用提供的一個語法糖,實際展開來是這樣子
<input name="username" type="text" :value="account.username" @input="account.username = $event.target.value">
當用戶在輸入框輸入時會觸發input事件,從而更新 account.username 值
而上一步中使用 document.querySelector('input[name=username]').value = 'test@dji.com'
模擬的輸入行為實際上并不能觸發 oninput 事件,那么模擬 button 的點擊事件后發起的 ajax 請求拿到的數據自然也就是未修改前的值(即空字符串)
解決方案
弄明白了問題的原理之后,解決方案自然也就很容易想到。既然js模擬輸入無法觸發 oninput 事件,那我們就再進一步,在修改完值后用js手動觸發 oninput 事件
實現代碼如下:
const usernameInput = document.querySelector('input[name=username]') const passwordInput = document.querySelector('input[name=password]') const button = document.querySelector('.login-button') const event = document.createEvent('HTMLEvents') event.initEvent('input', false, true) usernameInput.value = 'test@dji.com' // 修改用戶名輸入框的值 usernameInput.dispatchEvent(event) // 手動觸發輸入框的input事件 passwordInput.value = 'xxxxxxxx' // 修改密碼輸入框的值 passwordInput.dispatchEvent(event) // 手動觸發輸入框的input事件 button.click() // 觸發按鈕點擊事件
以上代碼未考慮兼容性、代碼封裝等問題,僅提供解決思路的參考
寫在最后
其實問題說不上多難,但是對于很多學習知識時只是淺嘗輒止的同學,很可能會是個不小的麻煩。平時經常能聽到一些 框架會用就行了,原理什么的也就應付一下面試,工作壓根用不到 之類的言論,希望大家可以在日趨浮躁的大環境下,守住極客精神,認真鉆研技術,做一個真正的程序員,而不僅僅只是個搬磚的。
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。