Vue.js Vue中的方法是否具有反应性?

Vue.js Vue中的方法是否具有反应性?,vue.js,Vue.js,我使用Vue已经有一段时间了,我的经验是,如果底层的反应性数据被更新,方法将重新计算。我在以下方面遇到了相互矛盾的信息: 我试图回答,但被多次告知情况并非如此 接受的答案表明“[方法]只有在显式调用时才会被计算。” 我翻遍了文件,没有看到任何异常清晰的东西 如果它们不是反应性的,那么这个例子为什么有效 {{animal.name} 导出默认值{ 数据(){ 返回{ 冬虫夏草:, 动物:[ {id:1,名称:'dog'}, {id:5,名称:'cat'}, {id:9,名字:'鱼'}

我使用Vue已经有一段时间了,我的经验是,如果底层的反应性数据被更新,方法将重新计算。我在以下方面遇到了相互矛盾的信息:

  • 我试图回答,但被多次告知情况并非如此
  • 接受的答案表明“[方法]只有在显式调用时才会被计算。”
我翻遍了文件,没有看到任何异常清晰的东西

如果它们不是反应性的,那么这个例子为什么有效

  • {{animal.name}
导出默认值{
数据(){
返回{
冬虫夏草:,
动物:[
{id:1,名称:'dog'},
{id:5,名称:'cat'},
{id:9,名字:'鱼'},
],
};
},
创建(){
设置超时(()=>{
这个。令人敬畏的动物。推(5);
}, 1000);
设置超时(()=>{
这个。令人敬畏的动物。推(9);
}, 2000);
},
方法:{
isAwesome(动物){
返回此.awesomeAnimalIds.includes(animal.id);
},
},
};

我想真的想得到一个明确而令人满意的答案,这个社区可以参考。

这是一个非常有趣的案例

根据我的阅读和经验,我可以说:不,方法本身并不是被动的。必须显式调用方法才能执行。

但是,那我怎么解释你的情况呢?我将您的代码放入沙箱中,当您将id推入数组时,模板会更新以显示动物名称。这表明存在某种反应性。有什么好处

嗯,我做了一个实验。我在每个循环中添加了一个简单的
div
,该循环在生成时生成一个随机数

<li v-for="animal in animals" :key="animal.id">
        <div>{{ random() }}</div>
        <span v-if="isAwesome(animal)">{{ animal.name }}</span>
</li>

...

random() {
      return Math.random();
}
  • {{random()}} {{animal.name}
  • ... 随机的{ 返回Math.random(); }
    我看到的是,每当一个新的id被推入数组,所有的随机数都会改变。这是理解为什么方法
    似乎是反应性的关键

    不知何故,当一个新ID被推送到数组时,Vue会完全重新呈现循环,从而再次执行这些方法。我无法解释为什么vue重新呈现整个循环的内部工作原理,这需要进一步研究


    来回答你的问题
    isAwesome
    不是反应性的,它只是通过重新渲染循环而产生的幻觉

    不,方法不是被动的。在Vue中,只有数据可以是被动的。

    但了解Vue的工作原理很重要

  • Vue将获取模板,将其编译为渲染函数并运行渲染函数
  • 渲染函数运行时,Vue会监视所有
    data()
    成员(它会一直这样做,而不仅仅是在第一次渲染期间)。如果在渲染期间访问了任何数据,则Vue知道此数据成员的内容会影响渲染结果
  • Vue使用步骤2中收集的知识。每当数据成员在渲染过程中“接触”更改时,它就知道应该进行重新渲染并执行该操作
  • 直接引用数据成员并不重要,可以在
    计算中使用它,也可以在
    方法中使用它,如果在渲染过程中“接触”了数据,数据的更改将在将来触发重新渲染…

    基于文档,下面是发生的情况:

  • 为组件实例创建一个特殊的观察程序,以确定何时需要重新渲染

  • Vue将
    数据的所有属性转换为getter和setter

  • 获取动物(){
    //添加依赖项:如果动物更新,可能会触发重新渲染
    ...
    }
    设置动物(){
    //通知观察者动物已更新
    ...
    }
    获得令人敬畏的动物(){
    //添加依赖项:如果awesomeAnimalIds更新,可能会触发重新渲染
    ...
    }
    设置awesomeAnimalIds(){
    //通知观察者awesomeAnimalIds已更新
    ...
    }
    
  • 将呈现模板。在渲染期间,将从模板调用
    isAwesome
  • isAwesome
    的主体中,调用了
    awesomeAnimalIds
    的getter
  • 观察者在
    数据
    awesomeAnimalIds
    字段上建立依赖关系
  • 超时后,
    awesomeAnimalIds
    将更新,这将调用
    awesomeAnimalIds
    setter
  • 由于模板依赖于收到通知的
    数据
    字段,因此会触发重新渲染
  • 重复步骤(3)
  • 通过以上示例,我们可以得出以下结论:

    从模板进行的方法调用在方法调用堆栈中使用的
    数据
    字段子集上建立反应式依赖关系。如果基础字段被更新,它将触发组件的重新渲染

    有一种常见的误解,即从模板调用方法时,“只调用一次”或“触发并忘记”。显然情况并非总是如此,因为方法可以建立一个反应性依赖关系

    那么什么时候应该使用计算属性与方法?

    请参阅上的指南部分。以下是我对它的看法:

    • 计算属性只有在其反应依赖项发生更改时才会重新计算。也就是说,它使用缓存来提高效率
    • 计算属性应该没有副作用。例如,你不应该给他们打电话
      fetch
    • 如果可能的话,出于效率原因,请始终选择计算属性而不是方法
    • 如果你有副作用或者你需要传递一个参数(如原问题所示),请使用一种方法
    好问题--不确定是否有