在使用element-ui的table组件时,想全局配置一个空数据状态,重复写十分蛋疼。
试了下用函数式组件,算是假装实现了一波继承。
在后面开发的过程中,发现想改个prop的默认值,不想每次用组件的时候都写一次去改,于是弄出下面的改进版,针对props也可以做修改,这样继承就更完善了
函数式组件,extends
import { Table } from 'element-ui'const emptyComp = (h, text) => {const emptyTip = text || '暂无数据'return h('div', {slot: 'empty'}, [h('div', null, emptyTip)])}const myTable = {props: {stripe: {type: Boolean,default: true}},extends: Table// 继承element-ui的table// 覆盖了table默认prop,根据extends的描述,配置将会合并}export default {functional: true,render: function (h, context) {const childNode = [...context.children, emptyComp(h, context.props.emptyTxt)]return h(myTable, context.data, childNode)}}
函数式组件,修改attrs
import { Dialog } from 'element-ui'// 修改attrs,用assign来赋默认值// 注意:在 2.3.0 之前的版本中,如果一个函数式组件想要接收 prop,则 props 选项是必须的。// 在 2.3.0 或以上的版本中,你可以省略 props 选项,所有组件上的 attribute 都会被自动隐式解析为 prop。// 这就是为什么我直接放在attrs里,也可以当props用的原因export default {functional: true,render (h, context) {context.data.attrs = Object.assign({closeOnClickModal: false,closeOnPressEscape: false}, context.data.attrs)return h(Dialog,context.data,context.children)}}
普通组件,extends
普通的render模式仍然会产生一层template,要用ref的方式去调用组件内部方法就比较尴尬了
import { Table } from 'element-ui'const emptyComp = (h, text) => {const emptyTip = text || '暂无数据'return h('div', {slot: 'empty'}, [h('div', null, emptyTip)])}const myTable = {props: {stripe: {type: Boolean,default: true}},extends: Table// 继承element-ui的table// 覆盖了table默认prop,根据extends的描述,配置将会合并}export default {render: function (h) {const slots = Object.keys(this.$slots).reduce((arr, key) => arr.concat(this.$slots[key]), []).map(vnode => {vnode.context = this._selfreturn vnode})// 展开$slots为数组,并插入自己需要的插槽slots.push(emptyComp(h, this.emptyTxt))return h(myTable, {listeners: this.$listeners,props: this.$props,scopedSlots: this.$scopedSlots,attrs: this.$attrs}, slots)}}
函数式组件针对hooks的优雅写法,还没想到应用场景
export default {functional: true,render (h, { parent, children }) {if (parent._isMounted) {return children} else {parent.$once('hooks:mounted', () => {parent.$forceUpdate()})}}}
