场景
Cesium中双击飞到对应图层位置
方案
方法1
参考:https://blog.csdn.net/q469731241/article/details/107356605/
<el-tree
ref="tree"
node-key="id"
:data="treeData"
:expand-on-click-node="false"
@node-click="handleNodeClick">
</el-tree>
<script>
data() {
return {
//定义点击次数,默认0次
treeClickCount: 0,
}
},
methods: {
//节点点击事件
handleNodeClick(data, node) {
//记录点击次数
this.treeClickCount++;
//单次点击次数超过2次不作处理,直接返回,也可以拓展成多击事件
if (this.treeClickCount >= 2) {
return;
}
//计时器,计算300毫秒为单位,可自行修改
this.timer = window.setTimeout(() => {
if (this.treeClickCount == 1) {
//把次数归零
this.treeClickCount = 0;
//单击事件处理
this.console('单击事件,可在此处理对应逻辑')
} else if (this.treeClickCount > 1) {
//把次数归零
this.treeClickCount = 0;
//双击事件
this.console('双击事件,可在此处理对应逻辑')
}
}, 300);
}
}
</script>
类似写法参考:https://www.lihuyong.com/archives/1383
<el-tree
:data="data"
node-key="id"
:props="defaultProps">
<span slot-scope="{node, data}">
<span @dblclick="clkDb()" @click="clk()">{{data.label}}</span>
</span>
</el-tree>
<script>
let debounceTimer;
export default {
data() {
return {
data: [],
timer: null
}
},
methods: {
// 对同一元素添加单击@click和双击@dblclick事件时,双击事件执行之前单击事件总会执行两次,于是用函数去抖对此方法进行了修改
clk() {
debounceTimer = this.timer;
if (debounceTimer) {
window.clearTimeout(debounceTimer);
this.timer = null;
}
this.timer = window.setTimeout(() => {
console.log("click");
}, 300);
},
clkDb() {
debounceTimer = this.timer;
if (debounceTimer) {
window.clearTimeout(debounceTimer);
this.timer = null;
}
console.log("db click");
}
}
}
</script>
方法2 封装的思想可以借鉴
https://github.com/ravenq/ravenq.github.io/blob/master/blog.md/el-tree-dblclick.md
参见原文:https://blog.csdn.net/my___dream/article/details/104571980
目前 element-ui 的 tree 控件不支持双击事件,在后台管理系统时经常需要双击事件。
如果在 element-ui 源码上直接添加双击事件是很简单的,我已经在 github 上提交了 issue: #17448 和 PR。
但是等待官方更新都很慢,项目急着需要,而且官方不一定采纳你的 PR。
那么只有两个解决方案,一种比较土,直接 clone 一个官方版本,直接改,自己编译,自己使用,这样有一个很明显的缺点,很难跟进官方的版本。
因此这里主要介绍另外一种方法:非侵入式的封装。
首先引入 elment-ui 的 tree
import Tree from 'element-ui'
Tree.name = 'extend-base-el-tree' // 改名
Vue.use(Tree) // 注册
这里我对原生 element-ui 的 tree 进行了改名,为了是在使用在分装的树组件读可以直接使用 `````。如果以后官方采纳了 PR 直接删除再分装的代码就好了,不需要修改应用代码。
然后,创建一个自己的 el-tree.vue
文件
<template>
<extend-base-el-tree v-bind="$attrs" @node-click="hdlClick" />
</template>
<script>
import debounce from 'lodash.debounce'
export default {
inheritAttrs: false,
data() {
return {
clickCount: 0
}
},
methods: {
hdlClick() {
const args = arguments
// 发送单击事件
this.$emit('nod-click', ...args)
// 发送双击事件
this.clickCount++
const fnEmitDblClick = debounce(() => {
if (this.clickCount > 1) {
this.$emit('node-dblclick', ...args)
}
this.clickCount = 0
}, 500)
fnEmitDblClick()
}
}
}
</script>
在封装的组件需要引入原生组件的所有属性,因此使用 Vue 的 v-bind="$attrs"
方法,绑定所有属性。
在组件里监听单击事件,使用 lodash 的 debounce 方法,判定在 500 毫秒内点击数大于 1 则发送双击事件。
还有一个细节,发送事件的时候会有很多参数,我们不必一个个的定义在发送,可以使用 js 的 arguments 特性,在用一个结构赋值 ...args
转发所有参数即可。
最后,因为 Vue 的事件是使用 $emit
方法发送的,因此 $attrs
只能绑定属性,事件需要在封装的组件中监听在转发,就像单击事件一样。
这只是一个临时解决方案,你可根据使用到的事件进行转发,也可以一次性把原生 Tree 的事件都转发出去。
最后的最后,只需要全局注册我们自己的封装过的树组件就可以了
import ElTree from './your/path/to/your/el-tree.vue'
Vue.component('el-tree', ElTree)
在你的代码中可以直接使用 `` 并且支持双击事件了。
<template>
<el-tree @node-dblclick="hdlDblclick" />
</template>
<script>
export default {
methods: {
hdlDblclick() {
console.log('tree node dblclick event.')
}
}
}
</script>