-
demo背景:为用户发起活动时可自定义报名表单,使活动参与者报名时填写。由于表单需要在另一个页面显示并使用,所以要使表单可存储并渲染。
-
实现过程:百度并查阅了一系列关于自定义表单的内容后,在form-create中发现可以通过特定的JSON格式数据渲染表单,于是就写了一个简单的demo实现自定义的过程,将数据收集成特定的JSON格式来实现渲染。
先上效果图:
由于我的项目需要使移动端,所以简单做了一个移动端的demo来分享。
比较简陋,同时本人是新手,有写的不周到的地方欢迎指出
只是为了分享这个思路,随便画的界面!!!
只是为了分享这个思路,随便画的界面!!!
只是为了分享这个思路,随便画的界面!!!
实际效果图:
环境:
第一步
- vue-cli 2.X 关于安装就不赘述了
- form-create 安装可查看官方文档:http://www.form-create.com/v2/guide/start.html#%E5%BC%95%E5%85%A5-form-create-v2
通过npm安装
npm i @form-create/element-ui
第二步
然后在 main.js 中写入以下内容:
import formCreate from '@form-create/iview'
Vue.use(formCreate)
在相应页面写入:
方式1 <form-create v-model="fApi" :rule="rule" :option="option"></form-create>
方式2<div id="form-create"></div>
本demo采用的方式2,详细可查看文档用更详细的用法
第三步
data(){
rule: [],//存储表单json数据
}
mounted() {
//表单插入的节点
const root = document.getElementById('form-create');
//$f为表单api
const $f = window.formCreate.create(
//表单生成规则
this.rule,//存储JSON表单数据的数组
//组件参数配置
{
el:root,
//显示表单重置按钮
submitBtn: false, //控制是否显示提交按钮
resetBtn: false, //控制是否显示重置按钮
});
},
rule中可先放入一些假数据
rule: [
{"type":"input","field":"goods_name","title":"商品名称","value":"mi"},
{"type":"inputNumber","field":"goods_price","title":"商品价格","value":12}
]
进行到这一步时 如果环境与代码无误 页面时会显示相应的两项表单元素。
同理当其他页面作为表单的使用页时,将以上代码写入 并将格式合理的json数据存入rule就可以了
页面完整代码:
<template>
<div class="Form_box">
//此处只实现了输入框的demo,其它依葫芦画瓢即可实现
<div class="Form_topbar">
<div class="Form_item" @click="details(1)">输入框</div>
<div class="Form_item" @click="details(2)">单选</div>
<div class="Form_item" @click="details(3)">多选</div>
<div class="Form_item" @click="details(4)">文本框</div>
<div class="Form_item" @click="details(5)">图片</div>
<div class="Form_item" @click="details(6)">日期</div>
</div>
//这里是表单插入的地方,id要和js代码中的一致
<div id="app3">
<div class="form-create" id="form-create"></div>
</div>
//这里是表单项的配置弹窗,可根据需要改动
<div class="Form_details" v-if="showDetails">
<div class="Form_details_item">标题:
<input placeholder="例:姓名" maxlength="10" v-model="title">
</div>
<div class="Form_details_item">类型:
<el-select v-model="type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="Form_details_item">占位内容:
<input placeholder="例:请输入姓名" maxlength="10" v-model="placeholder">
</div>
<div class="Form_details_item">是否必填:
<el-switch
v-model="Required"
active-color="#13ce66"
inactive-color="#C0CCDA">
</el-switch>
</div>
<div class="Form_details_item">最大长度:
<el-input-number v-model="maxlength" :min="1" :max="50" label="描述文字"></el-input-number>
</div>
<div class="tapBar">
<div class="cancle" @click="cancle()">取消</div>
<div class="add" @click="add()">插入</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data(){
return{
maxlength: 1,//设置输入框最大长度
title:"",//存储表单元素标题
type:'',//存储表单元素类型
placeholder:'',//存储表单输入框占位符
Required:false,//存储表单元素类型
input:0,//用来改变表单元素id
showDetails:false,//表单细节弹窗
options: [{
value: 'text',
label: '字符'
}, {
value: 'number',
label: '数字'
}],//类型下拉框value
rule: [],//存储表单json数据
}
},
mounted() {
//表单插入的节点
const root = document.getElementById('form-create');
//$f为表单api
const $f = window.formCreate.create(
//表单生成规则
this.rule,
//组件参数配置
{
el:root,
//显示表单重置按钮
submitBtn: false,
resetBtn: false,
});
},
methods:{
//表单设置弹窗
details(index){
var that = this
that.showDetails = true;
},
//将填写好的数据整合成json并添加至rule
pushform(){
var that = this
let temp = {
type:'input',
title:that.title,
field:"input"+that.input,
value:"",
props: {
type:that.type,
maxlength:that.maxlength,
placeholder:that.placeholder,
},
validate:[
{
required: that.Required,
message: '不得为空',
},
],
}
that.rule.push(temp)
that.input++
return Promise.resolve()//为了解决异步
},
//添加表单元素并为其加入删除button
add(){
var that = this
let index = 0
//这样写为了解决异步
that.pushform().then(() => {
let newli = document.createElement('button');
newli.innerHTML="x";
newli.style.width='20px'
newli.style.height='20px'
newli.style.borderRadius='50%'
newli.style.position='absolute'
newli.style.right='20px'
newli.style.backgroundColor='#2cb3d0'
newli.style.color='#fff'
newli.onclick=function(e){
that.$forceUpdate()
that.del(e).then(()=>{
that.sort()
})
}
let tags = document.getElementsByTagName("div");
that.$forceUpdate()
for( let k in tags)
{
let tag = tags[k];
if(tag.className == 'el-col el-col-24') {
newli.value=index
tag.appendChild(newli);
index++;
}
}
});
},
//删除所选项
del(e){
var that =this
let id = e.target.value
that.rule.splice(id,1)
return Promise.resolve()
},
//对剩余元素重新排序(目的实现删除功能)
sort(){
let ind = 0
let tags = tags || document.getElementsByTagName("div");
for( let k in tags)
{
let tag = tags[k];
if(tag.className == 'el-col el-col-24') {
tag.childNodes[1].value=ind
ind++;
}
}
},
cancle(){
//省略
}
}
}
</script>
<style>
.el-col-24 {
height: 100px;
display: flex;
}
</style>
<style lang="less" scoped>
button{
border: unset;
}
.Form_box{
width:100%;
height: 100%;
position: relative;
.form-create{
position: relative;
.delbtn{
position: absolute;
right: 10px;
width: 50px;
}
}
.Form_topbar{
display: flex;
width: 100%;
white-space: nowrap;
overflow-x:scroll;
margin-bottom: 20px;
.Form_item{
background-color: #2cb3d0;
color: #fff;
border: 1px solid #000;
flex-shrink: 0;
width: 150px;
margin-left: 10px;
margin-top: 10px;
}
}
.Form_details{
text-align: left;
align-items: center;
width: 90%;
height: 50%;
background-color: #fff;
bottom: 10px;
position: absolute;
border: 1px solid #000;
left: 50%;
transform: translate(-50%);
.Form_details_item{
margin-top: 20px;
width: 500px;
margin: 20px auto;
}
.tapBar{
display: flex;
position: absolute;
bottom: 20px;
color: #fff;
width: 100%;
text-align: center;
justify-content: center;
.cancle{
background-color: gray;
width: 200px;
border-radius: 20px;
margin-right: 50px;
}
.add{
background-color: #13ce66;
width: 200px;
border-radius: 20px;
}
}
}
}
</style>
以上对form-create的简单使用。有很多不足的地方,欢迎大佬们指点和交流!!!!!