【问题标题】:How to avoid vue component redraw?如何避免vue组件重绘?
【发布时间】:2018-07-04 18:10:40
【问题描述】:

我已经在 Vue 中准备了带有标签分组的标签输入控件。模板包括:

<script type="text/x-template" id="tem_vtags">
<div class="v-tags">
  <ul>
    <li v-for="(item, index) in model.items" :key="index" :data-group="getGroupName(item)"><div :data-value="item"><span v-if="typeof model.tagRenderer != 'function'">{{ item }}</span><span v-if="typeof model.tagRenderer == 'function'" v-html="tagRender(item)"></span></div><div data-remove="" @click="remove(index)">x</div></li>
  </ul>
  <textarea v-model="input" placeholder="type value and hit enter" @keydown="inputKeydown($event,input)"></textarea>
  <button v-on:click="add(input)">Apply</button>
</div>
</script>

我已经定义了名为 .getGroupName() 的组件方法,它依赖于可以在 props 上设置的名为 .qualifier() 的其他函数。

我的问题:一旦我将任何标签添加到集合 (.items) 中,当我在 textarea 中为每个 keydown 输入任何内容时,.getGroupName() 似乎被调用了。看起来像在 textarea 中输入任何内容会导致所有组件重新渲染?

你知道如何避免这种行为吗?我希望 .getGroupName 只有在添加新标签时才会被调用。

完整代码如下: https://codepen.io/anon/pen/bKOJjo?editors=1011(我已放置 debugger; 以在运行时进入 .qualifier() 时捕获。

任何帮助appriciated。

男人

【问题讨论】:

    标签: vuejs2


    【解决方案1】:

    TL;DR;
    你不能,你能做的就是优化以减少函数调用。


    重绘是动态的,由数据更改触发。因为你有函数(v-model@keydown)你会更新数据。问题是当你调用一个函数时::data-group="getGroupName(item)" 它每次都会执行,因为它不假设哪些数据可能已经改变。

    一种处理方法是将 groupName 设置为计算的 key-val 对象,您可以在不调用函数的情况下进行查找。然后您可以使用:data-group="getGroupName[item]",而无需在重绘时调用该函数。 v-html="tagRender(item)"也应该这样做

    【讨论】:

      【解决方案2】:

      与其试图与框架处理数据输入事件和渲染的方式作斗争,不如利用它来发挥你的优势:

      new Vue({
        el: '#app',
        template: '#example',
        data() {
          return {
            someInput: '',
            someInputStore: []
          };
        },
        methods: {
          add() {
            if (this.someInputStore.indexOf(this.someInput) === -1) {
              this.someInputStore.push(this.someInput);
              this.someInput = '';
            }
          },
        }
      });
      <html>
      
      <body>
        <div id="app"></div>
        <template id="example">
          <div>
            <textarea v-model="someInput" @keyup.enter.exact="add" @keyup.shift.enter=""></textarea>
            <button @click="add">click to add new input</button>
            <div>
              {{ someInputStore }}
            </div>
          </div>
        </template>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
      </body>
      
      </html>

      事件修饰符修改

      在示例中,您可以看到我使用了 4 种不同的事件修饰符来达到预期的结果,但我将在这里重点介绍它们的组合:

      1. @keyup.enter.exact - 允许控制触发事件所需的系统修饰符的精确组合。在本例中,我们正在寻找回车按钮。
      2. @keyup.shift.enter - 这是有趣的一点。我们可以使用它(和一个空白值)来防止我们添加到@keyup.enter.exact 中的事件触发,而不是试图阻止框架触发这两个事件。我必须注意="" 对整个设置正常工作至关重要。没有它,您就无法为 vue 提供触发 add 方法的替代方法,如我的示例所示。

      我希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2019-09-24
        • 1970-01-01
        • 1970-01-01
        • 2019-07-17
        • 1970-01-01
        • 2021-04-20
        • 2013-04-06
        • 2018-04-05
        • 1970-01-01
        相关资源
        最近更新 更多