显示效果
模板模式
<template><tr ><td class="my-td" v-if="element.isInsert===1"><el-button type="danger" circle size="mini" class="delete-btn" title="删除" @click="deleteItem()" ><i class="el-icon-delete" /></el-button></td><td class="my-td" v-else></td><td class="my-td" ><el-input type="text" placeholder="请输入内容" maxlength="10" minlength="0" show-word-limit v-model="element.stepName" /></td><td class="my-td" > {{ element.componentName }} </td><td class="my-td" ><div><el-buttonv-for="(item, index) of this.element.plugins":key="index"type="text" circle size="mini" class="plugin-btn":icon="pluginsConf[item.layout].icon"@click="todoSomething(index, item)">{{ pluginsConf[item.layout].text }}</el-button></div></td><td class="my-td move"><el-button type="text" size="mini" style="color: #727272" class="move-btn" ><i class="el-icon-menu" /></el-button></td></tr>
</template><script>export default {props: ['element','indexParent','drawingList','pluginsConf',],methods: {deleteItem() {this.$emit("deleteItem", this.indexParent, this.drawingList);},todoSomething(index, item) {this.$emit("todoSomething", index, item, this.indexParent, this.element);}}
}
</script>
<style scoped lang='scss'>
.delete-btn { cursor: pointer;}
.move-btn { cursor: move;}
</style>
渲染模式
<script>
import draggable from 'vuedraggable'const operate = {itemBtns(h, element, index, parent,) {const { deleteItem } = this.$listenersif(element.isInsert==1) {return [<td class="my-td" ><el-button type="danger" circle size="mini" class="delete-btn" title="删除"onClick={event => { deleteItem(index, parent); event.stopPropagation() }}><i class="el-icon-delete" /></el-button></td>]} else {return [<td class="my-td" ></td>]}}
}const plugins = {defaultItem(h, element, index, elementParent, indexParent) {const { todoSomething } = this.$listenersreturn(<el-button type="text" circle size="mini" class="plugin-btn" icon={this.pluginsConf[element.layout].icon}onClick={event => { todoSomething(index, element, indexParent, elementParent); event.stopPropagation() }}>{this.pluginsConf[element.layout].text}</el-button>)},
}const layouts = {frameworkItem(h, element, index, parent) {let child = renderChildren.apply(this, arguments)return (<tr >{operate.itemBtns.apply(this, arguments)}<td class="my-td" ><el-input type="text" placeholder="请输入内容" maxlength="10" minlength="0" show-word-limitvalue={element.stepName}onInput={ value => element.stepName = value }/></td><td class="my-td" > { element.componentName } </td><td class="my-td" ><draggable list={element.components} animation={340} group="pluginGroup" class="drag-wrapper" handle=".move" >{child}</draggable></td><td class="my-td move"><el-button type="text" size="mini" style="color: #727272" class="move-btn" ><i class="el-icon-menu" /></el-button></td></tr>)}
}function renderChildren(h, elementParent, indexParent, parent) {if (!Array.isArray(elementParent.plugins)) return nullreturn elementParent.plugins.map((element, index) => {const plugin = plugins['defaultItem']if (plugin) {return plugin.call(this, h, element, index, elementParent, indexParent)}return pluginsIsNotFound()})
}function pluginsIsNotFound() {throw new Error(`没有与${this.element.layout}匹配的plugin`)
}export default {components: {draggable},props: ['element','index','drawingList','pluginsConf',],render(h) {const layout = layouts['frameworkItem']return layout.call(this, h, this.element, this.index, this.drawingList)}
}
</script><style scoped lang='scss'>
.delete-btn { cursor: pointer;}
.move-btn { cursor: move;}
</style>