企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
* [x] 表格`el-table`+分页`el-pagination` * [x] 弹窗`el-dialog` ## 封装思路 借助`render`(渲染)函数实现 * 原生render函数写起来比较难受的。但可以通过[Babel 插件](https://github.com/vuejs/jsx)实现用于在 Vue 中使用 [JSX ](https://cn.vuejs.org/v2/guide/render-function.html#JSX)语法,它可以让我们回到更接近于模板的语法上(官方原话,哈哈)。 首先看看我们组件中的`this`都有些什么: * 列举几个常用属性:`$attrs`、`$children`、`$listeners`、`$slots`等等,关键是在`vue2.x`怎么用,可点击查看[文档](https://github.com/vuejs/jsx#installation)。 * 这里先说属性和方法的绑定方式:绑定属性:`{...{ attrs: this.$attrs }}`;绑定方法:`{...{ on: this.$listeners }}`,下面会用到。 ![](https://img.kancloud.cn/55/d7/55d7c7b4bfbf3450891bbc842925ec42_1201x585.png) ## 版本说明 ``` "element-ui": "2.13.2", "vue": "2.6.10", ``` ## 表格+分页封装 * 网上确实有很多`JSON`+`el-table`+`el-pagination`封装的方式,什么意思呢?就是把HTML换成JS写法,并没有起到简化作用,个人认为反而带来更大的(他人)学习和维护(额外配置)成本,所以这并不算是很好的一种方式; * 我认为封装的定义:在尽可能保留原来的基础上,扩展、补充或者说“承上启下”的过程中干点什么,这样在使用时,即可按照原基础配置即可使用,更多附带功能才需要去查看和学习。 * 好了,废话不多说,说说我是如何封装的吧,借助`render`(渲染)函数实现,不过写起来比较难受,但好在可以通过[Babel 插件](https://github.com/vuejs/jsx)实现用于在 Vue 中使用 [JSX ](https://cn.vuejs.org/v2/guide/render-function.html#JSX)语法,它可以让我们回到更接近于模板的语法上(官方原话,哈哈)。 * 无非就是属性和方法的绑定: 1. 绑定属性:`{...{ attrs: this.$attrs }}` 2. 绑定方法:`{...{ on: this.$listeners }}` * 代码如下: ``` jsx <div class='xxx-table-container'> <el-table {...{ attrs: this.$attrs }} {...{ on: this.$listeners }}> {this.$slots.default} // 可以干点什么,如具名插槽 </el-table> </div> ``` ## 弹窗封装 如何实现属性和方法的绑定,其实封装起来就简单很多了,弹窗的代码如下: ``` jsx <script> import elDragDialog from '@/directive/el-drag-dialog' export default { name: 'NexiotDialog', directives: { elDragDialog }, props: { closeOnClickModal: { type: Boolean, default: false }, sureBtn: { // 无slot='footer'时生效 type: Boolean, default: true } }, methods: { close() { this.$emit('update:visible', false) // this.$emit('close', false) }, sureSubmit() { this.$emit('submit', true) } }, render() { return ( <el-dialog v-el-drag-dialog custom-class='nexiot-dialog-container' {...{ attrs: { ...this.$attrs, 'close-on-click-modal': this.closeOnClickModal } }} {...{ on: this.$listeners }} > {this.$slots.default} {this.$slots.footer ? ( <span slot='footer' class='dialog-footer'> {this.$slots.footer} </span> ) : ( <span slot='footer' class='dialog-footer'> <el-button {...{ on: { click: this.close }}}>取 消</el-button> {this.sureBtn ? ( <el-button {...{ on: { click: this.sureSubmit }}} type='primary'> 确 定 </el-button> ) : ( '' )} </span> )} </el-dialog> ) } } </script> <style lang="scss" scoped> ::v-deep .nexiot-dialog-container { .el-dialog__header { padding: 0 16px; border-bottom: 1px solid #eee; height: 50px; line-height: 50px; .el-dialog__title { font-weight: 500; font-size: 16px; } } .el-dialog__headerbtn { top: 15px; } .el-dialog__footer { padding: 16px; } .el-dialog__body { padding: 16px 16px 0; } } </style> ```