最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用jquery来操作。
项目A
先简单说说以前项目A中的应用场景,可能有小伙伴儿也遇到相同的需求。A项目是公司的OA系统中有的项目,是用java的jsp渲染的页面,需求是要改成:嵌入APP中显示,前后端分离, 后端返回的内容,还不能修改, 只是后端同事做了下接口处理,返回给前端的是一大堆的表单数据。
每个表单都有多个字段表示它的属性:
项目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 如何生成动态表单
<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) } } })
这样其他表单值变换的时候都不会影响到我这份模板的数据,问题解决了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍mongodb+php实现简单的增删改查,包括了mongodb+php实现简单的增删改查的使用技巧和注意事项,需要的朋友参考一下 windows上安装mongodb的php扩展 下载地址https://s3.amazonaws.com/drivers.mongodb.org/php/index.html 找到对应的php版本的dll文件,下载php_mongo.dll,放到php安装
本文向大家介绍JS来动态的修改url实现对url的增删查改,包括了JS来动态的修改url实现对url的增删查改的使用技巧和注意事项,需要的朋友参考一下 虽然可以通过get方式提交post表单等方式来动态修改url,但如果多个按钮能并行提交时,写多个大体相同,又有些细节差异的表单,难免有些不妥,因此,想到了通过JS来动态的修改url,来实现对url的增删查改。
本文向大家介绍vue实现可增删查改的成绩单,包括了vue实现可增删查改的成绩单的使用技巧和注意事项,需要的朋友参考一下 前端变化层出不穷,去年NG火一片,今年react,vue火一片,ng硬着头皮看了几套教程,总被其中的概念绕晕,react是faceback出品,正在不断学习中,同时抽时间了解了vue,查看了vue官方文挡,看完格外入眼,总觉得要拿来试一试手。 正好周未,做一个小成绩单玩玩,以前有
本文向大家介绍Node.js+Express+Mysql 实现增删改查,包括了Node.js+Express+Mysql 实现增删改查的使用技巧和注意事项,需要的朋友参考一下 这次选用nodejs+express+mysql 使用http作为客户端,express框架搭建服务端,从而实现数据的增删改查。这篇文章可以算作上篇文章的升级篇,加入了和数据库的交互。 安装 node 直接去官网下载选择下载
一、前言 在第二章《Memcached源码分析 - Memcached源码分析之命令解析(2)》 和第三章《Memcached源码分析 - Memcached源码分析之消息回应(3)》 中我们主要通过Memcached的get命令,分析了Memcached的命令解析和消息回应的模块功能。这一章,我们主要来详细看一下Memcached常用的增删改查操作。 在看Memcached的增删改查操作前,我们
本文向大家介绍PHP MySql增删改查的简单实例,包括了PHP MySql增删改查的简单实例的使用技巧和注意事项,需要的朋友参考一下 mysql_connect()连接数据库 mysql_select_db选择数据库 mysql_fetch_assoc()获取结果集 mysql_query()执行sql语句 实例如下: 以上这篇PHP MySql增删改查的简单实例就是小编分享给大家的全部内容了,