vue2 实战:模板模式与渲染模式代码互切

文章详细描述了在Vue中使用模板和渲染模式创建组件,包括如何处理删除、拖拽和插件操作,以及组件间的通信。展示了如何在表格行中实现删除按钮、输入框、插件按钮和可拖动列表的动态展示。
摘要由CSDN通过智能技术生成

显示效果

模板模式

<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-button
          v-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.$listeners
    if(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.$listeners
    return(
      <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-limit
             value={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 null
  return 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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值