原文: https://ravenq.github.io/blog.md/el-tree-dblclick.html
目前 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)
在你的代碼中可以直接使用 <el-tree>
並且支持雙擊事件了。
<template>
<el-tree @node-dblclick="hdlDblclick" />
</template>
<script>
export default {
methods: {
hdlDblclick() {
console.log('tree node dblclick event.')
}
}
}
</script>