DivEditable.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <template>
  2. <div>
  3. <span class="address-placeholder" v-show="onshow" @click="getfouce">请输入</span>
  4. <div
  5. class="test_box"
  6. contenteditable="true"
  7. v-html="innerText"
  8. :ref="Maincontent"
  9. @input="handleInput"
  10. @blur="unblur"
  11. @focus="changeColor"
  12. @compositionstart="handleStart"
  13. @compositionend="handleEnd"
  14. ></div>
  15. </div>
  16. </template>
  17. <script>
  18. // import { Fragment } from 'vue-fragment'
  19. export default {
  20. name: 'DivEditable',
  21. props: ['value', 'Maincontent'],
  22. data() {
  23. return {
  24. innerText: this.value,
  25. isChange: true,
  26. composing: false,
  27. onshow: true
  28. };
  29. },
  30. // components: { Fragment },
  31. watch: {
  32. value() {
  33. if (this.isChange) {
  34. this.innerText = this.value;
  35. }
  36. }
  37. },
  38. mounted() {
  39. let len = this.value.length;
  40. this.onshow = len > 0 ? false : true;
  41. },
  42. methods: {
  43. changeColor(){
  44. this.isChange = false
  45. this.$refs[this.Maincontent].style.border = '1px solid #48C5D7'
  46. },
  47. unblur() {
  48. this.$refs[this.Maincontent].style.border = '1px solid #dcdfe6'
  49. },
  50. getfouce() {
  51. this.$refs[this.Maincontent].focus()
  52. },
  53. handleInput(event) {
  54. let text = event.target.innerText;
  55. let len = text.length;
  56. this.onshow = len > 0 ? false : true;
  57. this.valueHandle(event, text);
  58. this.$emit('input', text);
  59. },
  60. valueHandle(event, strVale) {
  61. let _this = this;
  62. let text = strVale;
  63. if (this.composing) {
  64. return;
  65. }
  66. let len = text.length;
  67. this.onshow = len > 0 ? false : true;
  68. if (len > 200) {
  69. this.$refs[this.Maincontent].innerHTML = text.substr(0, 200);
  70. this.$refs[this.Maincontent].focus();
  71. }
  72. setTimeout(() => {
  73. _this.keepLastIndex(event.target);
  74. }, 5);
  75. // 拓展 如果想要只需要前100位数据
  76. // this.content = this.content.substring(0, 100)
  77. },
  78. handleStart() {
  79. this.composing = true;
  80. },
  81. /**
  82. * 中文输入结束
  83. */
  84. handleEnd($event) {
  85. this.composing = false;
  86. let text = $event.target.innerHTML;
  87. // console.log($event.target.innerHTML)
  88. this.valueHandle($event, text);
  89. },
  90. keepLastIndex(obj) {
  91. if (window.getSelection) {
  92. // ie11 10 9 ff safari
  93. obj.focus(); // 解决ff不获取焦点无法定位问题
  94. let range = window.getSelection(); // 创建range
  95. range.selectAllChildren(obj); // range 选择obj下所有子内容
  96. range.collapseToEnd(); // 光标移至最后
  97. } else if (document.selection) {
  98. // ie10 9 8 7 6 5
  99. let range = document.selection.createRange(); // 创建选择对象
  100. // var range = document.body.createTextRange();
  101. range.moveToElementText(obj); // range定位到obj
  102. range.collapse(false); // 光标移至最后
  103. range.select();
  104. }
  105. }
  106. }
  107. };
  108. </script>
  109. <style lang="less" scoped>
  110. .address-placeholder {
  111. line-height: 42px;
  112. height: 42px;
  113. color: #a2a2a2;
  114. position: absolute;
  115. left: 16px;
  116. top: 6px;
  117. opacity: 0.7;
  118. font-size: 14px;
  119. }
  120. .test_box {
  121. min-height: 20px;
  122. max-height: 300px;
  123. outline: 0;
  124. border: 1px solid #dcdfe6;
  125. font-size: 14px;
  126. line-height: 1.5;
  127. word-wrap: break-word;
  128. overflow-x: hidden;
  129. overflow-y: auto;
  130. border-radius: 4px;
  131. margin-top: 6px;
  132. padding: 10px 15px;
  133. }
  134. </style>