1.调查问卷系统-整合formDesigner

1.1调查问卷系统

1、在若依上整合formDesigner

参考原文:如何将formDesigner集成到前端管理模板中 - 酒肉空间 - OSCHINA - 中文开源技术交流社区

1、下载 formDesigner 组件最新版本代码

2、下载完毕之后解压,取得 formDesigner 组件源码,完整复制到自己前端项目中

image-20240315220532938image-20240315220606312

3、将 formDesigner 组件中 asset 目录下的 iconfont 目录复制到项目的 asset 目录下,以避免出现表单组件的图标无法显示

image-20240315220732337

4、找到项目中 formDesigner 组件目录的 /index.js 文件,作者的项目路径为:ruoyi-ui/src/components/formDesigner/index.js,圈中的红框内,需要解决路径依赖,作者调整为相对路径,亦可调整为项目的绝对路径。

image-20240315220907045

5、在项目中找到 main.js, 注册 formDesigner 组件(此处供参考)

路径:ruoyi-ui/src/main.js

image-20240315221458567

image-20240315221251310

6、解决依赖组件问题,对比 formDesigner 组件和项目的依赖,install 相关的组件

此图为原作者提供,下列为此项目所需的依赖:

img

下列为ruoyi+此项目的依赖参考(可自行修改版本):

路径:ruoyi-ui/package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
"dependencies": {
"@babel/parser": "^7.7.4",
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.24.0",
"beautifier": "^0.1.7",
"china-area-data": "^5.0.1",
"clipboard": "2.0.8",
"core-js": "3.25.3",
"css-loader": "^3.5.3",
"echart": "^0.1.3",
"echarts": "^5.4.2",
"element-ui": "2.15.13",
"file-saver": "^2.0.5",
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"lodash": "^4.17.21",
"npm": "^6.13.7",
"nprogress": "0.2.0",
"quill": "1.3.7",
"resize-detector": "^0.3.0",
"screenfull": "5.0.2",
"sortablejs": "1.10.2",
"voca": "^1.4.0",
"vue": "2.6.12",
"vue-barcode": "^1.3.0",
"vue-codemirror": "^4.0.6",
"vue-count-to": "^1.0.13",
"vue-cropper": "0.5.5",
"vue-meta": "2.4.0",
"vue-qr": "^4.0.9",
"vue-quill-editor": "^3.0.6",
"vue-router": "3.4.9",
"vuedraggable": "2.24.3",
"vuex": "3.6.0",
"xlsx": "^0.18.5"
}

7、定义路由,和展示的页面:

在ruoyi中添加路由:

image-20240315222729489

对应的文件:

image-20240315222614831

下列为index.vue文件和view.vue文件参考(可自行修改,下列文件可以在原作者项目中找到示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div >
<form-designer ref="formDesigner" v-model="form.fdFrom"></form-designer>
</div>
</template>

<script>
export default {
name:'designerExample',
data(){
return{
form:{
fdFrom:''
}
}
},
}
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<template>
<div >
<el-card class="box-card">
<el-tabs v-model="tabName">
<el-tab-pane
:key="item.name"
v-for="item in tableTabs"
:label="item.title"
:name="item.name"
class="tab-pane"
>
<div v-if="item.name ==='form'">
<form-builder ref="formBuilder" v-model="formVal" :buildData="formCode" v-if="itemList.length>0" disabled/>
</div>
<codemirror v-model="code" :options="codeMirror" v-show="item.name ==='config'||item.name ==='value'"/>
<div v-if="item.name==='view'">
<form-viewer ref="formViewer" v-model="formVal" :buildData="formCode"></form-viewer>
</div>
<div v-if="item.name==='edit'">
<form-builder ref="formBuilder" v-model="formEditVal" :buildData="formEditCode" />
<div style="margin-bottom:15px;text-align:center">
<el-button type="primary" class="button" @click="editFormData()">回显数据</el-button>
</div>
</div>
</el-tab-pane>
</el-tabs>

</el-card>
</div>
</template>

<script>
import formBuilder from '@/components/formDesigner/formBuilder'
import formViewer from '@/components/formDesigner/formViewer'
import {codemirror} from 'vue-codemirror';
// 核心样式
import 'codemirror/lib/codemirror.css';
// 引入主题后还需要在 options 中指定主题才会生效
import 'codemirror/theme/dracula.css';
import 'codemirror/mode/javascript/javascript'
const options = {
tabSize: 2, // 缩进格式
theme: 'dracula', // 主题,对应主题库 JS 需要提前引入
lineNumbers: true, // 显示行号
line: true,
styleActiveLine: true, // 高亮选中行
hintOptions: {
completeSingle: true // 当匹配只有一项的时候是否自动补全
}
}
export default {
components:{
formBuilder,
codemirror,
formViewer
},
data(){
return{
formCode:'',
formVal:'',
formEditVal:'',
formEditCode:'',
tabName:'form',
tableTabs: [{
name: 'form',
}],
codeMirror:options
}
},
mounted(){
this.$nextTick(()=> {
const formCode = localStorage.getItem("formCode");
this.formCode = formCode;
// console.log(this.formCode)
const formVal = localStorage.getItem("formVal");
this.formVal = formVal;
// console.log(this.formVal)
})

},
methods:{
handlerchangeopen(){
},
editFormData(){
this.formEditCode = this.formCode;
this.formEditVal = this.formVal;
},
handlerSubForm(){
this.$refs['formBuilder'][0].validate();
if(this.formVal!==''){
this.addNewTab();
this.addEditTab();
}
},
addNewTab(){
if(this.tableTabs.length<4){
this.tableTabs.push({
title: '查看表单',
name: 'view'
});
}

},
addEditTab(){
if(this.tableTabs.length<5){
this.tableTabs.push({
title: '表单数据回显',
name: 'edit'
});
}

}
},
computed:{
itemList(){
if(this.formCode!==''){
const form = JSON.parse(this.formCode);
return form.list;
}else{
return [];
}
},
code:{
get() {
if(this.tabName ==='form'){
return ''
}else if(this.tabName === 'config'){
return this.formCode
}else{
return this.formVal
}
},
set(){}
}
}
}
</script>

<style scoped>
/* .box-card >>> .el-tabs__header{
margin: 0px 0px 0px 0px;
} */

.box-card{
width:60%;
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
margin:auto;
overflow: auto;
display: block;
}
#app{
position: relative;
}
</style>

效果展示:

image-20240315223133809