【问题标题】:Vuejs Computed Setter with an object two way data binding具有对象双向数据绑定的 Vuejs Computed Setter
【发布时间】:2018-03-03 23:31:04
【问题描述】:

按照基本示例说明双向数据绑定的工作原理:

<template>
<input v-model="fullname"/>
<input v-model="first"/>
<input v-model="last"/>
</template>
<script>
    var app = new Vue({
      el: '#app',
      data: {
        first: '',
        last: ''
      },
      computed: {
        fullname: {
          // getter function
          get: function() {
            return this.first + " " + this.last
          },
          // setter function
          set: function(value) {
            var name = value.split(' ')
            this.first = name[0]
            this.last = name[1]
          }
        }
      }
    })
</script>

如图所示:https://youtu.be/PuxdMnk-u5k?t=17m43s (17:43) - 您可以在全名输入中轻松修改名字和姓氏数据。

现在我的情况有点不同。我有一个对象如下:

myObject: [
   {active: true, itemId: "55", text: 'some text', textOutput: ''}
   {active: true, itemId: "56", text: 'some text', textOutput: ''}
   {active: true, itemId: "58", text: 'some text', textOutput: ''}
   {active: true, itemId: "65", text: 'some text', textOutput: ''}
   {active: true, itemId: "105", text: 'some text', textOutput: ''}
]

接下来我通过计算稍微修改一下 - 这里只是添加到每个项目&lt;li&gt;标签:

modifyArrayItem () {
  var output=''
    for (var i=0; i<this.myObject.length; i++) {
      if (this.myObject[i].active) {
        this.myObject[i].textOutput= '<li>' + this.myObject[i].text + '</li>'
        output = output + this.myObject[i].textOutput
      }
      else {
        this.myObject[i].textInput = ''
      }          
    }
    return output
  }, 

然后通过 v-html 只输出活动项目

<div  v-html="modifyArrayItem"></div>

到目前为止很容易。现在我希望能够通过我的 html 中的输出来编辑输出,比如说 quill-editor:

<quill-editor v-model="modifyArrayItem" :options="options"></quill-editor>

可以吗?

我应该怎么做才能根据我的羽毛笔编辑器字段中的itemId 数字编辑myObject[n-element].textmyObject[n-element].textOutput? (请注意[n-element] != itemId)。

如何在编辑时将每个元素的myObject.active 动态更改为真/假,以防止编辑后的数据丢失?将编辑后的文本保存到单独的变量中怎么样?

编辑:一些想法 - 为每个 &lt;li&gt; 添加某种带有 itemId 值的不可见标签到 quill-editor?

【问题讨论】:

  • 你能提供一个 jsfiddle 的东西吗?看起来modifyArrayItem() 返回一个字符串。那么你想如何访问它的第 n 个元素呢? proTemplate 是什么?现在我只能告诉你使用sync 修饰符或事件。在文档中了解如何使用它们。
  • @oniondomes 抱歉,我现在已将其更正为 myObject。这是如何访问第 n 个元素的主要问题。我认为这可以通过引用 itemId 来完成,它旨在是独一无二的。我想以某种方式类似于第一个示例。同步或事件可能是有价值的建议,我会寻找它们
  • 最简单的解决方案是传递一个实际数组并将其转换为编辑器组件内的字符串。因此,您可以键入 Id 并将它们发送回父级。
  • @oniondomes 你的意思是很多编辑器 - 每个都在单个组件模板上吗?每一个&lt;li&gt;?还是那样的?我认为这是最后的解决方案,因为我的用户将无法在编辑器 /li 之间移动光标
  • 可能会在 quill-editor 中添加某种带有 itemId 值的不可见标签?

标签: vue.js wysiwyg quill


【解决方案1】:

是的,这是可能的。您可以将 HTML 解析为行,并将这些行分配给它们在 myObject 中的相应条目。

但是,请注意,每次键入内容时更新编辑器的内容会导致光标移动到编辑器的开头。

原来 quill 有一种获取和设置选择位置的方法。它有点毛茸茸,因为每个编辑调用设置两次,所以你必须检查是否有任何实际变化。但这有效:

modifyArrayItem: {
  get() {
    return this.myObject.map(o => "<li>" + o.text + "</li>").join("");
  },
  set(newValue) {
    const oldLines = this.myObject.map((o) => o.text);
    const lines = newValue.split("</p>")
      .map((p) => p.replace('<p>', ''));
    const same = oldLines.join('') === lines.join('');

    if (!same) {
      const pos = this.$refs.quill.quill.getSelection();
      for (let i=0; i < this.myObject.length; ++i) {
        this.myObject[i].text = lines[i];
      }
      this.$nextTick(() => {
        this.$refs.quill.quill.setSelection(pos);
      });
    }
  }
}

Updated codepen

【讨论】:

  • 让我看看...这个光标移到开头可能会消除这个解决方案。我需要它像正常打字一样工作。另一种想法是在同一页面中为每个&lt;li&gt;一个接一个地放置5个quill编辑器,但是在它们之间移动会有光标问题
  • 谢谢你,你是我的 StackOverflow 英雄 :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-22
相关资源
最近更新 更多