当前位置: 首页 > Web前端 > vue.js

一条指令为各大vue组件库的表格组件添加动态编辑功能

时间:2023-03-31 22:22:31 vue.js

在现代vue组件库上实现表格编辑并不难。大部分都提供scopeslots,可以使用在slots中插入输入组件来实现。但是这样做有个缺点,太重了!填表几十行、上百行的输入滞后几乎是不可避免的,很难做到美观。想实现动态编辑功能其实很简单。我们只需要在当前点击的单元格中渲染输入,光标离开销毁输入即可。这里,我们使用Vue自定义指令来实现,因为指令不支持直接数据双向绑定。在参数上设计了两个hook,value和input,一个用来获取值,一个用来赋值importVuefrom'vue';constisFunc=v=>typeofv==='函数';常量getTargetEl=(el,nodeName)=>!nodeName||el.nodeName===节点名?el:el.parentElement?getTargetEl(el.parentElement,nodeName):undefined;functioncreateInput(options){constinput=document.createElement('input');输入.className=options.inputClass||'v-场';input.type=options.inputType||'文本';input.value=isFunc(options.value)?options.value():options.value;返回输入;}consttargets=[];functionhandle(el,binding){constoptions=binding.value||{};consttargetEl=getTargetEl(el,options.nodeName||'TD');if(targetEl){lettarget=targets.find(v=>v.el===targetEl),inputEl,disabled;如果(!target){target={options,el:targetEl};targets.push(目标);目标Elstyle.position='相对';targetEl.addEventListener(options.event||'click',()=>{disabled=isFunc(options.disabled)?options.disabled():options.disabled;if(!disabled&&!inputEl){inputEl=createInput(target.options);targetEl.appendChild(inputEl);inputEl.focus();inputEl.onblur=()=>{target.options.input&&target.options.input(inputEl.value);targetEl.removeChild(inputEl);inputEl=undefined;};}});}else{target.options=options;}}}constVField={inserted:handle,update:handle,};/***v-field="{value:()=>row.name,input:v=>row.name=v}"*/Vue.directive('字段',VField);代码写完之后,我们需要定义这个inputStyle,我在createInput的代码中默认给它添加了.v-field类,并提供了inputClass配置项,方便自定义扩展通过可以绑定指令的dom在范围槽中使用:v=>row.date=v}"类似于下面的例子row.date,input:v=>row.date=v}">{{row.date}}提供一个事件配置项,指定触发事件,默认是点击,你也可以设置如下对dblclick实现双击编辑row.date,input:v=>row.date=v}">{{row.date}}还有一个配置项nodeName用来过滤绑定事件对象,默认是TD,如果你想要在表头中使用,需要将其更改为TH。参考下面element-ui的示例效果。我测试了几个流行的vue组件库,它们都可以正常工作。element-uiiviewantd-vue通过npm使用这个命令,已经被我打包进了npm。安装npmi--savev-field并在入口文件中注册使用importVuefrom"vue";importVFieldfrom"v-field";Vue.use(VField);//可以通过第二个参数传给你任何你想改的命令名,默认是`field`通过npm使用的例子https://codesandbox.io/s/v-field-hh8g2已经开源在github,有想法的朋友可以提交代码https://github。com/akebe/v-field