前言
大部分人在看到这篇文章的标题时第一时间可能有点懵,我先简单介绍一下背景:
公司有一个基于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() // 触发按钮点击事件
以上代码未考虑兼容性、代码封装等问题,仅提供解决思路的参考
写在最后
其实问题说不上多难,但是对于很多学习知识时只是浅尝辄止的同学,很可能会是个不小的麻烦。平时经常能听到一些 框架会用就行了,原理什么的也就应付一下面试,工作压根用不到 之类的言论,希望大家可以在日趋浮躁的大环境下,守住极客精神,认真钻研技术,做一个真正的程序员,而不仅仅只是个搬砖的。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]