原贴:

vue2 实现 div contenteditable=“true” 类似于 v-model 的效果

但是有个问题,就是输入第一行的时候,光标会跳转到最前面

if (!this.isLocked || !this.innerText)

问题出在这里,如果去掉 !this.innerText这个条件或者改成&&就不会出这个问题。但是,又会触发新的问题,就是在父组件里面清空内容的时候,页面不更新。

思路:
设置在点击以后,将光标移动到最后。解决上面两个问题。
参考:

Vue中div contenteditable 的光标定位

具体代码:

<template>
  <div class="text"
       v-html="innerText"
       :contenteditable="canEdit"
       @focus="isLocked = true"
       @blur="isLocked = false"
       @input="changeText">
  </div>
</template>
<script>
  export default {
    name: 'editDiv',
    props: {
      value: {
        type: String,
        default: ''
      },
      canEdit: {
        type: Boolean,
        default: true
      }
    },
    data () {
      return {
        innerText: this.value,
        isLocked: false,
        isFistTime: true
      }
    },
    watch: {
      value () {
        console.log(this.value)
        console.log(this.isLocked)
        if (!this.isLocked || !this.innerText) {
          if (!this.innerText) {
            this.$nextTick(() => {
              this.keepLastIndex(this.$el)
            })
          }
          this.innerText = this.value
        }
        this.isFistTime = false
      },
      isLocked () {
        this.innerText = this.value
      }
    },
    methods: {
      changeText () {
        this.$emit('input', this.$el.innerHTML)
      },
      keepLastIndex (obj) {
        console.log(obj)
        console.log(window.getSelection)
        console.log(document.selection)
        if (window.getSelection) { // ie11 10 9 ff safari
          obj.focus() // 解决ff不获取焦点无法定位问题
          let range = window.getSelection() // 创建range
          range.selectAllChildren(obj) // range 选择obj下所有子内容
          range.collapseToEnd() // 光标移至最后
        } else if (document.selection) { // ie10 9 8 7 6 5
          let range = document.selection.createRange() // 创建选择对象
          // var range = document.body.createTextRange();
          range.moveToElementText(obj) // range定位到obj
          range.collapse(false) // 光标移至最后
          range.select()
        }
      }
    }
  }
</script>
Logo

前往低代码交流专区

更多推荐