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

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

项目A

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

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

  1. 是否可编辑
  2. 表单类型 (text, textarea, select, radio, checkbox, hidden等 )
  3. 与之联动的其他表单
  4. 。。。之前的方案就是各个表单类型和字段属性进行判断,调用不同的UI组件(如时间日历选择器等)

项目B

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

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

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

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

{% raw %}
<script type="text/x-template" id="dialog-wrap">
<div class="ms-dialog-wrap" v-show="visible">
 <div class="ms-dialog-inner">
  <div class="ms-dialog-title">{{title}}</div>
  <div class="ms-dialog-body">
   <div class="ms-dialog-content">
    <slot></slot>
   </div>
   <div class="ms-dialog-actions">
    <a class="ms-button" @click="cancelAction">取消</a>
    <a class="ms-button ms-success" @click="confirmSuccess">确定</a>
   </div>
  </div>
 </div>
 <div class="ms-overlayer" @click="cancelAction"></div>
</div>
</script>
{% 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. 一个列表,可以实现列表的动态添加,删除。
  2. 列表中的每一项是动态的表单,表单个数不确定,
  3. 有提交功能,提交或者可以保存整个表单
  4. 保存的表单,通过接口调回后,回填表单,还可以再次修改、增加、删除等

1 如何生成动态表单

<template v-for="item in lists">
   <div class="list-item" v-if="list.type === 'input'">
    <label>用户名</label>
    <input type="text" v-model="item.value" :value="list.defaultValue" class="form-control">
   </div>
   <div class="list-item" v-if="list.type === 'input'">
    <label>密码</label>
    <input type="text" v-model="item.value" :value="list.defaultValue" class="form-control">
   </div>
   <div class="list-item" v-if="list.type === 'textarea'">
    <label>说明</label>
    <textarea rows="3" v-model="item.value" :value="list.defaultValue" class="form-control"></textarea>
   </div>
   <div class="list-item" v-if="list.type === 'select'">
    <label>性别</label>
    <select v-model="list.value" :value="list.defaultValue">
      <option v-for="sub in list.source" :value="sub.value">{{sub.label}}</option>
    </select>
   </div>
</template>

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

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只是其中一个动态列表。

<div v-for="book in books">
  <template v-for="item in book.lists">
   ......
  </template>
</div>
<div class="actions">
<button @click="add"></button>
</div>

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)
    }
  }
})

这样其他表单值变换的时候都不会影响到我这份模板的数据,问题解决了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue.js+Element实现表格里的增删改查

    新项目使用的是vue.js 后来发现饿了吗前端编写的一套框架Element (http://element.eleme.io/#/zh-CN)来配合vue.js进行样式填充 之前用过angularjs 用到后来 发现越来越难学 于是就决定用vue.js 下面就介绍一下vue.js应用在表格里的增删改查 首先引入一下element的js <script src="plugins/element-ui/index.js"></script> 然后引入需要用到的vue

  • Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(一)

    环境搭建 spring boot的简介 以往我们开发时用到spring总是避免不了繁琐的配置,例如我们要配置一个数据库连接,可能需要以下几步: 1.编写jdbc.properties配置文件: 2.创建spring的配置文件,加入spring配置文件前缀.配置数据库连接信息以及sqlsessionFactory等等: 3.还要在web.xml文件中加入spring的监听. springboot的出现大大简化了项目的搭建过程(spring配置以及maven配置),让我们专注于应用功能的开发,而不是

  • JS组件系列之MVVM组件 vue 30分钟搞定前端增删改查

    正文 前言:关于Vue框架,好几个月之前就听说过,了解一项新技术之后,总是处于观望状态,一直在犹豫要不要系统学习下.正好最近有点空,就去官网了解了下,看上去还不错的一个组件,就抽空研究了下.最近园子里vue也确实挺火,各种入门博文眼花缭乱,博主也不敢说写得多好,就当是个学习笔记,有兴趣的可以看看. 一.MVVM大比拼 关于MVVM,原来在介绍knockout.js的时候有过讲解,目前市面上比较火的MVVM框架也是一抓一大把,比如常见的有Knockout.js.Vue.js.AvalonJS.An

  • vue实现表格数据的增删改查

    在管理员的一些后台页面里,个人中心里的数据列表里,都会有对这些数据进行增删改查的操作.比如在管理员后台的用户列表里,我们可以录入新用户的信息,也可以对既有的用户信息进行修改.在vue中,我们更应该专注于对数据的操作和处理. 比如我们有一个这样的页面: 我们在这个页面里,就实现了增删改查4个功能,点击链接查看demo[http://www.xiabingbao.com/demo/vue-curd/index.html]. 我们把这些用户信息保存到list的数组中,然后增删改查就在这个数组上进行:

  • Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(二)

    在上篇文章给大家介绍了Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(一),接下来我们添加分页相关的依赖,时间紧张,直接上代码了,贴上我的pom文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=

  • vue实现表格增删改查效果的实例代码

    整理文档,搜刮出一个vue实现表格增删改查效果的实例代码,稍微整理精简一下做下分享. 实现效果 我们把这些用户信息保存到list的数组中,然后增删改查就在这个数组上进行: list: [ { username: 'aaaaa', email: '123@qq.com', sex: '男', province: '北京市', hobby: ['篮球', '读书', '编程'] }, { username: 'bbbbb', email: 'bbbbbbb@163.com', sex: '女', p

  • vue增删改查的简单操作

    本文为大家分享了vue增删改查的简单操作,供大家参考,具体内容如下 我们把这些用户信息保存到list的数组中,然后增删改查就在这个数组上进行: list: [ { username: 'aaaaa', email: '123@qq.com', sex: '男', province: '北京市', hobby: ['篮球', '读书', '编程'] }, { username: 'bbbbb', email: 'bbbbbbb@163.com', sex: '女', province: '河北省'

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

    最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用jquery来操作. 项目A 先简单说说以前项目A中的应用场景,可能有小伙伴儿也遇到相同的需求.A项目是公司的OA系统中有的项目,是用java的jsp渲染的页面,需求是要改成:嵌入APP中显示,前后端分离, 后端返回的内容,还不能修改, 只是后端同事做了下接口处理,返回给前端的是一大堆的表单数据. 每个表单都有多个字段表示它的属性: 是否可编辑 表单类型 (text, textarea, select, radio,

  • 使用Laravel中的查询构造器实现增删改查功能

    引言 上一篇介绍了如何在windows环境下跑一个 laravel 项目,这一篇写如何使用 laravel 中的 查询构造器 实现增删改查. 读这篇文章时我默认你已拥有如下知识: 了解php的基础语法 了解数据库设计 了解常用的sql查询 正文 实现增删改查前, 我们先准备一些步骤: php, nginx, mysql 服务正确启用 新建一个数据库及其数据表 开启服务我们打开上篇文章介绍的 Wnmp.exe -> Start all 然后cmd上键入命令: D:/wnmp/Wnmp/php/ph

  • MySQL 详细单表增删改查crud语句

    MySQL 增删改查语句 1.创建练习表 这里练习表没有满足三范式 第一范式(又称 1NF):保证每列的原子性 数据表中的每一列(字段),必须是不可拆分的最小单元,也就是确保每一列的原子性.满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了. 第二范式(又称 2NF):保证一张表只描述一件事情 满足1NF后要求表中的所有列,每一行的数据只能与其中一列相关,即一行数据只做一件事.只要数据列中出现数据重复,就要把表拆分开来. 第三范式(又称 3NF):保证每列都

  • Java对象转JSON时动态的增删改查属性详解

    1. 前言 日常开发中少不了JSON处理,少不了需要在JSON中添加额外字段或者删除特定字段的需求.今天我们就使用Jackson类库来实现这个功能. 2. JSON字符串增加额外字段 假如我们有这样结构的JSON: { "username":"felord.cn", "age":18 } 期望增加一个性别字段gender: { "username": "felord.cn", "age"

  • vue中使用element-ui进行表单验证的实例代码

    element-ui 中验证 一.简单逻辑验证(直接使用rules) 实现思路 •html中给el-form增加 :rules="rules" •html中在el-form-item 中增加属性 prop="名称" •js中直接在data中定义rules:{} •html部分 <el-form ref="form" :rules="rules" :model="form" label-width=&q

  • python numpy中对ndarry按照index增删改查

    在numpy中的ndarry是一个数组,因此index就是位置下标,注意下标是从0开始 增加:在插入时使用np.insert(),在末尾添加时使用np.append() 删除:需要使用np.delete() 修改:直接指定下标 查找:直接指定下标 示例代码: import numpy as np if __name__ == '__main__':     array = np.array(["a", "b", "c", "d"

  • 简述Mybatis增删改查实例代码

    编写一个简单的mybatis进行插入数据的实例 1 数据库建表 其中建表dob=Date of Birth 的意思 create table students (stud_id number primary key, name varchar2(20), email varchar2(20), dob date ); Oracle数据库中出现表已创建,则表示创建成功,如果出现名称已被使用,则可在建表之前进行删除操作:drop table students;或者进行级联删除drop table s

  • IntelliJ Idea SpringBoot 数据库增删改查实例详解

    SpringBoot 是 SpringMVC 的升级,对于编码.配置.部署和监控,更加简单 微服务 微服务是一个新兴的软件架构,就是把一个大型的单个应用程序和服务拆分为数十个的支持微服务.一个微服务的策略可以让工作变得更为简便,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议. Spring 为 微服务提供了一整套的组件-SpringClound , SpirngBoot 就是该基础. 第一个SpringBoot程序 这里使用的开发软件是IntelliJ Idea,和Eclipse

  • python链接oracle数据库以及数据库的增删改查实例

    初次使用python链接oracle,所以想记录下我遇到的问题,便于向我这样初次尝试的朋友能够快速的配置好环境进入开发环节. 1.首先,python链接oracle数据库需要配置好环境. 我的相关环境如下: 1)python:Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 17:26:49) [MSC v.1900 32 bit (Intel)] on win32 2)oracle:11.2.0.1.0 64bit.这个是server版本号,在链接oracle

随机推荐