写这篇博客的时候已经快11点了,但是这么奇葩的bug我遇到了并且解决了,还是很开心的
bug复现场景:
el-table里使用了treeselect,因为行数太多,列表里大量使用了treeselect非常卡顿,el-table的性能没有vxe-table好,所以换成了vxe-table的可编辑列表。
vxe-table的可编辑列表性能是真的好,其实如果不是奇怪的需求,单说vxe-table本身,还是很好用的,文档也很齐全。
vxe-table的可编辑列表有两个插槽,一个是默认插槽,一个是编辑插槽。如果没有特殊要求,单用编辑插槽其实啥问题都没有。
但是要求是列表不能有抖动的感觉,看文档,点击哪一行会变成下拉框,没有点击的什么样式都没有,要求要统一。
但是如果默认插槽和编辑插槽都用树插件的话,还是会遇到卡顿的现象。
所以默认插槽只能是div
在默认插槽为div的情况下,要求一点击输入框就获取焦点并打开树下拉框
难点就在于它是从div切换成树插件
反正是要解决,那就上代码吧
我实现的方式写自定义指令
定义一个js文件,myFocus.js
import Vue from 'vue'
//自定义输入框聚焦
export default {
inserted(el, binding, vnode) {
el.querySelector('input').focus()
vnode.componentInstance.openMenu()
},
}
const install = function (Vue) {
Vue.directive('hasRole', hasRole)
Vue.directive('hasPermi', hasPermi)
Vue.directive('reClick', reClick)
Vue.directive('tableFit', tableFit)
Vue.directive('myFocus', myFocus)
}
if (window.Vue) {
window['myFocus'] = myFocus
Vue.use(install)
}
export default install
在需要的页面直接使用 v-my-focus就行
<TreeSelect
ref="treeRef"
v-model="row.Code"
:options="deptOptions"
:normalizer="normalizer"
clearable
v-my-focus
loadingText="数据加载中"
:matchKeys="['name', 'code']"
placeholder=""
style="width: 100%"
:appendToBody="true"
:disable-branch-nodes="true"
open-direction="bottom"
@select="node => treeHandleSelect(row, rowIndex, node)"
@input="value => treeSelectInput(rowIndex, value)"
>
<div slot="option-label" slot-scope="{ node }" :style="{ marginLeft: !node.raw.children ? '16px' : '0' }">
[{{ node.raw.code }}]{{ node.raw.label }}
</div>
<div slot="value-label" slot-scope="{ node }">{{ row.Code ? `[${row.Code}]` : '' }}{{ row.Name }}</div>
</TreeSelect>
openMenu方法我是在源码里找到的,去GitHub上搜vue-treeselect就能看到源码
记录下思路,以后也不怕源码了
-------更新-----
早上来点击的时候发现了一个新的bug
就是树下拉框打开选完节点后,它没有自动关上,一直展示着
我本来是想在树节点点击事件里关闭,但是不起作用
看来还是要自定义指令关了
新增myBlur.js
import Vue from 'vue'
//自定义输入框关闭下拉框
export default {
componentUpdated(el, binding, vnode) {
if (el.querySelector('input').blur()) {
setTimeout(() => {
vnode.componentInstance.closeMenu()
}, 0)
}
},
}
首先要判断是否失去焦点,用instrted还是componentUpdated钩子函数,这个我没测试,在试的过程中发现,如果没有定时器,可能会同时执行,也有可能是因为一开始没有写判断条件,反正都可以自己试试,我的已经实现了,就懒得再测了