Skip to content

如何与后台交互

SSC edited this page Nov 10, 2020 · 3 revisions

进入此文档说明你已经了解了设计器的基本属性,已经可以成功开始使用了。

前言

到此我们已经可以在设计器里完成绝大部分的表单拖拽设计了。若还有更复杂的需求可以到 github码云 fork源码,自己修改。或者提交issue/pr。 回到正题,有很多同学都有一个问题:表单设计完了,怎么和后端交互存入到数据库呢?由于avue的配置并不是纯json,所以这边建议数据库字段使用varchar类型,而不是json类型。

开始

  • 本demo项目使用了avue-crud来实现增删改查,不了解的同学请前往Avue查看文档。
  • 使用vuex代替模拟数据库操作,实际在项目中替换增删改查四种方法即可。

模拟请求 store.js

import Vue from 'vue'
import Vuex from 'vuex'

import createPersistedState from 'vuex-persistedstate' // 缓存vuex

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    list: [{
      id: '1',
      key: '表单key',
      name: '表单名称',
      content: ''
    }],
  },

  mutations: {
    SET_LIST: (state, list) => {
      state.list = list
    },
  },

  actions: {
    GetData({ state }) { // 模拟获取列表
      return new Promise((resolve) => {
        resolve(state.list)
      })
    },
    SubmitData({ commit, state }, data) { // 模拟提交/更新
      return new Promise((resolve, reject) => {
        if (!data) reject('参数错误')

        let list = state.list

        if (data.id) {
          const index = list.findIndex(l => l.id == data.id)
          if (index != -1) {
            list.splice(index, 1, data)
          }
        } else {
          data.id = Date.now() + '_' + Math.ceil(Math.random() * 99999)
          list.push(data)
        }
        commit("SET_LIST", list)
        resolve()
      })
    },
    DeleteData({ commit, state }, data) { // 模拟删除
      return new Promise((resolve, reject) => {
        if (!data) reject('参数错误')
        let list = state.list

        if (data.id) {
          const index = list.findIndex(l => l.id == data.id)
          if (index != -1) {
            list.splice(index, 1)
            commit("SET_LIST", list)
            resolve()
          }
        }
        reject('删除失败')
      })
    }
  },
  plugins: [createPersistedState({
    storage: window.sessionStorage
  })]
})

页面展示 App.vue

<template>
  <div style="padding: 20px">
    <avue-crud :option="option"
               :table-loading="loading"
               :data="data"
               v-model="form"
               @row-update="rowUpdate"
               @row-save="rowSave"
               @row-del="rowDel"
               @on-load="onLoad">
      <template slot="menu"
                slot-scope="{row}">
        <el-button type="text"
                   icon="el-icon-edit-outline"
                   @click="handleDesign(row)">设计</el-button>
      </template>
    </avue-crud>

    <el-dialog :visible.sync="visible"
               title="表单设计"
               fullscreen
               :before-close="handleClose">
      <avue-form-design style="height: 89vh"
                        ref="formDesign"
                        :toolbar="['clear', 'preview', 'import']"
                        :includeFields="['group', 'dynamic', 'input', 'textarea', 'number', 'map', 'radio','checkbox','select','tree','cascader', 'upload', 'date','time','datetime','daterange','datetimerange','timerange','ueditor','switch','rate','color','icon','slider']"
                        :options="options">
        <template slot="toolbar">
          <el-button type="text"
                     size="medium"
                     icon="el-icon-download"
                     @click="handleSubmit">保存</el-button>
        </template>
      </avue-form-design>
    </el-dialog>
  </div>
</template>

<script>
// import { getList, add, update, remove } from "@/api/flow/form";

export default {
  data() {
    return {
      visible: false,
      options: {},
      form: {},
      loading: true,
      selectionList: [],
      option: {
        tip: false,
        border: true,
        index: true,
        selection: true,
        dialogType: 'drawer',
        align: 'center',
        column: [
          {
            label: "表单key",
            prop: "key",
            rules: [{
              required: true,
              message: "请输入表单key",
              trigger: "blur"
            }],
            // search: true
          },
          {
            label: "表单名称",
            prop: "name",
            rules: [{
              required: true,
              message: "请输入表单名称",
              trigger: "blur"
            }],
            // search: true
          },
        ]
      },
      data: []
    }
  },
  methods: {
    // 提交设计器配置
    handleSubmit() {
      this.$refs.formDesign.getData('string').then(data => {
        this.row.content = data
        this.$store.dispatch("SubmitData", this.row).then(() => {
          this.$message.success("保存成功")
          this.visible = false
        })
      })
    },
    // 设计器关闭前
    handleClose(done) {
      this.$confirm('关闭会丢失未保存的配置, 是否继续?', '提示', {
        type: 'warning'
      }).then(() => {
        done()
      }).catch(() => {
      })
    },
    // 开始设计
    handleDesign(row) {
      this.visible = true
      this.options = this.deepClone(row.content || '')
      this.row = row
    },
    // 增
    rowSave(row, loading, done) {
      loading()
      this.$store.dispatch("SubmitData", row).then(() => {
        this.onLoad(this.page)
        this.$message({
          type: "success",
          message: "操作成功!"
        })
      }).catch((error) => {
        done()
        console.log(error)
      })
    },
    // 删
    rowDel(row) {
      this.$confirm("确定将选择数据删除?", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        return this.$store.dispatch("DeleteData", row)
      }).then(() => {
        this.onLoad(this.page)
        this.$message({
          type: "success",
          message: "操作成功!"
        })
      })
    },
    // 改
    rowUpdate(row, index, loading, done) {
      loading()
      this.$store.dispatch("SubmitData", row).then(() => {
        this.onLoad(this.page)
        this.$message({
          type: "success",
          message: "操作成功!"
        })
      }).catch((error) => {
        done()
        console.log(error)
      })
    },
    // 查
    onLoad(page, params = {}) {
      this.loading = true
      this.$store.dispatch("GetData", params).then(res => {
        this.data = res
        this.loading = false
      })
    }
  }
};
</script>

<style>
</style>

最终效果
输入图片说明

总结
  1. 使用设计器设计表单。
  2. 使用this.$refs.formDesign.getData('string').then(data => {})方法获取设计好的js(string格式)。
  3. 将已存在的js赋值avue-form-design的options属性来继续设计表单。(string格式可直接赋值)
  4. 将已存在的js赋值avue-form的option属性来展示设计好的表单。(string格式需使用 eval('(' + js + ')')转换后赋值)