v-model 實現原理, 自定義v-model 以及應用 對可編輯div實現雙向數據綁定,解決光標在前和不能輸入中文的問題

對於表單大家都很熟悉,v-model 大家也很喜歡,他確實很方便。那麼他是怎麼實現的呢, 其實他是一個語法糖, v-model 幹了 兩件事 下面以 input 爲例

<input type="text" v-bind:value='message' @input='message = $event.target.value'>

等價於

<input type="text" v-model='message'>

對於自定義組件,我們也要實現雙向綁定,對於可編輯div大家都瞭解,接下來我們來實現可編輯div的雙向綁定

子組件:ContentEditable

<template>
  <div
    class="edit-div"
    v-html="innerText"
    :contenteditable="canEdit"
    @focus="isLocked = true"
    @blur="isLocked = false"
    @input="changeText"
    placeholder="請輸入審批意見(必填)"
  ></div>
</template>
<script>
export default {
  name: "ContentEditable",
  props: {
    value: {
      type: String,
      default: ""
    },
    canEdit: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      innerText: this.value,
      isLocked: false
    };
  },
  watch: {
    value() {
      if (!this.isLocked || !this.innerText) {
        this.innerText = this.value;
      }
    }
  },
  methods: {
    changeText() {
      this.$emit("input", this.$el.innerHTML);
    }
  }
};
</script>
<style lang="scss">
.edit-div {
  width: 100%;
  height: 100%;
  overflow: auto;
  word-break: break-all;
  outline: none;
  user-select: text;
  white-space: pre-wrap;
  text-align: left;
  &[contenteditable="true"] {
    &:empty:before {
      content: attr(placeholder);
      display: block;
      color: #ccc;
    }
  }
}
</style>

調用:

<ContentEditable v-model="text" />
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章