利用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 相关文章推荐
javascript 定义初始化数组函数
Sep 07 Javascript
javascript中全局对象的parseInt()方法使用介绍
Dec 19 Javascript
Javascript验证上传图片大小[前台处理]
Jul 18 Javascript
Egret引擎开发指南之视觉编程
Sep 03 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
Jul 12 Javascript
Vue.js仿Metronic高级表格(一)静态设计
Apr 17 Javascript
w3c编程挑战_初级脚本算法实战篇
Jun 23 Javascript
JSON对象转化为字符串详解
Aug 11 Javascript
6行代码实现微信小程序页面返回顶部效果
Dec 28 Javascript
通过jQuery学习js类型判断的技巧
May 27 jQuery
vue-property-decorator用法详解
Dec 12 Javascript
在Vue中使用antv的示例代码
Jun 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
如何用PHP实现插入排序?
2013/04/10 PHP
php学习笔记之面向对象
2014/11/08 PHP
PHP实现的pdo连接数据库并插入数据功能简单示例
2019/03/30 PHP
PHP+redis实现的限制抢购防止商品超发功能详解
2019/09/19 PHP
javascript 写类方式之九
2009/07/05 Javascript
JavaScript获取客户端计算机硬件及系统等信息的方法
2014/01/02 Javascript
js 获取、清空input type=&quot;file&quot;的值示例代码
2014/02/19 Javascript
jQuery淡入淡出元素让其效果更为生动
2014/09/01 Javascript
情人节单身的我是如何在敲完代码之后收到12束玫瑰的(javascript)
2015/08/21 Javascript
JS自动倒计时30秒后按钮才可用(两种场景)
2015/08/31 Javascript
ajax跨域调用webservice的实现代码
2016/05/09 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
2016/08/03 Javascript
浅谈JavaScript 数据属性和访问器属性
2016/09/01 Javascript
Vue.js每天必学之构造器与生命周期
2016/09/05 Javascript
微信小程序 wxapp内容组件 text详细介绍
2016/10/31 Javascript
vue2.0 如何把子组件的数据传给父组件(推荐)
2018/01/15 Javascript
JS实现简单的点赞与踩功能示例
2018/12/05 Javascript
vue中使用vue-cli接入融云实现即时通信
2019/04/19 Javascript
原生js实现滑块区间组件
2021/01/20 Javascript
[48:48]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Dream TIME
2014/05/21 DOTA
[42:23]完美世界DOTA2联赛PWL S3 Forest vs Rebirth 第二场 12.10
2020/12/13 DOTA
Python中有趣在__call__函数
2015/06/21 Python
Python3.6正式版新特性预览
2016/12/15 Python
Django权限机制实现代码详解
2018/02/05 Python
Django1.9 加载通过ImageField上传的图片方法
2018/05/25 Python
Python爬虫使用脚本登录Github并查看信息
2018/07/16 Python
Python简单处理坐标排序问题示例
2019/07/11 Python
python opencv根据颜色进行目标检测的方法示例
2020/01/15 Python
scrapy结合selenium解析动态页面的实现
2020/09/28 Python
Hoka One One法国官网:美国专业跑鞋品牌
2018/12/29 全球购物
搞笑创意广告语
2014/03/17 职场文书
车间主任岗位职责范本
2015/04/08 职场文书
MySQL 百万级数据的4种查询优化方式
2021/06/07 MySQL
Python实现归一化算法详情
2022/03/18 Python
CentOS7安装GlusterFS集群以及相关配置
2022/04/12 Servers