本文介绍了Vue 中的方法是反应式的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Vue 已经有一段时间了,我的经验一直是,如果更新了底层响应式数据,方法将重新计算.我在 SO 上遇到了相互矛盾的信息:

  • 我试图回答

    1. 为组件实例创建了一个特殊的观察器,以确定何时需要重新渲染.

    2. Vue 将 data 的所有属性转换为 getter 和 setter.

    get Animal() {//添加依赖:如果动物更新,可能会触发重新渲染...}设置动物(){//通知观察者动物已经更新...}获得 awesomeAnimalIds() {//添加依赖:如果 awesomeAnimalIds 更新,可能会触发重新渲染...}设置 awesomeAnimalIds() {//通知观察者 awesomeAnimalIds 已更新...}
    1. 模板已呈现.在渲染期间,从模板调用 isAwesome.
    2. isAwesome 的主体中,调用了awesomeAnimalIds 的getter.
    3. 观察者建立对dataawesomeAnimalIds字段的依赖.
    4. 超时后,更新 awesomeAnimalIds,从而调用 awesomeAnimalIds 设置器.
    5. 因为模板依赖于接收通知的 data 字段,所以会触发重新渲染.
    6. 重复步骤 (3).

    从这个和上面的例子,我们可以得出以下结论:

    从模板进行的方法调用建立了对方法调用堆栈中使用的 data 字段子集的反应式依赖.如果底层字段被更新,它将触发组件的重新渲染.

    有一个普遍的误解,认为方法只调用一次".或火而忘记"从模板调用时.显然情况并非总是如此,因为方法可以建立反应式依赖.

    那么我们什么时候应该使用计算属性和方法呢?

    请参阅关于计算缓存与方法.这是我的看法:

    I've been using Vue for a while, and my experience has always been a method will recompute if its underlying reactive data is updated. I've encountered conflicting information on SO:

    I searched through the docs and I didn't see anything incredibly clear.

    If they are not reactive, then why does this example work?

    <ul>
      <li v-for="animal in animals" :key="animal.id">
        <span v-if="isAwesome(animal)">{{ animal.name }}</span>
      </li>
    </ul>
    
    export default {
      data() {
        return {
          awesomeAnimalIds: [],
          animals: [
            { id: 1, name: 'dog' },
            { id: 5, name: 'cat' },
            { id: 9, name: 'fish' },
          ],
        };
      },
      created() {
        setTimeout(() => {
          this.awesomeAnimalIds.push(5);
        }, 1000);
        setTimeout(() => {
          this.awesomeAnimalIds.push(9);
        }, 2000);
      },
      methods: {
        isAwesome(animal) {
          return this.awesomeAnimalIds.includes(animal.id);
        },
      },
    };
    

    I would really like to have a definitive and satisfying answer that this community can refer to.

    解决方案

    Based on How Changes Are Tracked from the docs, here's what's going on:

    1. A special watcher is created for the component instance to determine when a re-render is required.

    2. Vue converts all properties of data to getters and setters.

    get animals() {
      // Add dependency: potentially trigger a re-render if animals updates
      ...
    }
    set animals() {
      // Notify the watcher that animals has been updated
      ...
    }
    get awesomeAnimalIds() {
      // Add dependency: potentially trigger a re-render if awesomeAnimalIds updates
      ...
    }
    set awesomeAnimalIds() {
      // Notify the watcher that awesomeAnimalIds has been updated
      ...
    }
    
    
    1. The template is rendered. During the render, a call to isAwesome is made from the template.
    2. In the body of isAwesome, the getter for awesomeAnimalIds is invoked.
    3. The watcher establishes a dependency on the awesomeAnimalIds field of data.
    4. After a timeout, awesomeAnimalIds is updated, which invokes the awesomeAnimalIds setter.
    5. Because the template depends on a data field which received a notification, a re-render is triggered.
    6. Repeat step (3).

    From this and the example above, we can conclude the following:

    There is a common misconception that methods are "invoked only once" or "fire and forget" when called from a template. This is clearly not always the case because methods can establish a reactive dependency.

    So when should we use a computed property vs a method?

    See the guide section on Computed Caching vs Methods. Here's my take on it:

    • A computed property will only reevaluate when its reactive dependencies have changed. I.e. it uses caching for improved efficiency.
    • Computed properties should be side-effect free. E.g. you shouldn't call fetch from them.
    • Always prefer a computed property to a method if possible for efficiency reasons.
    • Use a method if you have side effects or if you need to pass in an argument (as seen in the original question).

    这篇关于Vue 中的方法是反应式的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 16:51