Vue - 实现双击显示编辑框;自动聚焦点击的显示框;点击编辑框外的地方,隐藏编辑框
实现这三个功能的踩坑记录。
1. 需求
在Vue中,有一个input, 双击时编辑文本,点击该input节点外的其他地方,则取消编辑。

那么这里有三个要实现的地方
第一是双击显示编辑框。
第二是自动聚焦点击的显示框。
第三是点击编辑框外的地方,隐藏编辑框。
一二点都是在startPipeLineNameEdit这个method中去实现。
2. 实现双击显示编辑框
思路: 使用两个span包含双击前和双击后的代码,用isEditingPipeLineName这个变量去控制显示与否。(PipeLineName与我写的当前组件有关)。
然后绑定一个双击时的事件@dblclick="startPipeLineNameEdit"。
父组件BoardArea大致代码
//PipeLine是子组件,可见可以有很多个子组件实例,因为v-for了一个数组
<PipeLine
v-for="pipeLine in wrappedPipeLineList"
:pipeLine="pipeLine"
class="pipe-line-item"
:key="pipeLine.id"
/>
子组件PipeLine大致代码
<span v-show="!isEditingPipeLineName">
..未双击前
<span @dblclick="startPipeLineNameEdit"></span>
<span></span>
</span>
<span v-show="isEditingPipeLineName" v-model="editPipeLineName">
...双击后
<input class="edit-pipeline"...>
<button ...>save</button>
</span>
3. 实现编辑框自动聚焦。
方案一: 手动操作DOM(不建议,不符合Vue思想)
方案二: 自定义指令,无效。加入TODO,日后研究
方案三: autofocus,无效。加入TODO。
思路:操作DOM,找出那个DOM节点,然后focus。初学Vue,也想不到其他办法了。其实在Vue中自行操作DOM节点不好,因为Vue是数据驱动的,是自行更新DOM。
startPipeLineNameEdit() {
this.isEditingPipeLineName = true;
let edit_pipeline = document.querySelector('.edit-pipeline');
edit_pipeline.focus();
},
问题1 死活不能focus。

Google后,发现https://forum.vuejs.org/t/setting-focus-to-textarea-not-working/17891。
原来Vue有一个DOM更新周期,可以用$nextTick立即触发。
startPipeLineNameEdit() {
this.isEditingPipeLineName = true;
this.$nextTick(() => {
let edit_pipeline = document.querySelector('.edit-pipeline');
edit_pipeline.focus();
}
},
问题2 只能focus第一个pipeline

原因: 
解决办法:改成querySelectorAll然后遍历好了
startPipeLineNameEdit() {
this.isEditingPipeLineName = true;
this.$nextTick(() => {
let edit_pipelines = document.querySelectorAll('.edit-pipeline');
edit_pipelines.forEach((element) => {
element.focus();
})
});
},

4. 实现点击编辑框外的地方,隐藏编辑框
方法1 首先想到的是“点击外面”,然后google: "vue click away", "vue click outside"等关键字,找到https://stackoverflow.com/questions/36170425/detect-click-outside-element。
里面有自定义vue指令的,也有两个轮子。选用其中一个轮子vue-clickaway。
// 按文档上开整
<input class="edit-pipeline" type="text" v-model="editPipeLineName" v-on-clickaway="away">
away() {
console.log('clicked away');
this.isEditingPipeLineName = false;
},
方法1出现的问题(还没解决有TODO)
性能损耗严重: 如果有n个Pipeline, 则每次会触发n次这个函数。如果这个函数里面有密集计算(例如加个循环加法),导致非常卡。

弃用这个轮子,可能这个轮子不适合去实现这个功能。
还有个原生和jQuery的“点击外面”的方法,现在功力不行,加入TODO。
方法2 监听blur事件
得益于自动聚焦(focus),那么我可以监听focus的相反事件blur。
<input class="edit-pipeline" type="text" v-model="editPipeLineName" @blur="away">

4. 问题又出现了,要解决blur和click冲突问题
原因应该是把逻辑写在blur里面不对。
方案一: 延迟blur函数里面的逻辑。可以用lodash里面的debounce或者直接在blur执行的回调函数里setTimeout(我这里采用这一种最简单的方案,延迟100毫秒)
方案二: 改为mousedown。用户体验不好。
总结
应该有其他优雅的实现方法,加入TODO。
Vue - 实现双击显示编辑框;自动聚焦点击的显示框;点击编辑框外的地方,隐藏编辑框的更多相关文章
- Vue国际化处理 vue-i18n 以及项目自动切换中英文
1. 环境搭建 命令进入项目目录,执行以下命令安装vue 国际化插件vue-i18n npm install vue-i18n --save 2. 项目增加国际化翻译文件 在项目的src下添加lang ...
- DataGridView单元格内容自动匹配下拉显示
页面显示数据使用的控件是ComponentFactory.Krypton.Toolkit中的KryptonDataGridView控件.在指定“商品”单元格中需要根据用户输入内容自动匹配数据库中商品信 ...
- Creating Dialogbased Windows Application (4) / 创建基于对话框的Windows应用程序(四)Edit Control、Combo Box的应用、Unicode转ANSI、Open File Dialog、文件读取、可变参数、文本框自动滚动 / VC++, Windows
创建基于对话框的Windows应用程序(四)—— Edit Control.Combo Box的应用.Unicode转ANSI.Open File Dialog.文件读取.可变参数.自动滚动 之前的介 ...
- vue打包后CSS中引用的背景图片不显示问题
vue项目中,在css样式中引用了一张背景图片,开发环境下是可以正常显示,build之后背景图片不显示. 解决方法: 找到build/utils.js文件 修改成为如下所示内容: 添加红框中的内容即 ...
- vue中点击空白处隐藏弹框(用指令优雅地实现)
在写vue的项目的时候,弹框经常性出现,并要求点击弹框外面,关闭弹框,那么如何实现呢?且听我一一...不了,能实现效果就好 <template> <div> <div c ...
- Ubuntu18.04系统下安装Pycharm&vim设置自动缩进及默认显示行号
Ubuntu18.04系统自带python3.6及python2.7,Pycharm是一款非常强大的IDE.目前Pycharm有两个版本:专业版和Community社区,区别是专业版是收费,而且功能更 ...
- 如何让input框自动获得焦点
项目中有个需求 一个用扫描枪输入的input框 为了避免每次都需要人为点击 需要做成当打开页面时该input框自动获取焦点 <input type="text" name= ...
- Js控制显示、隐藏文本框中的密码
Js控制显示.隐藏文本框中的密码,也可称为是一款小型的JavaScript星号密码破解器,点击会显示出密码类型的文本框中的真实信息,再次点击则还原,程序 主要是获取HTML元素对象,然后强制更改元素属 ...
- android中Textview 和图片同时显示时,文字省略号显示,图片自动靠到右边
很纠结的一个标题,实在是不知道怎么去描述这个现象. 上图片吧,先看看需求是什么样的. 1.需求: 视频与票的图标跟在标题后面显示,当标题过长时icon显示到省略号…后(textview省略号显示, ...
随机推荐
- Linux断网安装jdk1.8
1.创建目录存放jdk包 mkdir /usr/java 2.上传jdk包 通过xftp或者其他远程工具 3.解压jdk tar zxvf jdk-8u221-linux-x64.tar.gz 4.打 ...
- vue学习指南:第十四篇(详细) - Vue的 路由 第四篇 ( 路由的导航守卫 )
导航守卫 一.全局导航守卫 1. 全局导航守卫,把方法给 router,只要路由发生改变跳转都会触发这个函数 2. 每个路由 都有一个 meta 3. 全局导航守卫分两种: 1. 全局前置导航守卫:路 ...
- yii2验证规则
验证规则 1.内置验证规则 [['sex', 'partner_id'], 'integer'], [['partner_id', 'camp_id',], 'required'], [['creat ...
- Application Comparison Of LED Holiday Light And Traditional Incandescent Lights
Obviously, LED holiday lights are leading the competition in economical Christmas decorations, but t ...
- 银行贷款利率低到“令人发指”,很多人还坚持借高利贷,why?
编辑 | 于斌 出品 | 于见(mpyujian) 网络上,每隔一段时间,就会出现因为借了高利贷,家破人亡的新闻. 这种现象,层出不求,但其实,我们每次看了这些新闻,只是为其感到惋惜,并没有进一步去发 ...
- 软件工程 实验一 Git版本管理
实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2) 熟练掌握git的基本指令和分支管理指令: 实验内容: 1)安装git 2)初始配置git ,git init git status指 ...
- sql语句代码规范
19年年底的时候领导一直强调代码规范化以前写代码的时候很随意后来越来越看自己写的代码难受逐渐的也像规范化走去,今天又学了一招记录分享一下 这张图就是以前写代码的时候正常情况很是杂乱无章 这张就是规范话 ...
- Spring AOP操作action时无法注入,报NullPointer异常
Spring AOP操作action时无法注入,报NullPointer异常当使用Spring AOP对action层进行操作时,会出现注入失败的问题,出现空指针异常.原因是一般struts2+spr ...
- Junit +cucumber 运行报错 initiallizationError
step1: 访问 https://search.maven.org/ 搜索下载相关jar包 step2: 访问 http://maven.outofmemory.cn/info.cukes/cuc ...
- 调用百度地图api隐藏版权信息
调用百度地图API隐藏右下角版权信息 商用的话建议不要隐藏,避免侵权. 隐藏前: 隐藏后: .BMap_cpyCtrl { display: none; } .anchorBL { display: ...