三脚猫

Vue使用可编辑div进行数据双向绑定的尝试

2019-08-12  本文已影响0人  DADFAD

表单可以通过简单的v-model实现数据的双向绑定(value 的单向绑定 + onChange 事件侦听),实现所见即所得,但表单是限高的,在文本的输入过程中不能自增高度,因此想到使用div进行数据双向绑定;

为了实现View=>Model,需要一个可编辑的div,这里使用了contenteditable属性:

<!-- EditableDiv.vue -->
<template>
  <div ref="div" contenteditable="true"></div>
<template/>

v-model并不能直接在div上使用,我们通过mounted周期来模拟插值的过程:

// EditableDiv.vue
export default {
  props: ['value'], // 组件接受一个 value 属性用来在 div 中展示
  mounted() {
    this.setVal(this.value) // 将 value 注入 div 中
  },
  methods: {
    setVal(val) {
      this.$refs.div.innerHTML = val
    }
  },
  watch: {
    // 当 props.value 发生改变时 更新 div 中的值
    value(val) {
      this.setVal(this.value)
    }
  }
}

这样就实现了视图向数据的绑定。

在实现Model=>View的过程中,会有较多头疼的问题,这篇文章做了很好的总结,但最终还是无法做到像input一样真实的绑定,只是模拟了行为。

以下是通过blur事件实现的绑定,同样也是妥协后的结果:

<!-- EditableDiv.vue -->
<!-- 为 div 绑定 blur 事件以更新value -->
<template>
  <div
    ref="div"
    contenteditable="true"
    @blur="$emit('update:value', $event.target.innerHTML)"
  ></div>
</template>

在使用时通过sync修饰符:

<!-- Home.vue -->
<editable-div :value.sync="content" />
上一篇下一篇

猜你喜欢

热点阅读