最近項(xiàng)目中遇到的需求是要操作大量的表單,之前的項(xiàng)目中有做過這方的研究,只不過是用jquery來操作。
創(chuàng)新互聯(lián)2013年開創(chuàng)至今,先為廣州等服務(wù)建站,廣州等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為廣州企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
項(xiàng)目A
先簡單說說以前項(xiàng)目A中的應(yīng)用場景,可能有小伙伴兒也遇到相同的需求。A項(xiàng)目是公司的OA系統(tǒng)中有的項(xiàng)目,是用java的jsp渲染的頁面,需求是要改成:嵌入APP中顯示,前后端分離, 后端返回的內(nèi)容,還不能修改, 只是后端同事做了下接口處理,返回給前端的是一大堆的表單數(shù)據(jù)。
每個(gè)表單都有多個(gè)字段表示它的屬性:
項(xiàng)目B
現(xiàn)在遇到的項(xiàng)目,展示類型少很多,第一個(gè)想到的就是同樣的方法,不過這次使用的是Vue的雙向綁定。
以下是我在python后端項(xiàng)目中的經(jīng)驗(yàn),如果沒有興趣可以直接看最后的動(dòng)態(tài)表單部分
1 python 后端項(xiàng)目中如何引入Vue
項(xiàng)目B用的是python的jinjia2的模板, 同樣都是 {{}} 去解析數(shù)據(jù),這種情況下怎么辦呢?
{% 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 可以阻止解析內(nèi)部的代碼,這樣就可以引入我們的vue模板了,這里是我寫的一個(gè)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) } })
動(dòng)態(tài)表單組件
一般的需求是:
1 如何生成動(dòng)態(tài)表單
<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>
我們的與后端商量好的數(shù)據(jù)格式可以是這樣的;
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: '女' }] }]
這樣一個(gè)動(dòng)態(tài)模板就生成了,其他更多類型都可以定義。這份模板數(shù)據(jù),一般是需要緩存的。因?yàn)榻酉聛淼?添加操作也需要這份數(shù)據(jù)。
添加操作
上面的template只是其中一個(gè)動(dòng)態(tài)列表。
<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: '女' }] }] }) },
這里需要注意的是,如果這份模板的數(shù)據(jù),你是通過在data屬性中定義的字段去緩存的,那有可能遇到的是你通過添加操作之后的表單的值會(huì),會(huì)隨著其中的某個(gè)表單的值一起聯(lián)動(dòng)。
具體原因,猜測是這里的數(shù)據(jù)已經(jīng)是變成響應(yīng)式的了, 又或者你 通過實(shí)例化后的值去緩存這份模板數(shù)據(jù),可能結(jié)果還是這樣。
具體代碼可能是這樣的:
var vm = new Vue({ data: { books: [], cacheTemplate: null }, methods: { getForms: function (argument) { this.$http.post(url, paras).then(res => { // 此處緩存了這份模板數(shù)據(jù),cacheTemplate中的數(shù)據(jù)已經(jīng)變成響應(yīng)式的了 this.cacheTemplate = res.body.data this.books.push(res.body.data) // 創(chuàng)建第一動(dòng)態(tài)表單列表 // 或者你是這是定義的的, 此時(shí)data中沒有cacheTemplate這個(gè)值, // 這樣定義按理說是非響應(yīng)式的,但實(shí)際情況并非如此,在項(xiàng)目中發(fā)現(xiàn)它還是會(huì)影響其他表單 vm.cacheTemplate = res.body.data this.books.push(res.body.data) // 創(chuàng)建第一動(dòng)態(tài)表單列表 }, res => { }) }, add: function () { // 此處你會(huì)發(fā)現(xiàn)你新創(chuàng)建的表單的值會(huì)影響其他表單 // log出來this.cacheTemplate你會(huì)發(fā)現(xiàn)里面的值已經(jīng)發(fā)生了變換 this.books.push(this.cacheTemplate) } } })
這里this.cacheTemplate的值為什么會(huì)發(fā)生變換,沒有搞明白, 猜測原因可能是變成響應(yīng)式了,vue中會(huì)實(shí)時(shí)監(jiān)控跟蹤,對(duì)vue原理理解好的小伙伴可以評(píng)論告訴我原因。
下面說下我的解決方法: 我不管你是不是響應(yīng)式的,因?yàn)槭菍?duì)象,你才能監(jiān)控到變換,那我把你變成字符串不就好了。
直接上代碼:
var vm = new Vue({ data: { books: [], cacheTemplate: null }, methods: { getForms: function (argument) { this.$http.post(url, paras).then(res => { // 此處同樣緩存了這份模板數(shù)據(jù),不同的是把它變成了字符串 this.cacheTemplate = JOSN.stringify(res.body) this.books.push(res.body) // 創(chuàng)建第一動(dòng)態(tài)表單列表 }, res => { }) }, add: function () { // 此處轉(zhuǎn)化成json對(duì)象,你發(fā)現(xiàn)this.cacheTemplate中的值是沒有變換的。 var cacheTemplate = JSON.parse(this.cacheTemplate) this.books.push(cacheTemplate) } } })
這樣其他表單值變換的時(shí)候都不會(huì)影響到我這份模板的數(shù)據(jù),問題解決了。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)頁標(biāo)題:vue2中如何實(shí)現(xiàn)動(dòng)態(tài)表單增刪改查實(shí)例
分享URL:http://muchs.cn/article4/jpjdie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、全網(wǎng)營銷推廣、小程序開發(fā)、網(wǎng)站策劃、用戶體驗(yàn)、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)