index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <!-- 可配置表格 -->
  2. <template>
  3. <div class="config-table">
  4. <div class="config-table-options">
  5. <div>
  6. 表格阴影:
  7. <el-radio v-model="curQue.isShadow" :label="true">有</el-radio>
  8. <el-radio v-model="curQue.isShadow" :label="false">无</el-radio>
  9. </div>
  10. <div>
  11. 表格标题:
  12. <el-radio v-model="curQue.isTitle" :label="true">有</el-radio>
  13. <el-radio v-model="curQue.isTitle" :label="false">无</el-radio>
  14. <el-input v-show="curQue.isTitle" v-model="curQue.title" type="text" />
  15. </div>
  16. <div>
  17. 表头行背景色:
  18. <el-color-picker
  19. v-model="curQue.headerBgColor"
  20. size="mini"
  21. :predefine="predefineColors"
  22. />
  23. </div>
  24. <div>
  25. 内容对齐方式:
  26. <el-radio v-model="curQue.textAlign" label="left">左对齐</el-radio>
  27. <el-radio v-model="curQue.textAlign" label="center">居中</el-radio>
  28. <el-radio v-model="curQue.textAlign" label="right">右对齐</el-radio>
  29. </div>
  30. <div>
  31. 拼音位置:
  32. <el-radio v-model="curQue.pinyinPosition" label="top">上</el-radio>
  33. <el-radio v-model="curQue.pinyinPosition" label="bottom">下</el-radio>
  34. <el-radio v-model="curQue.pinyinPosition" label="left">左</el-radio>
  35. <el-radio v-model="curQue.pinyinPosition" label="right">右</el-radio>
  36. </div>
  37. <div>
  38. 外层边框突出显示:
  39. <el-radio v-model="curQue.marginHighlight" :label="true">是</el-radio>
  40. <el-radio v-model="curQue.marginHighlight" :label="false">否</el-radio>
  41. </div>
  42. <div>
  43. <el-button @click="addTableHeader">增加一行表头</el-button>
  44. <el-button @click="addCol">增加一列</el-button>
  45. <el-button @click="addRow">增加一行</el-button>
  46. </div>
  47. </div>
  48. <div class="config-table-preview">
  49. <table class="preview-table">
  50. <caption v-if="curQue.isTitle">
  51. {{
  52. curQue.title
  53. }}
  54. </caption>
  55. <thead>
  56. <tr>
  57. <td />
  58. <td
  59. v-for="(item, k) in curQue.tableData.colsConfig.width"
  60. :key="`tfoot-${k}`"
  61. >
  62. 第{{ k + 1 }}列
  63. </td>
  64. <td />
  65. </tr>
  66. <tr v-for="(item, i) in curQue.tableData.headers" :key="i">
  67. <th />
  68. <th v-for="(header, j) in item.content" :key="j">
  69. <el-form :inline="true" :model="header">
  70. <el-form-item label="内容">
  71. <el-input v-model="header.text" class="text" />
  72. </el-form-item>
  73. <el-form-item label="合并行">
  74. <el-input
  75. v-model="header.rowspan"
  76. class="rowspan"
  77. type="number"
  78. />
  79. </el-form-item>
  80. <el-form-item label="合并列">
  81. <el-input
  82. v-model="header.colspan"
  83. class="colspan"
  84. type="number"
  85. />
  86. </el-form-item>
  87. </el-form>
  88. </th>
  89. <th>
  90. <el-button size="mini" @click="deleteThead(i)">
  91. 删除表头
  92. </el-button>
  93. </th>
  94. </tr>
  95. </thead>
  96. <tbody>
  97. <tr v-for="(row, i) in curQue.tableData.body" :key="`row-${i}`">
  98. <td width="60">第{{ i + 1 }}行</td>
  99. <td v-for="(col, j) in row.content" :key="`col-${j}`">
  100. <p>
  101. {{
  102. col.prefix + " " + col.text + " " + col.sentence_data.sentence
  103. }}
  104. </p>
  105. <template v-if="col.mulText">
  106. <ul
  107. v-for="(dItem, dIndex) in col.mulText.detail"
  108. :key="'ddItem' + dIndex"
  109. class="option-detail-detail"
  110. >
  111. <li
  112. v-for="(ddItem, ddIndex) in dItem.detail"
  113. :key="'ddItem' + dIndex + ddIndex"
  114. >
  115. <span
  116. :class="[
  117. ddItem.config.wordPadding.indexOf('left') > -1
  118. ? 'dleft'
  119. : '',
  120. ddItem.config.wordPadding.indexOf('right') > -1
  121. ? 'dright'
  122. : '',
  123. !ddItem.sentence ? 'placeholder' : '',
  124. ]"
  125. >
  126. {{ ddItem.sentence }}
  127. </span>
  128. </li>
  129. </ul>
  130. </template>
  131. <el-button size="mini" @click="edit(i, j)">编辑</el-button>
  132. </td>
  133. <td>
  134. <el-button size="mini" @click="deleteRow(i)">删除行</el-button>
  135. </td>
  136. </tr>
  137. <tr>
  138. <td />
  139. <td
  140. v-for="(item, k) in curQue.tableData.colsConfig.width"
  141. :key="`tfoot-${k}`"
  142. >
  143. <el-input
  144. v-model.number="item.val"
  145. size="mini"
  146. class="input-width"
  147. >
  148. <template slot="prepend">宽度</template>
  149. </el-input>
  150. <el-button size="mini" @click="deleteCol(k)">删除列</el-button>
  151. </td>
  152. <td />
  153. </tr>
  154. </tbody>
  155. </table>
  156. </div>
  157. <cell-edit
  158. :visible="visible"
  159. :body="curQue.tableData.body"
  160. :cur-index="curIndex"
  161. @close="close"
  162. />
  163. </div>
  164. </template>
  165. <script>
  166. import CellEdit from "./components/CellEdit.vue";
  167. export default {
  168. components: { CellEdit },
  169. props: {
  170. curQue: {
  171. type: Object,
  172. default: () => {
  173. return {
  174. isFirst: true,
  175. type: "config_table",
  176. name: "可配置表格",
  177. isShadow: false,
  178. isTitle: false,
  179. marginHighlight: false,
  180. pinyinPosition: "top",
  181. title: "",
  182. textAlign: "center",
  183. headerBgColor: "#fff",
  184. tableData: {
  185. headers: [],
  186. body: [
  187. {
  188. content: [
  189. {
  190. type: "content",
  191. text: "",
  192. prefix: "",
  193. isUnderline: false,
  194. background: "#fff",
  195. isCross: false,
  196. answer: "",
  197. CrossAnswer: "normal",
  198. rowspan: 1,
  199. colspan: 1,
  200. sentence_data: {
  201. type: "sentence_segword_chs",
  202. name: "句子分词",
  203. pyPosition: "top", // top 拼音在上面;bottom 拼音在下面
  204. sentence: "", // 句子
  205. segList: [], // 分词结果
  206. seg_words: "",
  207. wordsList: [],
  208. },
  209. mulText: {
  210. correct: {
  211. completeInput: "",
  212. },
  213. detail: [],
  214. input_Isexample: false,
  215. },
  216. },
  217. ],
  218. },
  219. ],
  220. colsConfig: {
  221. width: [{ val: 100 }],
  222. },
  223. },
  224. };
  225. },
  226. },
  227. changeCurQue: {
  228. type: Function,
  229. required: true,
  230. },
  231. },
  232. data() {
  233. return {
  234. visible: false,
  235. curIndex: {
  236. col: 0,
  237. row: 0,
  238. },
  239. predefineColors: ["#f6d5a4", "#efeff9", "#e2e1c8"],
  240. };
  241. },
  242. computed: {
  243. rows() {
  244. return this.curQue.tableData.body.length;
  245. },
  246. cols() {
  247. if (this.rows.length <= 0) return 0;
  248. return this.curQue.tableData.body[0].content.length;
  249. },
  250. },
  251. created() {
  252. if (this.curQue.isFirst) {
  253. this.curQue.isFirst = false;
  254. this.changeCurQue(this.curQue);
  255. }
  256. },
  257. methods: {
  258. edit(i, j) {
  259. this.curIndex = {
  260. col: j,
  261. row: i,
  262. };
  263. this.visible = true;
  264. },
  265. close() {
  266. this.visible = false;
  267. },
  268. addTableHeader() {
  269. if (this.cols <= 0 && this.rows <= 0) {
  270. return this.$message.warning("请先添加行或列");
  271. }
  272. let content = [];
  273. for (let i = 0; i < this.cols; i++) {
  274. content.push({
  275. text: "",
  276. rowspan: 1,
  277. colspan: 1,
  278. });
  279. }
  280. this.curQue.tableData.headers.push({
  281. isMerge: false,
  282. content,
  283. });
  284. },
  285. deleteThead(i) {
  286. this.curQue.tableData.headers.splice(i, 1);
  287. },
  288. addCol() {
  289. this.curQue.tableData.body.forEach(({ content }) => {
  290. content.push({
  291. type: "content",
  292. text: "",
  293. prefix: "",
  294. isUnderline: false,
  295. background: "#fff",
  296. isCross: false,
  297. rowspan: 1,
  298. colspan: 1,
  299. sentence_data: {
  300. type: "sentence_segword_chs",
  301. name: "句子分词",
  302. pyPosition: "top", // top 拼音在上面;bottom 拼音在下面
  303. sentence: "", // 句子
  304. segList: [], // 分词结果
  305. seg_words: "",
  306. wordsList: [],
  307. },
  308. mulText: {
  309. correct: {
  310. completeInput: "",
  311. },
  312. detail: [],
  313. },
  314. });
  315. });
  316. this.curQue.tableData.headers.forEach(({ content }) => {
  317. content.push({
  318. text: "",
  319. rowspan: 1,
  320. colspan: 1,
  321. });
  322. });
  323. this.curQue.tableData.colsConfig.width.push({ val: 100 });
  324. },
  325. deleteCol(k) {
  326. this.$confirm("确定要删除吗?", "提示", {
  327. confirmButtonText: "确定",
  328. cancelButtonText: "取消",
  329. type: "warning",
  330. }).then(() => {
  331. if (this.cols <= 1) return this.$message.warning("必须留一列");
  332. this.curQue.tableData.body.forEach(({ content }) => {
  333. content.splice(k, 1);
  334. });
  335. this.curQue.tableData.headers.forEach(({ content }) => {
  336. content.splice(k, 1);
  337. });
  338. this.curQue.tableData.colsConfig.width.splice(k, 1);
  339. });
  340. },
  341. addRow() {
  342. let content = [];
  343. for (let i = 0; i < this.cols; i++) {
  344. content.push({
  345. type: "content",
  346. text: "",
  347. prefix: "",
  348. isUnderline: false,
  349. background: "#fff",
  350. isCross: false,
  351. rowspan: 1,
  352. colspan: 1,
  353. sentence_data: {
  354. type: "sentence_segword_chs",
  355. name: "句子分词",
  356. pyPosition: "top", // top 拼音在上面;bottom 拼音在下面
  357. sentence: "", // 句子
  358. segList: [], // 分词结果
  359. seg_words: "",
  360. wordsList: [],
  361. },
  362. mulText: {
  363. correct: {
  364. completeInput: "",
  365. },
  366. detail: [],
  367. },
  368. });
  369. }
  370. this.curQue.tableData.body.push({
  371. content,
  372. });
  373. },
  374. deleteRow(i) {
  375. this.$confirm("确定要删除吗?", "提示", {
  376. confirmButtonText: "确定",
  377. cancelButtonText: "取消",
  378. type: "warning",
  379. }).then(() => {
  380. if (this.rows <= 1) return this.$message.warning("必须留一行");
  381. this.curQue.tableData.body.splice(i, 1);
  382. });
  383. },
  384. },
  385. };
  386. </script>
  387. <style lang="scss" scoped>
  388. .config-table {
  389. border: 1px solid #ccc;
  390. border-radius: 4px;
  391. padding: 8px 12px;
  392. &-options {
  393. > div {
  394. margin-bottom: 12px;
  395. }
  396. }
  397. &-preview {
  398. border-top: 1px solid #ccc;
  399. padding-top: 12px;
  400. overflow: auto;
  401. .preview-table {
  402. border-collapse: collapse;
  403. td,
  404. th {
  405. padding: 8px;
  406. }
  407. td {
  408. border: 1px solid #aaa;
  409. .input-width {
  410. min-width: 118px;
  411. }
  412. }
  413. th {
  414. border: 1px solid #aaa;
  415. .rowspan,
  416. .colspan {
  417. width: 70px;
  418. }
  419. }
  420. }
  421. }
  422. .option-detail-detail {
  423. clear: both;
  424. overflow: hidden;
  425. margin-bottom: 10px;
  426. > li {
  427. float: left;
  428. > span {
  429. float: left;
  430. &.dleft {
  431. padding-left: 4px;
  432. }
  433. &.dright {
  434. padding-right: 4px;
  435. }
  436. }
  437. }
  438. > i {
  439. float: left;
  440. }
  441. }
  442. }
  443. </style>