当前位置:   article > 正文

element框架 el-table嵌套input 实现表单(pc端)_element表格嵌入输入框

element表格嵌入输入框

运用到实际项目可能有帮助的点:

  1. el-table嵌套input的实际使用

  1. 多选和单选的答案排版显示切换

  1. v-model改变了但页面没渲染的解决方式

  1. 封装组件的思想

前几天做了一个表单组件 分享一下感受(vue2

先上图

点击新增或者编辑会进入表单组件并且触发组件内的init方法,编辑会带该题的id,新建则是空。(父组件代码就不摆上来了)

子组件代码
  1. <template>
  2. <transition name="el-zoom-in-center">
  3. <div class="JNPF-preview-main">
  4. <div class="JNPF-common-page-header">
  5. <el-page-header @back="goBack" :content="!dataForm.id ? '新建' : '编辑'" />
  6. <div class="options">
  7. <el-button type="primary" @click="dataFormSubmit()" :loading="btnLoading">确 定</el-button>
  8. <el-button @click="goBack">取 消</el-button>
  9. </div>
  10. </div>
  11. <div :style="{ margin: '0 auto', width: '100%' }">
  12. <el-row :gutter="15" class=" main">
  13. <el-form ref="elForm" :model="dataForm" size="small" label-width="100px" label-position="right"
  14. :rules="rules">
  15. <el-col :span="24">
  16. <el-form-item label="分类" prop="Category">
  17. <el-select v-model='dataForm.Category' placeholder='请选择' clearable required
  18. :style='{ "width": "100%" }'>
  19. <el-option v-for="(item, index) in CategoryOptions" :key="index" :label="item.fullName"
  20. :value="item.id"></el-option>
  21. </el-select>
  22. </el-form-item>
  23. </el-col>
  24. <el-col :span="24">
  25. <el-form-item label="题型" prop="QuestionType">
  26. <el-radio-group v-model='dataForm.QuestionType' @change="(e) => QuestionTypeIs(e)" required>
  27. <el-radio v-for="(item, index) in QuestionTypeOptions" :key="index" :label="item.id">{{
  28. item.fullName }} </el-radio>
  29. </el-radio-group>
  30. </el-form-item>
  31. </el-col>
  32. <el-col :span="24">
  33. <el-form-item label="题干" prop="QuestionStem">
  34. <el-input v-model='dataForm.QuestionStem' placeholder='请输入' clearable required
  35. :style='{ "width": "100%" }'>
  36. </el-input>
  37. </el-form-item>
  38. </el-col>
  39. <el-col :span="24">
  40. <el-form-item label-width="0">
  41. <div class="JNPF-common-title">
  42. <h2>选项内容</h2>
  43. </div>
  44. <el-table :data="dataForm.Options" size='mini'>
  45. <el-table-column type="index" width="50" label="序号" align="center" />
  46. <el-table-column prop="Options" label="选项内容">
  47. <template slot="header">
  48. <span class="required-sign">*</span>选项内容
  49. </template>
  50. <template slot-scope="scope">
  51. <el-input v-model="dataForm.Options[scope.$index]" :style='{ "width": "100%" }'
  52. placeholder='请输入' clearable required>
  53. </el-input>
  54. </template>
  55. </el-table-column>
  56. <el-table-column label="操作" width="50">
  57. <template slot-scope="scope">
  58. <el-button size="mini" type="text" class="JNPF-table-delBtn"
  59. @click="handleDelEmaQuestionOptionEntityList(scope.$index)">删除</el-button>
  60. </template>
  61. </el-table-column>
  62. </el-table>
  63. <div class="table-actions" @click="addHandleEmaQuestionOptionEntityList()">
  64. <el-button type="text" icon="el-icon-plus">新增</el-button>
  65. </div>
  66. </el-form-item>
  67. </el-col>
  68. <el-col :span="24">
  69. <el-form-item label="答案" prop="Answer" v-if="QuestionType == 1">
  70. <el-select v-model='dataForm.Answer' placeholder='请选择' clearable required
  71. :style='{ "width": "100%" }'>
  72. <el-option v-for="(item, index) in dataForm.Options" :key="index" :label="index + 1"
  73. :value="index + 1"></el-option>
  74. </el-select>
  75. </el-form-item>
  76. <el-form-item label="答案" prop="Answer" v-if="QuestionType == 2">
  77. <el-select v-model="dataForm.Answer" placeholder="请选择" :style='{ "width": "100%" }'
  78. clearable required multiple>
  79. <el-option v-for="(item, index) in dataForm.Options" :key="index" :label="index + 1"
  80. :value="index + 1">
  81. </el-option>
  82. </el-select>
  83. </el-form-item>
  84. </el-col>
  85. <el-col :span="24">
  86. <el-form-item label="分值" prop="Point">
  87. <el-input-number v-model='dataForm.Point' placeholder='数字文本' required :step='1'
  88. controls-position='right' :max='100' :min='1'>
  89. </el-input-number>
  90. </el-form-item>
  91. </el-col>
  92. <el-col :span="24">
  93. <el-form-item label="是否有效" prop="F_EnabledMark">
  94. <el-switch v-model='dataForm.F_EnabledMark' :active-value='1' :inactive-value='0'>
  95. </el-switch>
  96. </el-form-item>
  97. </el-col>
  98. <el-col :span="24" v-if='false'>
  99. <el-form-item label="创建用户" prop="F_CreatorUserId">
  100. <jnpf-open-data v-model='dataForm.F_CreatorUserId' readonly type='currUser'>
  101. </jnpf-open-data>
  102. </el-form-item>
  103. </el-col>
  104. <el-col :span="24" v-if='false'>
  105. <el-form-item label="创建时间" prop="F_CreatorTime">
  106. <jnpf-open-data v-model='dataForm.F_CreatorTime' readonly type='currTime'>
  107. </jnpf-open-data>
  108. </el-form-item>
  109. </el-col>
  110. <el-col :span="24" v-if='false'>
  111. <el-form-item label="修改用户" prop="F_LastModifyUserId">
  112. <el-input v-model='dataForm.F_LastModifyUserId' placeholder='系统自动生成' readonly>
  113. </el-input>
  114. </el-form-item>
  115. </el-col>
  116. <el-col :span="24" v-if='false'>
  117. <el-form-item label="修改时间" prop="F_LastModifyTime">
  118. <el-input :value='dataForm.f_LastModifyTime | toDate' placeholder='系统自动生成' readonly />
  119. </el-form-item>
  120. </el-col>
  121. </el-form>
  122. </el-row>
  123. </div>
  124. </div>
  125. </transition>
  126. </template>
  127. <script>
  128. import request from '@/utils/request'
  129. import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
  130. export default {
  131. components: {},
  132. props: [],
  133. data() {
  134. return {
  135. btnLoading: false,
  136. loading: false,
  137. visible: false,
  138. dataForm: {
  139. id: '',
  140. Category: '',
  141. QuestionType: "1",
  142. QuestionStem: '',
  143. Answer: [],
  144. Point: 5,
  145. F_EnabledMark: 0,
  146. F_CreatorUserId: '',
  147. F_CreatorTime: '',
  148. F_LastModifyUserId: '',
  149. F_LastModifyTime: '',
  150. },
  151. QuestionType: 1,
  152. rules: {
  153. Category: [
  154. {
  155. required: true,
  156. message: '请输入分类',
  157. trigger: 'change'
  158. },
  159. ],
  160. QuestionType: [
  161. {
  162. required: true,
  163. message: '请输入题型',
  164. trigger: 'change'
  165. },
  166. ],
  167. QuestionStem: [
  168. {
  169. required: true,
  170. message: '请输入题干',
  171. trigger: 'blur'
  172. },
  173. ],
  174. Answer: [
  175. {
  176. required: true,
  177. message: '请输入答案',
  178. trigger: 'change'
  179. },
  180. ],
  181. Point: [
  182. {
  183. required: true,
  184. message: '请输入分值',
  185. trigger: [
  186. "blur",
  187. "change"
  188. ]
  189. },
  190. ],
  191. },
  192. CategoryOptions: [],
  193. }
  194. },
  195. computed: {},
  196. watch: {},
  197. created() {
  198. this.getcategoryOptions();
  199. },
  200. mounted() {
  201. },
  202. computed: {
  203. },
  204. watch: {
  205. },
  206. methods: {
  207. // 非空校验
  208. emaQuestionOptionExist() {
  209. let isOk = true;
  210. for (let i = 0; i < this.dataForm.Options.length; i++) {
  211. const e = this.dataForm.Options[i];
  212. if (!e) {
  213. this.$message({
  214. message: '选项内容不能为空',
  215. type: 'error',
  216. duration: 1000
  217. });
  218. isOk = false
  219. break
  220. }
  221. if (this.QuestionType == 2) {
  222. if (this.dataForm.Answer.length == 1) {
  223. this.$message({
  224. message: '多选题答案应为两个及以上',
  225. type: 'error',
  226. duration: 1000
  227. });
  228. isOk = false
  229. break
  230. }
  231. }
  232. }
  233. return isOk;
  234. },
  235. // 获取试题分类数据(消防安全等等..)
  236. getcategoryOptions() {
  237. getDictionaryDataSelector('397272689904988741').then(res => {
  238. this.CategoryOptions = res.data.list
  239. });
  240. },
  241. // 关闭
  242. goBack() {
  243. this.$emit('refresh')
  244. },
  245. // 点开
  246. init(id) {
  247. this.dataForm.id = id || '';
  248. this.visible = true;
  249. this.$nextTick(() => {
  250. this.$refs['elForm'].resetFields();
  251. this.dataForm.Options = [];
  252. // 编辑操作
  253. if (this.dataForm.id) {
  254. request({
  255. url: `api/visualdev/OnlineDev/380291022044793029/${this.dataForm.id}`,
  256. method: 'get'
  257. }).then(res => {
  258. this.dataForm = res.data.data
  259. this.dataForm.id = id || '';
  260. this.dataForm.Answer = JSON.parse(this.dataForm.Answer);
  261. this.QuestionType = this.dataForm.QuestionType || 1
  262. })
  263. // 新建操作
  264. }else{
  265. this.QuestionType = 1
  266. }
  267. });
  268. this.$store.commit('generator/UPDATE_RELATION_DATA', {})
  269. },
  270. // 多选单选切换
  271. QuestionTypeIs(e) {
  272. this.QuestionType = e
  273. if (e == 1) this.dataForm.Answer = ''
  274. if (e == 2) this.dataForm.Answer = []
  275. },
  276. // 提交确定
  277. dataFormSubmit() {
  278. this.$refs['elForm'].validate((valid) => {
  279. if (valid) {
  280. if (!this.emaQuestionOptionExist()) return;
  281. this.btnLoading = true;
  282. this.dataForm.F_EnabledMark = parseInt(this.dataForm.F_EnabledMark)
  283. this.dataForm.flowId = ''
  284. // 新建提交确定
  285. if (!this.dataForm.id) {
  286. request({
  287. url: `/api/visualdev/OnlineDev/380291022044793029/`,
  288. method: 'post',
  289. data: {
  290. id: this.dataForm.id,
  291. data: this.dataForm
  292. }
  293. }).then((res) => {
  294. this.$message({
  295. message: res.msg,
  296. type: 'success',
  297. duration: 1000,
  298. onClose: () => {
  299. this.btnLoading = false;
  300. this.visible = false,
  301. this.$emit('refresh', true)
  302. }
  303. })
  304. }).catch(() => {
  305. this.btnLoading = false;
  306. })
  307. } else {
  308. // 编辑提交确定
  309. request({
  310. url: `/api/visualdev/OnlineDev/380291022044793029/${this.dataForm.id}`,
  311. method: 'PUT',
  312. data: {
  313. id: this.dataForm.id,
  314. data: this.dataForm
  315. }
  316. }).then((res) => {
  317. this.$message({
  318. message: res.msg,
  319. type: 'success',
  320. duration: 1000,
  321. onClose: () => {
  322. this.btnLoading = false;
  323. this.visible = false
  324. this.$emit('refresh', true)
  325. }
  326. })
  327. }).catch(() => {
  328. this.btnLoading = false;
  329. })
  330. }
  331. }
  332. })
  333. },
  334. // 选项新增
  335. addHandleEmaQuestionOptionEntityList() {
  336. let item = ''
  337. this.dataForm.Options.push(item)
  338. if (!this.dataForm.id) this.$forceUpdate()
  339. },
  340. // 选项删除
  341. handleDelEmaQuestionOptionEntityList(index) {
  342. this.dataForm.Options.splice(index, 1);
  343. if (!this.dataForm.id) this.$forceUpdate()
  344. },
  345. }
  346. }
  347. </script>
编辑实际图
新增实际图

代码不复杂 且都做了注释

主要是分享下el-table嵌套input项目中的实际运用(插槽的使用),还有怎么实现一个简洁可编辑响应式表单(新增 编辑 删除)的业务需求

其中需要注意的目前回忆起来有几点:
  1. el-select多选框的multiple属性(可多选)需要是一个数组,所以每次都需要切换

  1. 如果反复切换,数组和字符串的方法转化会多很多不要的标点符号,所以每次切换得清空值

  1. scope里的$index可以拿到循环里的下标

  1. 新建的时候选项的值更新了 但是没有进到dataForm.Options里面去 所以我用了this.$forceUpdate()。

第四点奇怪的是编辑时候是正常的 能同步到select去,但是新建就不行得用强制刷新,这个问题我还在疑惑,希望有大佬解惑。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/584033
推荐阅读
相关标签
  

闽ICP备14008679号