时间:2021-05-25
前言
大部分人在看到这篇文章的标题时第一时间可能有点懵,我先简单介绍一下背景:
公司有一个基于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() // 触发按钮点击事件以上代码未考虑兼容性、代码封装等问题,仅提供解决思路的参考
写在最后
其实问题说不上多难,但是对于很多学习知识时只是浅尝辄止的同学,很可能会是个不小的麻烦。平时经常能听到一些 框架会用就行了,原理什么的也就应付一下面试,工作压根用不到 之类的言论,希望大家可以在日趋浮躁的大环境下,守住极客精神,认真钻研技术,做一个真正的程序员,而不仅仅只是个搬砖的。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了vue.js实现输入框输入值内容实时响应变化的方法。分享给大家供大家参考,具体如下:/vue/2.5.16/vue.min.js">你好,{{na
Vue.js引用百度百科的话:是一个构建数据驱动的web界面的渐进式框架。Vue.js的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件。它不仅
引入Vue.js,通过script形式,vue官网语法记录创建vue应用,数据和DOM已经被建立了关联,所有东西都是响应式的1:插值缺点:让你的网速慢,或者数据
现在来系统地学习一下Vue(参考vue.js官方文档):Vue.js是一个构建数据驱动的web界面的库,其目标是实现响应的数据绑定和组合的试图组件。Vue.js
深入响应式原理大部分的基础内容我们已经讲到了,现在讲点底层内容。Vue.js最显著的一个功能是响应系统——模型只是普通对象,修改它则更新视图。这让状态管理非常简