EditableItem.vue 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. <template>
  2. <component
  3. ref="element"
  4. :is="item.type"
  5. :id="item.id"
  6. @input="handleInput"
  7. @keydown.stop="handleKeyDown"
  8. contenteditable
  9. v-html="item.content"
  10. >
  11. </component>
  12. </template>
  13. <script>
  14. import blockTypeRegs from '../../utils/block-type-regs'
  15. import { MODIFY_ITEM, ADD_ITEM_AFTER } from '../../store/types/editor-types'
  16. export default {
  17. name: 'editable-item',
  18. props: ['item', 'pageId'],
  19. data: function() {
  20. return {}
  21. },
  22. mounted() {},
  23. updated() {},
  24. methods: {
  25. handleKeyDown(e) {
  26. switch (e.key) {
  27. case 'Enter':
  28. e.preventDefault()
  29. this.$store.commit(ADD_ITEM_AFTER, {
  30. pageId: this.pageId,
  31. itemId: this.item.id
  32. })
  33. break
  34. default:
  35. break
  36. }
  37. },
  38. handleInput(e) {
  39. const diff = { content: e.target.textContent }
  40. this.item.type === 'div' &&
  41. Object.entries(blockTypeRegs)
  42. .map(array => ({ tagName: array[0], reg: array[1] }))
  43. .some(({ tagName, reg }) => {
  44. if (reg.test(e.target.textContent)) {
  45. diff.type = tagName
  46. }
  47. })
  48. this.$store.commit(MODIFY_ITEM, {
  49. pageId: this.pageId,
  50. itemId: this.item.id,
  51. diff
  52. })
  53. }
  54. }
  55. }
  56. </script>
  57. <style lang="scss" scoped>
  58. * [contenteditable] {
  59. outline: none;
  60. padding: 10px;
  61. &:hover {
  62. background: #fafcfe;
  63. }
  64. &:focus {
  65. background: #f9fafc;
  66. }
  67. }
  68. </style>