javascript - vuejs 对数组元素使用计算属性

标签 javascript vue.js

我有一个基本模板,它通过如下两种方式的数据绑定(bind)从所见即所得编辑器输出文本:

<template>
  <div>
    <quill-editor 
      v-model="debounceText"
      :options="editorOptionProTemplate"
      >
    </quill-editor>
  <div  v-html="textComputed"></div>
  </div>
</template>

<script>
data () {
  return {
    text: ''
  }
},
computed: {
debounceText: {
  get() { return this.text; },
  set: _.debounce(function(newValue) {
    this.text = newValue;
  }, 100)
 },
//using computed for many variants for styling output in web (here just adding <b> tag)
  textComputed() {
    return '<b>' + this.text + '</b>'
  }
 }
</script>

在这个级别一切正常

现在,我正在将变量更改为数组(对象),使用 v-for(同时编辑许多元素并将它们输出到数组中,如下所示):

<template>
  <div v-for="item in items">
    <quill-editor 
      v-model="item.text"
      :options="editorOptionProTemplate"
      >
    </quill-editor>
  <div v-html="textComputedArray"></div>
  </div>
</template>

<script>
data () {
  return {
    items: [
      {active: true, text: 'text1', textOutput: ''},
      {active: true, text: 'text2', textOutput: ''},
      {active: true, text: 'text3', textOutput: ''},
      {active: true, text: 'text4', textOutput: ''},
      {active: true, text: 'text5', textOutput: ''}
   ]
  }
},

textComputedArray: {
        var output=''
          for (var i=0; i<this.items.length; i++) {
            if (this.items[i].active) {
              this.items[i].textOutput= this.items[i].text + '<br />'
              output = output + this.items[i].textOutput
            }
            else {
              this.items[i].textOutput= ''
            }          
          }
          return output
        },
</script>

我应该如何修改我的代码以将 debounceText 计算应用于此输出?我认为我根本无法将计算添加到我的模板中,而且我也无法将任何参数传递给计算属性。

也许比我更有经验的人会给我一些解决方案/建议?

最佳答案

任何时候你有一个数组并且你认为每个项目都需要计算,你应该考虑制作一个组件。这就是数据和计算相互关联的方式。

在很多情况下,您可以根据数组进行计算,这很好,但您应该意识到对数组的任何更改都会导致重新计算整个计算数组。对于组件,仅重新计算受影响的行。此处嵌入了一个简单示例。

new Vue({
  el: '#app',
  data: {
    arr: [1, 2, 3]
  },
  computed: {
    carr() {
      console.log("Computing the whole array");
      return this.arr.map(x => 'hi ' + x);
    }
  },
  components: {
    addHi: {
      props: ['value'],
      template: '<div>{{a}}</div>',
      computed: {
        a() {
          console.log("Computing for", this.value);
          return 'hi ' + this.value;
        }
      }
    }
  },
  created() {
    setTimeout(() => {
      console.log("** Changing a value");
      this.arr.splice(2, 1, 'X');
    }, 1500);
  }
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div v-for="a in carr">{{a}}</div>
  <add-hi v-for="a in arr" :value="a" :key="a"></add-hi>
</div>

如果你需要你的计算是可写的,你将无法编辑单个项目,所以你真的被迫制作一个组件。这非常简单:只需将 HTML 移动到组件的模板中,将计算移动到组件中(调整它以在 prop value 上工作),然后 - 因为它是在 prop 上运行– 将 set 函数更改为使用 $emit 而不是直接更改其值。

debouncedQuillEditor: {
  props: ['value', 'options'],
  template: '<quill-editor v-model="debouncedValue" :options="options"></quill-editor>',
  computed: {
    debouncedValue: {
      get() {
        return this.value;
      },
      set: _.debounce(function(newValue) {
        this.$emit('input', newValue);
      }, 100)
    }
  }
},

我做了 a fiddle展示。我制作了第二个组件来处理输出 HTML,尽管它本可以包含在第一个组件中。

关于javascript - vuejs 对数组元素使用计算属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49025064/

相关文章:

vue.js - 如何使用 Vuetify 反转标题方向?

vue.js - 更改点击事件 vue.js 的过滤器

javascript - Cypress 包含 if/else 条件语句

javascript - 为什么在此示例中使用生成器函数比填充和迭代数组慢?

vue.js - @ 符号在 Vue.js 中有什么作用?

unit-testing - 使用 jest 和 avoriaz 时如何在 Vuejs 的组件中测试异步方法

javascript - Vuex 操作不等待完成 axios promise

javascript - Firefox Web 扩展覆盖新标签页

javascript - 解码 JavaScript 编码的内容

javascript - 谁来为 ngx-bootstrap Daterangepicker 定义日期模式?