Ruoyi表单构建

Ruoyi表单构建通过拖动组件就能自动生成前端代码,很方便,所以本文简单通过上层函数源码来梳理一下大致流程,如有需要再自行仔细一行行分析底层代码。

组件拖动

实现组件拖动功能主要依赖第三方库:VueDragger。简单通过例子+注释介绍一下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<draggable  
  class="components-draggable"  
  :list="inputComponents"
  :group="{ name: 'componentsGroup', pull: 'clone', put: false } 
  :clone="cloneComponent"
  draggable=".components-item"  
  :sort="false"  
  @end="onEnd"  
>  
  <div  
    v-for="(element, index) in inputComponents" :key="index" class="components-item"  
    @click="addComponent(element)"  
  >  
    <div class="components-body">  
      <svg-icon :icon-class="element.tagIcon" />  
      {{ element.label }}  
    </div>  
  </div>  
</draggable>

:list组件数据,:group group通过name来分组,pull和put设置拖出和拖入规则。

生成代码

点击导出vue文件或者是复制代码,可以将设计好的页面代码生成并且导出,这里我用复制代码功能作为例子来说明一下流程。

点击复制代码,显示弹窗

1
2
3
4
5
6
<code-type-dialog
      :visible.sync="dialogVisible"
      title="选择生成类型"
      :show-file-name="showFileName"
      @confirm="generate"
/>

这是一个自定义组件,子组件以el-dialog为主,当选择好弹窗类型并且点击确认时,子组件将 {fileName:null,type:'file'} 传出。然后调用generate。

1
2
3
4
5
	generate(data) {//data:{filename,type}
      const func = this[`exec${titleCase(this.operationType)}`]//拼接方法名字,然后调用
      this.generateConf = data
      func && func(data)
    },

this[ exec${titleCase(this.operationType)} ] 拼接出 execCopy,然后调用

1
2
3
execCopy(data) {
      document.getElementById('copyNode').click()
},

点击该元素。在html部分我们可以看到,该id对应的是一个隐藏的input元素,本身无任何功能。

关键部分

看似点击一个隐藏元素没有任何意义,实际上它只是触发关键的“钥匙”。在mounted()中,ruoyi使用的第三方库ClipboardJS构建了一个对象。clipboardJS是复制粘贴包,所以该部分就是实现的真正原理。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  mounted() {
    const clipboard = new ClipboardJS('#copyNode', {//当点击 id=copyNode的元素时,会触发复制
      text: trigger => {
        const codeStr = this.generateCode()//产生页面代码的关键方法
        this.$notify({
          title: '成功',
          message: '代码已复制到剪切板,可粘贴。',
          type: 'success'
        })
        return codeStr
      }
    })
    clipboard.on('error', e => { //此处就是一个失败回调。
      this.$message.error('代码复制失败')
    })
  },
...
}

该对象绑定了 “copyNode” 元素,点击该元素就会触发复制。text的值就是填充到粘贴版上的文本。

1
2
3
4
5
6
7
8
    generateCode() {
      const { type } = this.generateConf //就是{filename,type}
      this.AssembleFormData()//将drawingList和formConf组装成formData,方便之后使用。
      const script = vueScript(makeUpJs(this.formData, type))
      const html = vueTemplate(makeUpHtml(this.formData, type))
      const css = cssStyle(makeUpCss(this.formData))//构建出vue三段式字符串
      return beautifier.html(html + script + css, beautifierConf.html)
    },

这就是大致流程,如果需要了解生成代码更多的细节,可以自行深入调试。