输入更改的v模型会影响性能

时间:2019-04-03 16:05:57

标签: javascript vue.js vuetify.js

所以我有一个页面基于这样的数组呈现v列表:

<v-list-tile v-for="item in array">
{{item}}
</v-list-tile>

和带有v-text-field的对话框:

<v-dialog>
    <v-text-field v-model="myInput">
    </v-text-field>
</v-dialog>

现在这很正常。 但是通过性能测试,我发现对于myInput模型更改(例如按键)触发的每个事件,在实际上不相关的情况下,也会触发v-for重新呈现列表。

在我庞大的阵列上,这是一个严重的问题,使UI真的很滞后。我认为这对于vuejs应用程序是正常的行为,但是我想知道是否可以准确地告诉wish元素检查重新渲染。

我尝试了一些v-if语句,但没有成功。

我希望对此有一个答案,我想我丢失了一些东西。

如果您要测试,我在这里所说的是准备就绪的html文件,请使用调试控制台对其进行调试,您会看到 [vue警告] < / em>重复键的消息,表明每次按键确实调用v-for。

现在想像一下,如果数组(此处为项目)远大于数组,并且包装到复杂的组件中,那么当我们仅打算更改“ myInput”值时,进行该调用会导致性能太重。


<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{data}}
        <ul>
            <li v-for="item in items" :key="item">
                {{ item.message }}
            </li>
        </ul>
        <input v-model="data"></input>
    </div>
</body>

<script>
    new Vue({
        el: '#app',
        data: () => ({
            data: '',
            items: [{
                    message: 'Foo'
                },
                {
                    message: 'Bar'
                }
            ]
        })
    })
</script>

</html>

3 个答案:

答案 0 :(得分:0)

尝试在更改事件后使用.lazy修饰符进行同步。

<input v-model.lazy="data"></input>

https://vuejs.org/v2/guide/forms.html#lazy

编辑

@IVO GELOV是正确的,当组件更改时,将重新渲染。该解决方案将您的组件分为几个子组件。

https://vuejs.org/v2/guide/reactivity.html

这是一个使用插槽的代码,使其看起来像您的示例。

  

HTML

    <div id="app">
   <new-component>
     <ul>
       <li v-for="item in items" :key="item">
         {{ item.message }}
       </li>       
     </ul>    
   </new-component>
</div>
  

JavaScript

    Vue.component('new-component', {
  data: () => {
    return {
      data: ''
    }
  },
  template: `
    <div>
      <div>{{ data }}</div>
      <slot></slot>
      <input v-model="data"></input>
    </div>`
})

new Vue({
        el: '#app',
        data: () => ({            
            items: [{
                    message: 'Foo'
                },
                {
                    message: 'Bar'
                }
            ]
        })
    })

答案 1 :(得分:0)

这是一个代码笔,在其自己的组件中显示了内部循环

Codepen.io

我在Date.now()个列表项之后添加了items[x].message,以显示重新呈现列表的时间。

如果Codepen掉线了:

<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        Main vue: {{data}}
        <loop-component :data="loopdata"></loop-component>
        <input v-model="data"></input>
        <input v-model="loopdata"></input>
    </div>
<script>
Vue.component('loop-component', {
    props: ['data'],
    data() {
        return {
            items: [
                {message: 'Foo'},
                {message: 'Bar'}
            ]
        }
    },
    template: `
<div>
Loop component: {{ data }}
<ul>
  <li v-for="(item, index) in items" :key="index">
    {{ item.message + ' Date.now(): ' + Date.now() }}
  </li>
</ul>
</div>
`
});

let app = new Vue({
    el: '#app',
    data: () => ({
        data: '',
        'loopdata': '',
        items: [
            {message: 'Foo'},
            {message: 'Bar'},
        ]
    }),
});
</script>
</body>
</html>

答案 2 :(得分:-1)

从Vue 2.0+开始,每当检测到更改-整个组件都会重新呈现。如果要避免这种情况-将您的组件分成几个子组件。

您的示例并不能证明您的意思-v-for中存在重复键警告的事实并不意味着v-for在每次按键时都会重新评估。要确认我的声明,只需更改您的代码,如下所示:

<li v-for="(item,idx) in items" :key="idx">

现在没有警告。