Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vue.js Vue模板中的匿名函数是性能杀手吗?_Vue.js_Templates_Anonymous Function_Emit - Fatal编程技术网

Vue.js Vue模板中的匿名函数是性能杀手吗?

Vue.js Vue模板中的匿名函数是性能杀手吗?,vue.js,templates,anonymous-function,emit,Vue.js,Templates,Anonymous Function,Emit,我有以下设置: 在子组件中: <template> <div @click="clickHandler"> </div> </template> <script> ... clickHandler() { this.$emit('emittedFunction', someInfo, otherInfo) } </script> ... clickHandler()

我有以下设置:

在子组件中:

 <template>
   <div @click="clickHandler">
   </div>
 </template>
 <script>
    ...
    clickHandler() { 
     this.$emit('emittedFunction', someInfo, otherInfo)
    }
 </script>

...
clickHandler(){
此.$emit('emittedFunction',someInfo,otherInfo)
}
在父组件中:

<template> 
  <child-component 
    v-for="index in 10"
    @emittedFunction="(someInfo, otherInfo) => someFunction(index, someInfo, otherInfo)"/>     
 </template>
 <script>
    ...
    someFunction(index, someInfo, otherInfo) { 
     do stuff 
    }
 </script>

...
someFunction(index,someInfo,otherInfo){
做事
}
这段代码运行得非常好。但我的一个问题是:我的一个朋友看到了这个代码片段,并在评论中说,“Vue模板中的匿名函数是性能杀手”,我应该用另一种方式来做……他显然没有解释如何做。 我在vue文档或堆栈溢出中找不到有关此主题的任何内容。我也不明白为什么这种代码会“杀死”性能? 他说得对吗?若有,原因为何?若否,原因为何?如果我的代码真的不好,有没有办法重构它


谢谢你的帮助

您的朋友指的是这样一个事实,即编译模板以呈现函数,这些函数在每次重新呈现时都会运行

他们所指的问题是,由于每个渲染中的处理程序不同,分配匿名函数的开销很小,这意味着Vue无法重用处理程序,并导致它使用侦听器重新渲染节点

这确实可能会带来性能问题,但不太可能因此而遇到或编写速度较慢的代码。通常情况下,如果组件重新渲染的频率太高,那么开销会变得很明显,这意味着您应该修复重新渲染触发器,而不是修复此触发器

因此,我不会说它是“性能杀手”,而是更像一个“优化机会”

为了安全起见,您可以使用闭包对其进行重构,如下所示:

<template> 
<child-component 
  v-for="index in 10"
  @emittedFunction="someFunction(index)(someInfo, otherInfo)"
/>     
</template>

<script>
   ...
   someFunction(index) { 
    return (someInfo, otherInfo) => {
      // this is a closure, you have access to the index.
    };
   }
</script>

...
函数(索引){
返回(someInfo,otherInfo)=>{
//这是一个闭包,您可以访问索引。
};
}

虽然这看起来很奇怪,但它不会在每次渲染时创建新函数,它只会在发出事件时创建一个新函数,并且它与渲染无关。

您的朋友指的是,模板被编译为渲染函数,渲染函数在每次重新渲染时运行

他们所指的问题是,由于每个渲染中的处理程序不同,分配匿名函数的开销很小,这意味着Vue无法重用处理程序,并导致它使用侦听器重新渲染节点

这确实可能会带来性能问题,但不太可能因此而遇到或编写速度较慢的代码。通常情况下,如果组件重新渲染的频率太高,那么开销会变得很明显,这意味着您应该修复重新渲染触发器,而不是修复此触发器

因此,我不会说它是“性能杀手”,而是更像一个“优化机会”

为了安全起见,您可以使用闭包对其进行重构,如下所示:

<template> 
<child-component 
  v-for="index in 10"
  @emittedFunction="someFunction(index)(someInfo, otherInfo)"
/>     
</template>

<script>
   ...
   someFunction(index) { 
    return (someInfo, otherInfo) => {
      // this is a closure, you have access to the index.
    };
   }
</script>

...
函数(索引){
返回(someInfo,otherInfo)=>{
//这是一个闭包,您可以访问索引。
};
}

虽然这看起来很奇怪,但它不会在每个渲染上创建新函数,它只会在发出事件时创建一个新函数,并且它与渲染无关。

这样写不需要Vue为每个节点生成一个内部包装函数吗,这么说,你又回到了起点了?我不确定Vue到底是如何做到的,但是如果你看看Vue源代码中的
updatelisteners.js
帮助程序。它创建一个特殊的
invoker
对象,作为处理程序的调度程序,对于iLife,就像上面代码段中的那样,它只将其添加到invoker
fns
中,如果它实际发生更改,它将删除它而不重新呈现节点,否则,它会执行一个简单的
==
来检查前一个处理程序是否等于新的处理程序。我认为源代码中更相关的部分是,它根据从
v-on
属性解析的字符串值生成
render
函数的相关部分。Vue本身需要创建一个包装函数,以便它可以在闭包中保存
索引
,并且每次呈现组件时都需要重新创建该函数,以确保它引用的是
索引
的最新值。首先感谢您的回答!!不过,这个话题似乎比我预想的更复杂。子组件中的“发射”事件将非常频繁地发射。父组件中的someFunction将更改一些值,这些值作为道具发送回子组件,因此编号为“index”的子组件将在该点重新渲染。但是我假设父组件在那个时候仍然不会完全重新加载?如果我每分钟发出200次“emittedFunction”,是否有办法确定是否会对性能产生影响?这样写不需要Vue为每个节点生成一个内部包装函数,所以实际上你回到了起点?我不确定Vue到底是如何做到的,但是如果您查看Vue源代码中的
updatelisteners.js
helper。它创建一个特殊的
invoker
对象,作为处理程序的调度程序,对于iLife,就像上面代码段中的那样,它只将其添加到invoker
fns
中,如果它实际发生更改,它将删除它而不重新呈现节点,否则,它会执行一个简单的
==
来检查前一个处理程序是否等于新的处理程序。我认为源代码中更相关的部分是,它根据从
v-on
属性解析的字符串值生成
render
函数的相关部分。Vue本身需要创建一个包装器函数,以便它可以在闭包中保存
索引
,并且该函数需要