关于javascript:免费开源基于Vue和Quasar的前端SPA项目crudapi零代码开发平台后台管理系统实战之之拖拽表单定制十六

114次阅读

共计 7836 个字符,预计需要花费 20 分钟才能阅读完成。

基于 Vue 和 Quasar 的前端 SPA 我的项目实战之拖拽表单定制(十六)

回顾

通过前一篇文章 基于 Vue 和 Quasar 的前端 SPA 我的项目实战之动静表单(五)的介绍,实现了元数据中动静表单设计性能,反对常见的数据类型和索引,而后实现了动静表单的 crud 增删改查性能,所有的表单页面都是默认的格调。本文次要介绍拖拽表单定制性能,通过拖拽的形式定制表单录入和编辑页面,满足了个性化需要。

简介

针对元数据表的每个字段,通过拖拽形式决定是否显示或者暗藏,而后还能够配置显示的宽度。最终以 json 格局保留到后盾数据库,运行时依据配置动静渲染录入和编辑表单 form 页面。针对不同的设施(电脑,平板,手机)都能够独自定制。

UI 界面


页面构建


运行时

代码

阐明

采纳开源框架 vuesortable,基于 vue 的实现排序,反对拖拽。页面构建分为左中右三个局部,右边为候选字段,两头为须要显示的字段,左边能够针对每个字段独自设置一些属性,比方宽度等。

数据表

创立表单 tableFormBuilder,用于存储页面构建 json 数据,包含类型 type、设施 device、内容 body 等字段, 充分利用 crudapi 性能,API 局部零代码实现。


tableFormBuilder

外围代码

页面构建

<draggable
  class="dragArea list-group row"
  :list="selectedList"
  group="people"
  @change="log"
>
  <div class="list-group-item q-pa-md" 
    v-for="formElement in selectedList"
    :key="formElement.columnId"
    :class="formElement | classFormat(currentElement)"
    @click="selectForEdit(formElement)"
  > 
    <div>
      <div 
        v-bind:class="{'required': !formElement.column.nullable}">
        {{formElement.column.caption}}:
      </div>
      <q-input v-if="isStringType(formElement)"
        readonly
        :placeholder="formElement.column.description"
        :type="formElement.isPwd ?'password':'text'"v-model="formElement.column.value" >
        <template v-slot:append v-if="!formElement.isText" >
          <q-icon
            :name="formElement.isPwd ?'visibility_off':'visibility'"class="cursor-pointer"@click="formElement.isPwd = !formElement.isPwd"
          />
        </template>
      </q-input>

      <q-editor readonly v-else-if="isTextType(formElement)"
        v-model="textValue"
        :placeholder="formElement.column.description" >
      </q-editor>

      <q-input v-else-if="isDateTimeType(formElement)" readonly>
        <template v-slot:prepend>
          <q-icon name="event" class="cursor-pointer">
            <q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
              <q-date
              mask="YYYY-MM-DD HH:mm:ss"
              @input="hideRefPopProxyAction('qDateProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>

        <template v-slot:append>
          <q-icon name="access_time" class="cursor-pointer">
            <q-popup-proxy ref="qTimeProxy" transition-show="scale" transition-hide="scale">
              <q-time mask="YYYY-MM-DD HH:mm:ss"
              format24h with-seconds
              @input="hideRefPopProxyAction('qTimeProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>
      </q-input>

      <q-input v-else-if="isDateType(formElement)" readonly>
        <template v-slot:append>
          <q-icon name="event" class="cursor-pointer">
            <q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
              <q-date
              mask="YYYY-MM-DD"
              @input="hideRefPopProxyAction('qDateProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>
      </q-input>

      <q-input v-else-if="isTimeType(formElement)" readonly>
        <template v-slot:append>
          <q-icon name="access_time" class="cursor-pointer">
            <q-popup-proxy ref="qTimeProxy" transition-show="scale" transition-hide="scale">
              <q-time  mask="HH:mm:ss"
              format24h with-seconds
              @input="hideRefPopProxyAction('qTimeProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>
      </q-input>

      <q-toggle v-else-if="isBoolType(formElement)" readonly
        v-model="formElement.column.value">
      </q-toggle>

      <q-input readonly
        v-else-if="isNumberType(formElement)"
        :placeholder="formElement.column.description"
        type="number"
        v-model="formElement.column.value" >
      </q-input>

      <CFile v-else-if="isAttachmentType(formElement)"
        v-model="formElement.column.value" >
      </CFile>

      <q-input v-else
        readonly
        :placeholder="formElement.column.description"
        :type="formElement.isPwd ?'password':'text'"v-model="formElement.column.value" >
        <template v-slot:append v-if="!formElement.isText" >
          <q-icon
            :name="formElement.isPwd ?'visibility_off':'visibility'"class="cursor-pointer"@click="formElement.isPwd = !formElement.isPwd"
          />
        </template>
      </q-input>
    </div>
    <div class="row reverse editable-element-action-buttons">
      <div class="justify-end q-pt-xs">
        <q-btn 
          @click="deleteElement(formElement)"
          v-if="isSelectedForEdit(formElement)" 
          class="editable-element-button" 
          color="red" 
          icon="delete" 
          round unelevated  size="xs">
          <q-tooltip> 移除 </q-tooltip>
        </q-btn>
      </div>
    </div>
  </div>
</draggable>

通过 draggable 标签实现

运行时渲染

<div v-if="selectedList.length > 0" class="row">
  <div class="list-group-item q-pa-md" 
    v-for="formElement in selectedList"
    :key="formElement.columnId"
    :class="formElement | classFormat">
    <div>
      <div 
        v-bind:class="{'required': !formElement.column.nullable}">
        {{formElement.column.caption}}:
      </div>

      <div class="row items-baseline content-center"
        style="border-bottom: 1px solid rgba(0,0,0,0.12)" 
        v-if="formElement.column.relationTableName">
        <div class="col-11">
          <span>{{formElement.column.value | relationDataFormat(formElement.column) }}</span>
        </div>
        <div class="col-1">
          <q-btn round dense flat icon="zoom_in" 
          @click="openDialogClickAction(formElement.column)" />
        </div>
      </div>

      <q-input v-else-if="isStringType(formElement.column.dataType)"
        v-model="formElement.column.value"
        :placeholder="formElement.column.description"
        :type="formElement.isPwd ?'password':'text'" >
        <template v-slot:append v-if="!formElement.isText" >
          <q-icon
            :name="formElement.isPwd ?'visibility_off':'visibility'"class="cursor-pointer"@click="formElement.isPwd = !formElement.isPwd"
          />
        </template>
      </q-input>

      <q-editor  v-else-if="isTextType(formElement.column.dataType)"
        v-model="formElement.column.value"
        :placeholder="formElement.column.description" >
      </q-editor>

      <q-input v-else-if="isDateTimeType(formElement.column.dataType)"
        v-model="formElement.column.value" >
        <template v-slot:prepend>
          <q-icon name="event" class="cursor-pointer">
            <q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
              <q-date v-model="formElement.column.value"
              mask="YYYY-MM-DD HH:mm:ss"
              @input="hideRefPopProxyAction('qDateProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>

        <template v-slot:append>
          <q-icon name="access_time" class="cursor-pointer">
            <q-popup-proxy ref="qTimeProxy" transition-show="scale" transition-hide="scale">
              <q-time  v-model="formElement.column.value"
              mask="YYYY-MM-DD HH:mm:ss"
              format24h with-seconds
              @input="hideRefPopProxyAction('qTimeProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>
      </q-input>

       <q-input v-else-if="isDateType(formElement.column.dataType)" 
        v-model="formElement.column.value">
        <template v-slot:append>
          <q-icon name="event" class="cursor-pointer">
            <q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
              <q-date  v-model="formElement.column.value"
              mask="YYYY-MM-DD"
              @input="hideRefPopProxyAction('qDateProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>
      </q-input>

      <q-input v-else-if="isTimeType(formElement.column.dataType)"
       v-model="formElement.column.value" >
        <template v-slot:append>
          <q-icon name="access_time" class="cursor-pointer">
            <q-popup-proxy ref="qTimeProxy" transition-show="scale" transition-hide="scale">
              <q-time   v-model="formElement.column.value" 
              mask="HH:mm:ss"
              format24h with-seconds
              @input="hideRefPopProxyAction('qTimeProxy')" />
            </q-popup-proxy>
          </q-icon>
        </template>
      </q-input>

      <q-toggle v-else-if="isBoolType(formElement.column.dataType)"
       v-model="formElement.column.value" >
      </q-toggle>

      <q-input 
        v-else-if="isNumberType(formElement.column.dataType)"
        v-model="formElement.column.value"
        :placeholder="formElement.column.description"
        type="number">
      </q-input>

      <CFile v-else-if="isAttachmentType(formElement.column.dataType)"
       v-model="formElement.column.value"
       @input="(data)=>{formElement.column.value = data.url;}"></CFile>

      <q-input v-else
        v-model="formElement.column.value"
        :placeholder="formElement.column.description"
        :type="formElement.isPwd ?'password':'text'" >
        <template v-slot:append v-if="!formElement.isText" >
          <q-icon
            :name="formElement.isPwd ?'visibility_off':'visibility'"class="cursor-pointer"@click="formElement.isPwd = !formElement.isPwd"
          />
        </template>
      </q-input>
    </div>
  </div>
</div>

判断是否存在定制页面,如果存在动静渲染,否则采纳默认页面布局。

例子

以产品为例,配置好录入页面之后,运行时原来的默认录入页面用新的页面代替,新的表单页面和之前配置的表单页面统一,性能不受影响,能够失常的录入数据。

小结

本文次要通过拖拽形式实现表单定制性能,应用十分不便,零代码定制表单录入和编辑页面,满足了个性化需要,整个过程无需写代码。

crudapi 简介

crudapi 是 crud+api 组合,示意增删改查接口,是一款零代码可配置的产品。应用 crudapi 能够辞别枯燥无味的增删改查代码,让您更加专一业务,节约大量老本,从而进步工作效率。crudapi 的指标是让解决数据变得更简略,所有人都能够收费应用!无需编程,通过配置主动生成 crud 增删改查 RESTful API,提供后盾 UI 治理业务数据。基于支流的开源框架,领有自主知识产权,反对二次开发。

demo 演示

crudapi 属于产品级的零代码平台,不同于主动代码生成器,不须要生成 Controller、Service、Repository、Entity 等业务代码,程序运行起来就能够应用,真正 0 代码,能够笼罩根本的和业务无关的 CRUD RESTful API。

官网地址:https://crudapi.cn
测试地址:https://demo.crudapi.cn/crudapi/login

附源码地址

GitHub 地址

https://github.com/crudapi/crudapi-admin-web

Gitee 地址

https://gitee.com/crudapi/crudapi-admin-web

因为网络起因,GitHub 可能速度慢,改成拜访 Gitee 即可,代码同步更新。

正文完
 0