BaseSingle.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <template>
  2. <div class="question-single">
  3. <div class="exersices-content">
  4. <IconText :text="'题目'" :color="'#2d8cf0'" :icon="'ios-create'" style="margin-bottom:15px;"></IconText>
  5. <div ref="singleEditor" style="text-align:left"></div>
  6. </div>
  7. <div class="question-option" style="margin-top:20px">
  8. <IconText :text="'单选选项'" :color="'#FF871C'" :icon="'md-reorder'"></IconText>
  9. <div v-if="options.length">
  10. <div v-for="(item,index) in options" :key="index" :ref="'optionBox' + index" class="option-editor-wrap" style="margin-top:10px;display:flex">
  11. <span class="fl-center option-order">{{String.fromCharCode(64 + parseInt(index+1))}}</span>
  12. <div :ref="'singleOption'+index" :data-index="index" style="text-align:left" class="qn-option-editor" @click="optionClick(item)"></div>
  13. <span class="fl-center option-delete" @click="deleteOption(index)">
  14. <Icon type="md-close" /></span>
  15. </div>
  16. </div>
  17. <p class="option-add"><span @click="addOption()"> + 添加选项 </span></p>
  18. </div>
  19. </div>
  20. </template>
  21. <script>
  22. import E from 'wangeditor'
  23. import IconText from '@/components/evaluation/IconText.vue'
  24. export default {
  25. components: {
  26. IconText
  27. },
  28. props: ['editInfo'],
  29. data() {
  30. return {
  31. options: [...new Array(4).keys()], // 默认四个选项
  32. existOptions: [...new Array(4).keys()],
  33. initFlag: true,
  34. trueIndex: 0,
  35. editSingleInfo: {},
  36. stemEditor: null,
  37. stemContent: '',
  38. optionsContent: [],
  39. optionEditors: [],
  40. }
  41. },
  42. created() {},
  43. methods: {
  44. resetContent() {
  45. console.log('重置')
  46. this.options = [...new Array(4).keys()],
  47. this.optionsContent = []
  48. this.optionEditors.forEach(i => {
  49. i.txt.clear()
  50. })
  51. this.stemEditor.txt.clear()
  52. },
  53. initEditors() {
  54. // Editor默认配置
  55. if (this.options.length > 0) {
  56. this.options.forEach((item, i) => {
  57. let that = this
  58. let editor = new E(that.$refs['singleOption' + i][0])
  59. this.$editorTools.initSimpleEditor(editor)
  60. // 选项编辑器失焦隐藏工具栏
  61. editor.config.onblur = function() {
  62. let allToolbars = document.getElementsByClassName('qn-option-editor')
  63. for (let i = 0; i < allToolbars.length; i++) {
  64. if (allToolbars[i].children.length) {
  65. allToolbars[i].children[0].style.visibility = 'hidden'
  66. }
  67. }
  68. }
  69. // 选项编辑器内容发生变化时
  70. editor.config.onchange = (html) => {
  71. let key = String.fromCharCode(64 + parseInt(i + 1))
  72. let codeArr = this.optionsContent.map(item => item.code)
  73. // 如果已经编辑过则 修改选项内容
  74. if (codeArr.indexOf(key) !== -1) {
  75. this.optionsContent[codeArr.indexOf(key)].value = html
  76. } else { // 否则创建新选项
  77. let option = {
  78. code: key,
  79. value: html
  80. }
  81. this.optionsContent.push(option)
  82. }
  83. }
  84. editor.create()
  85. this.optionEditors.push(editor)
  86. that.$refs["singleOption" + i][0].dataset.editorId = editor.id
  87. // 如果是编辑状态 则将选项内容回显
  88. if (Object.keys(this.editSingleInfo).length > 0) {
  89. editor.txt.html(this.editSingleInfo.option[i].value)
  90. }
  91. })
  92. }
  93. },
  94. onRichTextClick(e) {
  95. this.$parent.onRichTextClick(e)
  96. },
  97. // 添加选项
  98. addOption() {
  99. let that = this
  100. let wraps = Array.from(document.getElementsByClassName('qn-option-editor'))
  101. let optionsLength = wraps.length;
  102. let newIndex = parseInt(this.options[this.options.length - 1]) + 1
  103. if (optionsLength < 9) {
  104. this.options.push(newIndex)
  105. this.optionsContent.push({
  106. code: String.fromCharCode(64 + parseInt(newIndex + 1)),
  107. value: ''
  108. })
  109. this.$nextTick(() => {
  110. let editor = new E(that.$refs['singleOption' + newIndex][0])
  111. this.$editorTools.initSimpleEditor(editor)
  112. editor.config.onchange = (html) => {
  113. let key = String.fromCharCode(64 + parseInt(newIndex + 1))
  114. let codeArr = this.optionsContent.map(item => item.code)
  115. // 如果已经编辑过则 修改选项内容
  116. if (codeArr.indexOf(key) !== -1) {
  117. this.optionsContent[codeArr.indexOf(key)].value = html
  118. } else { // 否则创建新选项
  119. let option = {
  120. code: key,
  121. value: html
  122. }
  123. this.optionsContent.push(option)
  124. }
  125. }
  126. editor.create()
  127. this.optionEditors.push(editor);
  128. this.$refs["singleOption" + newIndex][0].dataset.editorId = editor.id
  129. this.refreshOrder()
  130. })
  131. } else {
  132. this.$Message.warning('最多只有9个选项!')
  133. }
  134. },
  135. /* 根据页面上的选项DOM数量,刷新每个选项的Order显示 */
  136. refreshOrder() {
  137. let wraps = Array.from(document.getElementsByClassName('option-order'))
  138. wraps.forEach((item, index) => {
  139. item.innerHTML = this.renderIndex(index)
  140. })
  141. },
  142. /* 根据下标渲染对应的字母顺序 */
  143. renderIndex(index) {
  144. return String.fromCharCode(64 + parseInt(index + 1))
  145. },
  146. // 删除选项
  147. deleteOption(index) {
  148. let wraps = Array.from(document.getElementsByClassName('qn-option-editor'))
  149. if (wraps.length > 2) {
  150. this.optionsContent.splice(index, 1)
  151. let textWrap = this.$refs['optionBox' + index][0]
  152. textWrap.remove()
  153. this.refreshOrder()
  154. } else {
  155. this.$Message.warning('至少保留两个选项!')
  156. }
  157. },
  158. // 保存试题 获取最新选项数据
  159. doSave(){
  160. // 拿到当前还剩的选项DOM
  161. let wraps = Array.from(document.getElementsByClassName('qn-option-editor'))
  162. let arr = []
  163. console.log(wraps)
  164. wraps.forEach((item,index) => {
  165. // 遍历选项 找到对应的 Editor 然后获取编辑器里面的内容
  166. let id = item.dataset.editorId
  167. let curEditor = this.optionEditors.filter(i => i.id === id)[0]
  168. // 生成新的选项对象
  169. let obj = {
  170. code:String.fromCharCode(64 + parseInt(index + 1)),
  171. value:curEditor.txt.html()
  172. }
  173. arr.push(obj)
  174. })
  175. this.$emit('onSave',{
  176. stemContent:this.stemContent,
  177. optionsContent:arr
  178. })
  179. },
  180. // 模拟选项聚焦事件
  181. optionClick(index) {
  182. let allToolbars = document.getElementsByClassName('option-editor')
  183. let that = this
  184. for (let i = 0; i < allToolbars.length; i++) {
  185. allToolbars[i].children[0].style.visibility = 'hidden'
  186. }
  187. setTimeout(function() {
  188. let currentToolBar = that.$refs['singleOption' + index][0].children[0]
  189. if(currentToolBar.clientHeight > 50){
  190. currentToolBar.style.top = '-90px'
  191. }
  192. currentToolBar.style.visibility = 'visible'
  193. }, 100)
  194. },
  195. },
  196. mounted() {
  197. let stemEditor = new E(this.$refs.singleEditor)
  198. stemEditor.config.onchange = (html) => {
  199. this.stemContent = html
  200. }
  201. this.$editorTools.addVideoUpload(this, stemEditor)
  202. this.$editorTools.addAudio(this, stemEditor)
  203. this.$editorTools.initMyEditor(stemEditor)
  204. this.$editorTools.initSimpleEditor(stemEditor)
  205. stemEditor.create()
  206. this.stemEditor = stemEditor
  207. this.initEditors()
  208. if (this.editInfo && this.editInfo.question) {
  209. console.log('进入单选题Mounted编辑')
  210. this.editSingleInfo = JSON.parse(JSON.stringify(this.editInfo))
  211. this.stemContent = this.editSingleInfo.question
  212. this.optionsContent = this.editSingleInfo.option
  213. this.options = this.editSingleInfo.option.map((item, index) => index)
  214. this.$nextTick(() => {
  215. this.initEditors()
  216. this.stemEditor.txt.html(this.editSingleInfo.question)
  217. })
  218. }
  219. },
  220. watch: {
  221. editInfo: {
  222. handler(newValue, oldValue) {
  223. if (newValue) {
  224. console.log('单选接收到的数据')
  225. console.log(newValue)
  226. this.editSingleInfo = JSON.parse(JSON.stringify(newValue))
  227. if (Object.keys(newValue).length > 0) {
  228. this.stemContent = this.editSingleInfo.question
  229. this.optionsContent = this.editSingleInfo.option
  230. this.options = this.editSingleInfo.option.map((item, index) => index)
  231. this.$nextTick(() => {
  232. this.initEditors()
  233. this.stemEditor.txt.html(this.editSingleInfo.question)
  234. })
  235. }
  236. }
  237. },
  238. // immediate:true
  239. },
  240. }
  241. }
  242. </script>
  243. <style lang="less">
  244. @import(reference) "./BaseSingle.less";
  245. </style>