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

网友投稿 447 2023-05-08


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

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

项目A

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

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

是否可编辑

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

与之联动的其他表单

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

项目B

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

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

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

项目B用的http://是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 () {

http:// // 此处你会发现你新创建的表单的值会影响其他表单

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

}

}

})

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:基于vue2.0实现的级联选择器
下一篇:使用接口实现手机功能(接口类型手机)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~