背景
这两天我打算抽象一个简单的表格组件,需要将类似elementUI的table-column
那样将插槽里的内容应用到cell里面,这时我就需要在模板里面渲染vNode了,由于之前我是参考elementUI实现表格组件的,这次只是简单实现,就没有给项目引入jsx(主要是想试试其他的实现,在工作之余找点乐趣。。)。也是在网上找了很久,网上倒是确实有方案,但好像讲得不是很浅显,至少我是差点漏过去了。
感谢这个哥们,解决了我的问题,我这里其实也只是再将他的方案写的清晰一点而已。
话说,vue3都出来了,现在写这个估计也没有多少用了,想着就当是水一下文章也好也许恰好还是有人需要,毕竟也不是每个公司都马上就上vue3不是。。
方案
其实方式就是创建一个组件,将vnode当作参数传入,利用createElement api 渲染,或者说在render里面渲染。可以创局部变量,当然也可以抽离出一个render-dom
组件。我的话是创建了局部变量,主要是感觉这种也不是很通用,再者那个参数的类型写得不是很好,基本就是报一个错补一个类型,( ╯□╰ ),就没有抽出来。
~~
{
components: {
RenderDom: {
props: {
vNode: [Array, String, Object, Number] // 这里为什么要这么写其实报一个类型检测不通过我补一个的,一开始我只写了数组和字符串。因为我这里其实不一定是vnode,毕竟直接传字符串和数字也可以,干嘛非得是vnode
},
render (h) {
if (typeof this.vNode === 'object') {
return this.vNode
} else {
return h('div', this.vNode)
}
}
}
}
}
后来补充的:在之前写这篇文章的时候,当时写代码的时候,查完上面提到的网址的答案,直接就写了,后面我重新review自己的代码时发现之前的写法是有问题的(当然你看到这段文字的时候,上面的代码已经修正了)。随便也补充一下为什么要这么写,当时纯粹是报错一个补一下,但是现在回看代码,我想可以解释的清除一点。
先来看看之前我是怎么写的:
render (h) {
return h('div', this.vNode)
}
实际上,这样写是有问题的,依据就看vue的官方文档:
可以参考createElement 参数
如下图所示,第二个参数如果是对象的话,会被识别为一个与模板中attribute
对应的数据对象,这时就渲染不出来了,但是对象的话,正常来说,这个就是vNode了,这时我们可以直接return
。而如果是string
或者number
以及array
类型的话直接return
是不可以的,所以都需要用一个div
去进行包裹。
至于使用,大概就是类似这样
<RenderDom :vNode="vNode"></RenderDom>
好了,以上就是今天全部内容了,希望可以帮到你,再见。