How to add, delete, modify, and query instances for dynamic forms in vue2
Recently, a large number of forms need to be operated. This research has been done in the previous project, but jquery is used for operations.
Project
Let's talk about the application scenarios of Project A in the past. Some friends may have the same requirements. Project A is A project in the company's OA system and A page rendered using java jsp. The requirement is to change it to: embedded in the APP for display, frontend and backend separation, and content returned by the backend, it cannot be modified yet, but the back-end colleague processed the interface and returned a lot of form data to the front-end.
Each form has multiple fields to indicate its attributes:
- Editable or not
- Form Type (text, textarea, select, radio, checkbox, hidden, etc)
- Other forms associated with it
- ... The previous scheme was to judge various form types and field attributes and call different UI components (such as the time and calendar selector)
Project B
There are a lot of display types for the current project. The first thought is the same method, but this time we use Vue two-way binding.
The following is my experience in python backend projects. If you are not interested, you can directly view the final dynamic form section.
1. How to introduce Vue in python backend Projects
Project B uses the python jinjia2 template, which also resolves data. What should I do in this case?
{% 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> </div> <div class = "ms-dialog- actions "> <a class =" ms-button "@ click =" cancelAction "> cancel </a> <a class =" ms-button ms-success "@ click =" confirmSuccess "> OK </a> </div> <div class =" ms-overlayer "@ click =" cancelAction "> </div> </div> </script >{% endraw %}
Using raw in jinjia2 can prevent internal code parsing, so that we can introduce our vue template. Here is a component of the dialog pop-up box I wrote.
2. Define Components
The following uses the dialog pop-up window component as an example to describe the Code directly.
// Vue in the dialog box. 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 )}})
Dynamic form component
The general requirements are:
- A list that can be dynamically added or deleted.
- Each item in the list is a dynamic form with an uncertain number of forms,
- The submit function is available. You can submit or save the entire form.
- Save the form. After the interface is called back, you can repeat, add, and delete the form.
1. How to generate a dynamic form
<Template v-for = "item in lists"> <div class = "list-item" v-if = "list. type = 'input' "> <label> User Name </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> password </label> <input type =" text "v-model =" item. value ": value =" list. defaultValue "class =" form-control "> </div> <div class =" list-item "v-if =" list. type = 'tarea '"> <label> description </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> gender </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>
The data format we have discussed with the backend can be like this;
Lists: [{type: 'input', defaultValue: 'Tom ', value: 'Tom'}, {type: 'input', defaultValue: '000000', value: '000000'}, {type: 'textta', defaultValue: '000000', value: '000000'}, {type: 'select', defaultValue: '0', value: '0', source: [{value: '1', label: 'male'}, {value: '1, label: 'female}]
Such a dynamic template is generated, and Other types can be defined. This template data usually needs to be cached. This data is also required for the next add operation.
Add operation
The template above is only a dynamic list.
<div v-for="book in books"> <template v-for="item in book.lists"> ...... </template></div><div class="actions"><button @click="add"></button></div>
The add method is generally:
Methods: {add: function () {this. books. push ({lists: [{type: 'input', defaultValue: 'Tom ', value: 'Tom'}, {type: 'input', defaultValue: '200 ', value: '20140901'}, {type: 'textea ', defaultValue: '20160901', value: '20160901'}, {type: 'select', defaultValue: '0 ', value: '0', source: [{value: '1', label: 'mal'}, {value: '1, label: female '}]})},
Note that if the template data is cached by the fields defined in the data attribute, it is possible that the value of the form after you add the operation will be linked with the value of a form.
The specific reason is that the data here has become responsive, or you can cache the template data by instantiating the value. The possible result is still like this.
The specific code may be as follows:
Var vm = new Vue ({data: {books: [], cacheTemplate: null}, methods: {getForms: function (argument) {this. $ http. post (url, paras ). then (res => {// The template data is cached here, and the data in cacheTemplate has become responsive. this. cacheTemplate = res. body. data this. books. push (res. body. data) // create the first dynamic form List // or you define it. At this time, the value of cacheTemplate is not in data. // This defines non-responsive, however, this is not the case. It is found in the project that it will still affect other form VMS. cacheTemplate = res. body. data this. books. push (res. body. data) // create the first dynamic form List}, res = >{})}, add: function () {// here you will find that the value of the newly created form will affect other forms // log this. cacheTemplate, you will find that the value has been changed this. books. push (this. cacheTemplate )}}})
Here this. why does the value of cacheTemplate change? I didn't understand it. I guess the cause may be a response. vue will monitor and track it in real time. If I have a good understanding of the vue principle, I can comment on it and tell me why.
Next, let's talk about my solution: No matter whether you are responsive or not, you can monitor the transformation only when you are an object, so it's not good if I turn you into a string.
Directly run the Code:
Var vm = new Vue ({data: {books: [], cacheTemplate: null}, methods: {getForms: function (argument) {this. $ http. post (url, paras ). then (res => {// The template data is also cached here. The difference is that it is converted to the string this. cacheTemplate = JOSN. stringify (res. body) this. books. push (res. body) // create the first dynamic form List}, res = >{})}, add: function () {// convert it to a json object. You can find this. the values in cacheTemplate are not transformed. Var cacheTemplate = JSON. parse (this. cacheTemplate) this. books. push (cacheTemplate )}}})
In this way, other form values will not affect the data in this template. The problem is solved.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.