Vue.js 移除渲染函数中的 contenteditable 属性

Vue.js remove contenteditable attribute in render function

看起来应该是一个简单的解决方案,但出了点问题...

我需要有条件地从元素中删除 contenteditable 属性:

<!-- first state -->
<div contenteditable="true"></div>

<!-- second state -->
<div></div>

我试过:

data() {
    return {
      contenteditable: true,
      title: "Title",
    };
  },
  methods: {
    handleClick() {
      this.contenteditable = null;
      this.title = null;
    },
  },
  render(createElement) {
    const options = {
      attrs: {
        id: "ID",
        title: this.title,
        contenteditable: this.contenteditable,
        // Not working either
        //...(this.contenteditable && { contenteditable: true }),
      },
      domProps: {
        innerHTML: "<p>Test</p>",
      },
      on: {
        click: this.handleClick,
      },
    };

    return createElement("div", options);
  },

Sandbox

结果是:<div contenteditable="false"></div>,但我需要完全删除属性。例如 title 属性按预期工作,如果它的值设置为 null,它不会呈现。我还尝试使 attrs 对象完全响应,例如:

data() {
  return {
    attrs: {
      title: 'Title',
      contenteditable: true,
    }
  }
},
methods: {
  handleClick() {
    Vue.delete(this.attrs, 'contenteditable')
    Vue.delete(this.attrs, 'title')
  },
},
render(createElement) {
    const options = {
      attrs: this.attrs,
      domProps: {
        innerHTML: "<p>Test</p>",
      },
      on: {
        click: this.handleClick,
      },
    };

    return createElement("div", options);
  },

Sandbox

...但没有运气。有什么解决办法吗?

谢谢!

Vue 2 将 contenteditable 属性视为 Vue 3 中的 special case here, it will not remove the attribute if the new attribute value is undefined. This is fixed(或计划)。

您可以绕过此行为并将其设置为 domProps

domProps: {
  contentEditable: this.contenteditable ? 'true' : 'inherit'
}

这是一个演示:

new Vue({
  el: '#app',
  data() {
    return {
      contenteditable: false
    }
  },
  render(h) {
    return h('div', [
      h('button', {
        on: {
          click: () => this.contenteditable = !this.contenteditable
        }
      }, `contenteditable: ${this.contenteditable}`),
      h('div', {
        domProps: {
          contentEditable: this.contenteditable ? 'true' : 'inherit'
        }
      }, 'Text')
    ])
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
</div>

假设你的div如下

<div id="editable"></div>

然后使用以下方法切换 contenteditable

document.getElementById('editable').contentEditable = "true"

document.getElementById('editable').setAttribute('contentEditable',"true")

如果你想让这个 div 在开头是 contentEditable 然后在 mounted.

里面添加上面的行