利用JS响应式修改vue实现页面的input值


Posted in Javascript onSeptember 02, 2019

前言

大部分人在看到这篇文章的标题时第一时间可能有点懵,我先简单介绍一下背景:

公司有一个基于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() // 触发按钮点击事件

以上代码未考虑兼容性、代码封装等问题,仅提供解决思路的参考

写在最后

其实问题说不上多难,但是对于很多学习知识时只是浅尝辄止的同学,很可能会是个不小的麻烦。平时经常能听到一些 框架会用就行了,原理什么的也就应付一下面试,工作压根用不到 之类的言论,希望大家可以在日趋浮躁的大环境下,守住极客精神,认真钻研技术,做一个真正的程序员,而不仅仅只是个搬砖的。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
nicejforms——美化表单不用愁
Feb 20 Javascript
js css样式操作代码(批量操作)
Oct 09 Javascript
BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
Oct 29 Javascript
JS定义网页表单提交(submit)的方法
Mar 20 Javascript
JavaScript数据操作_浅谈原始值和引用值的操作本质
Aug 23 Javascript
jQuery 移动端拖拽(模块化开发,触摸事件,webpack)
Oct 28 Javascript
JS实现类似百叶窗下拉菜单效果
Dec 30 Javascript
浅析node Async异步处理模块用例分析及常用方法介绍
Nov 17 Javascript
基于Vue 2.0的模块化前端 UI 组件库小结
Dec 21 Javascript
Vue登录注册并保持登录状态的方法
Aug 17 Javascript
javascript异步编程的六种方式总结
May 17 Javascript
详解JavaScript自定义函数
Jul 29 Javascript
layui 弹出层回调获取弹出层数据的例子
Sep 02 #Javascript
vue中通过使用$attrs实现组件之间的数据传递功能
Sep 01 #Javascript
Vue使用mixin分发组件的可复用功能
Sep 01 #Javascript
JavaScript页面加载事件实例讲解
Sep 01 #Javascript
Node.js安装详细步骤教程(Windows版)详解
Sep 01 #Javascript
vue组件命名和props命名代码详解
Sep 01 #Javascript
Vue-CLI项目中路由传参的方式详解
Sep 01 #Javascript
You might like
DISCUZ 论坛管理员密码忘记的解决方法
2009/05/14 PHP
解析smarty 截取字符串函数 truncate的用法介绍
2013/06/20 PHP
php转换颜色为其反色的方法
2015/04/27 PHP
PHP页面跳转实现延时跳转的方法
2016/12/10 PHP
yii 2.0中表单小部件的使用方法示例
2017/05/23 PHP
Swoole 5将移除自动添加Event::wait()特性详解
2019/07/10 PHP
javascript 字符串连接的性能问题(多浏览器)
2008/11/18 Javascript
javascript 异常处理使用总结
2009/06/21 Javascript
js获取checkbox复选框选中的选项实例
2014/08/24 Javascript
js简单工厂模式用法实例
2015/06/30 Javascript
使用Bootstrap框架制作查询页面的界面实例代码
2016/05/27 Javascript
基于Bootstrap的Metronic框架实现条码和二维码的生成及打印处理操作
2016/08/29 Javascript
基于JavaScript实现跳转提示页面
2016/09/24 Javascript
Jquery给当前页或者跳转后页面的导航栏添加选中后样式的实例
2016/12/08 Javascript
Javascript Function.prototype.bind详细分析
2016/12/29 Javascript
JavaScript实现左右下拉框动态增删示例
2017/03/09 Javascript
JS实现电商放大镜效果
2017/08/24 Javascript
vue实现微信分享朋友圈,发送朋友的示例讲解
2018/02/10 Javascript
全站最详细的Vuex教程
2018/04/13 Javascript
通过jquery获取上传文件名称、类型和大小的实现代码
2018/04/19 jQuery
Vue路由守卫之路由独享守卫
2019/09/25 Javascript
JavaScript forEach中return失效问题解决方案
2020/06/01 Javascript
Python+Pandas 获取数据库并加入DataFrame的实例
2018/07/25 Python
Python3简单实现串口通信的方法
2019/06/12 Python
使用python 写一个静态服务(实战)
2019/06/28 Python
使用Python为中秋节绘制一块美味的月饼
2019/09/11 Python
使用CSS3代码绘制可爱的Hello Kitty猫
2016/08/03 HTML / CSS
css3media响应式布局实例
2016/07/08 HTML / CSS
草莓网官网:StrawberryNET
2019/08/21 全球购物
我的珠宝盒:Ma boîte à bijoux
2019/08/27 全球购物
Booking.com缤客中国:全球酒店在线预订网站
2020/05/03 全球购物
共产党员公开承诺书
2014/03/25 职场文书
员工试用期自我鉴定范文
2014/09/15 职场文书
2015年试用期工作总结
2014/12/12 职场文书
初中教师个人工作总结
2015/02/10 职场文书
Python 读取千万级数据自动写入 MySQL 数据库
2022/06/28 Python