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省略号显示, ...
随机推荐
- AcWing 894. 拆分-Nim游戏
#include <cstring> #include <iostream> #include <algorithm> #include <unordered ...
- ORA-01476: 除数为 0
假设是a/bdecode(b,0,null,a/b) 这样如果b为0,输出null,不为0输出a/b decode():将查询结果翻译成其他值,类似三目运算符 比较1个参数时 decode( ...
- C++-对象指针的滥用
C++ 中经常出现使用对象指针,而不是直接使用对象本身的代码,比如下面这个例子: Object *myObject = new Object; 而不是使用: myObject.testFunc(); ...
- Qt- 图形界面应用程序的运行模式
main() 定义主窗口 ————>fd = DefineMainWindow() 创建主窗口————>win = CreateMainWindow() 创建主窗口中的元素-----> ...
- k线中转器
自动同步服务器k线,将交易日k线存入共享内存,交易平台直接去共享内存取想要的数据. 默认提供期货1.3.5分钟.日线数据.如果想要自定义,可以通过copydata向它发送请求,可以提供任何周期,任何偏 ...
- 我写的UI自动化框架
---------------------------------------------------------------------------------------------------- ...
- C++-POJ1021-2D-Nim[hash]
哈希,对于每个点哈希一次 哈希的方式:该点到联通分量边界(上下左右)的距离和 然后分别对两个图的n个点按hash值排序,判断是否相等即可 #include <set> #include & ...
- Java-POJ1005-I Think I Need a Houseboat
盗用的翻译,哈哈哈!白嫖就完事了. 题目: 密西西比河岸某处陆地因为河水侵蚀,每年陆地面积都在减少,每年减少50平方英里,减少的陆地面积呈半圆形,即该半圆形面积以每年50平方英里的速度增长.在第一年初 ...
- 「题解」「CF853B」Jury Meeting
目录 题目 思路 代码 题目 传送门 思路 十分巧妙的差分前缀和好题. 题目板块完结之后,我看到有很多处理此题的方法,但总感觉差分前缀和比较巧妙. 首先,通过输入我们可以将每个人能在 \(0\) 号点 ...
- 路飞-Redis的使用,登录注册接口
复习 """ 1.git项目开发 提供公钥成为开发者.copy项目.开发项目 先commit.再pull(可能出现冲突).最后push 特殊功能可以新建dev的子分支进行 ...