资讯专栏INFORMATION COLUMN

vue2 中如何实现动态表单增删改查

mmy123456 / 1016人阅读

摘要:最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用来操作。添加操作上面的只是其中一个动态列表。

最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用jquery来操作。

项目A

先简单说说以前项目A中的应用场景,可能有小伙伴儿也遇到相同的需求。A项目是公司的OA系统中有的项目,是用java的jsp渲染的页面,需求是要改成:嵌入APP中显示,前后端分离, 后端返回的内容,还不能修改, 只是后端同事做了下接口处理,返回给前端的是一大堆的表单数据。

每个表单都有多个字段表示它的属性:

是否可编辑

表单类型 (text, textarea, select, radio, checkbox, hidden等 )

与之联动的其他表单

。。。
之前的方案就是各个表单类型和字段属性进行判断,调用不同的UI组件(如时间日历选择器等)

项目B

现在遇到的项目,展示类型少很多,第一个想到的就是同样的方法,不过这次使用的是Vue的双向绑定。

以下是我在python后端项目中的经验,如果没有兴趣可以直接看最后的动态表单部分

1 python 后端项目中如何引入Vue

项目B用的是python的jinjia2的模板, 同样都是 {{}} 去解析数据,这种情况下怎么办呢?

{% raw %}

{% endraw %}

jinjia2中使用 raw 可以阻止解析内部的代码,这样就可以引入我们的vue模板了,这里是我写的一个dialog弹框的组件
2 定义组件
这里以dialog弹窗组件为例子,直接上代码

// dialog弹框
Vue.component("ms-dialog", {
  name: "ms-dialog",
  template: "#dialog-wrap",
  data: function () {
    return {
    }
  },
  props: {
    title: String,
    value: {
      type: Boolean,
      required: false
    }
  },
  computed: {
    visible: function () {
      return this.value
    }
  },
  watch: {
    visible: function (newVal) {
      if (newVal) {
        document.addEventListener("wheel", this.disabledScroll, false)
      } else {
        document.removeEventListener("wheel", this.disabledScroll, false)
      }
    }
  },
  methods: {
    confirmSuccess: function () {
      this.$emit("confirm-success")
    },
    cancelAction: function () {
      this.$emit("input", false)
    },
    disabledScroll: function (e) {
      e.preventDefault()
    }
  },
  beforeDestroy: function () {
    document.removeEventListener("scroll", this.disabledScroll, false)
  }
})
动态表单组件

一般的需求是:

一个列表,可以实现列表的动态添加,删除。

列表中的每一项是动态的表单,表单个数不确定,

有提交功能,提交或者可以保存整个表单

保存的表单,通过接口调回后,回填表单,还可以再次修改、增加、删除等

1 如何生成动态表单

我们的与后端商量好的数据格式可以是这样的;

lists:  [{
  type: "input",
  defaultValue: "tom",
  value: "tom"
}, {
  type: "input",
  defaultValue: "123456",
  value: "123456"
}, {
  type: "textarea",
  defaultValue: "123456",
  value: "123456"
}, {
  type: "select",
  defaultValue: "0",
  value: "0",
  source: [{
    value: "1",
    label: "男"
  }, {
    value: "1,
    label: "女"
  }]
}]

这样一个动态模板就生成了,其他更多类型都可以定义。这份模板数据,一般是需要缓存的。因为接下来的 添加操作也需要这份数据。

添加操作

上面的template只是其中一个动态列表。

add的方法一般是:

methods: {
 add:  function () {
   this.books.push({
    lists:  [{
      type: "input",
      defaultValue: "tom",
      value: "tom"
    }, {
      type: "input",
      defaultValue: "123456",
      value: "123456"
    }, {
      type: "textarea",
      defaultValue: "123456",
      value: "123456"
    }, {
      type: "select",
      defaultValue: "0",
      value: "0",
      source: [{
        value: "1",
        label: "男"
      }, {
        value: "1,
        label: "女"
      }]
    }]
 })
 },

这里需要注意的是,如果这份模板的数据,你是通过在data属性中定义的字段去缓存的,那有可能遇到的是你通过添加操作之后的表单的值会,会随着其中的某个表单的值一起联动。
具体原因,猜测是这里的数据已经是变成响应式的了, 又或者你 通过实例化后的值去缓存这份模板数据,可能结果还是这样。
具体代码可能是这样的:

var vm = new Vue({
    data: {
        books: [],
        cacheTemplate: null
    },
    methods: {
        getForms: function (argument) {
            this.$http.post(url, paras).then(res => {
                // 此处缓存了这份模板数据,cacheTemplate中的数据已经变成响应式的了
                this.cacheTemplate = res.body.data
                this.books.push(res.body.data) // 创建第一动态表单列表

                // 或者你是这是定义的的, 此时data中没有cacheTemplate这个值, 
                // 这样定义按理说是非响应式的,但实际情况并非如此,在项目中发现它还是会影响其他表单
                vm.cacheTemplate = res.body.data
                this.books.push(res.body.data) // 创建第一动态表单列表
            }, res => {

            })
        },
        add: function () {
            // 此处你会发现你新创建的表单的值会影响其他表单
            // log出来this.cacheTemplate你会发现里面的值已经发生了变换
            this.books.push(this.cacheTemplate)
        }
    }
})

这里this.cacheTemplate的值为什么会发生变换,没有搞明白, 猜测原因可能是变成响应式了,vue中会实时监控跟踪,对vue原理理解好的小伙伴可以评论告诉我原因。
下面说下我的解决方法: 我不管你是不是响应式的,因为是对象,你才能监控到变换,那我把你变成字符串不就好了。
直接上代码:

var vm = new Vue({
    data: {
        books: [],
        cacheTemplate: null
    },
    methods: {
        getForms: function (argument) {
            this.$http.post(url, paras).then(res => {
                // 此处同样缓存了这份模板数据,不同的是把它变成了字符串
                this.cacheTemplate = JOSN.stringify(res.body)
                this.books.push(res.body) // 创建第一动态表单列表
            }, res => {

            })
        },
        add: function () {
            // 此处转化成json对象,你发现this.cacheTemplate中的值是没有变换的。
            var cacheTemplate = JSON.parse(this.cacheTemplate)
            this.books.push(cacheTemplate)
        }
    }
})

这样其他表单值变换的时候都不会影响到我这份模板的数据,问题解决了。
如果觉得本文不错的话,欢迎点赞。如有问题, 大家一起交流和学习

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44428.html

相关文章

  • vue2 如何实现动态表单删改

    摘要:最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用来操作。添加操作上面的只是其中一个动态列表。 最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用jquery来操作。 项目A 先简单说说以前项目A中的应用场景,可能有小伙伴儿也遇到相同的需求。A项目是公司的OA系统中有的项目,是用java的jsp渲染的页面,需求是要改成:嵌入A...

    StonePanda 评论0 收藏0
  • vue2.0+axios+elementUI实现删改

    最近尝试使用vue+element实现增删改查功能,在实现的过程中遇到了蛮多问题,现在总结如下:首先安装相关的插件1、根据vue官网推荐,使用axios进行前后台交互,安装axiosnpm install axios -S2、安装elementUI,官网npm i element-ui -S3、安装 loader 模块npm install style-loader -Dnpm install c...

    rollback 评论0 收藏0
  • Vue+Mock.js模拟登录和表格的删改

    摘要:表示需要拦截的请求类型。表示数据模板,可以是对象或字符串。表示用于生成响应数据的函数。指向本次请求的选项集。生成规则是可选的。返回成功的数据,就是登录成功了,否则相反。模拟登录接下来介绍模拟表格增删改查。 前言 关于mockjs,官网描述的是 1.前后端分离 2.不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。 3.数据类型丰富 4.通过随机数据,模拟各种场景。 5...

    coordinate35 评论0 收藏0
  • [译]如何使用Flask开发一个删改的应用(part2)

    摘要:获取成为开发专家的技巧。我们可以在两个文本框输入笔记的标题和内容。在本教程中,我们将使用一个名为的工具。它是一个火狐浏览器的扩展,我们可以使用它管理数据库。安装,打开火狐浏览器,点击,然后点找到的文件夹图标并点击它。 showImg(https://cdn-images-1.medium.com/max/600/1*Ou6FFJJD3zhcIUU8wBZqIw.png); 教程译文首发...

    adam1q84 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<