Là phương pháp trong Vue phản ứng?


9

Tôi đã sử dụng Vue được một thời gian và kinh nghiệm của tôi luôn là một phương pháp sẽ tính toán lại nếu dữ liệu phản ứng cơ bản của nó được cập nhật. Tôi đã gặp thông tin mâu thuẫn trên SO:

  • Tôi đã cố gắng trả lời câu hỏi này và đã được nói nhiều lần rằng đây không phải là trường hợp.
  • Câu trả lời được chấp nhận ở đây chỉ ra rằng "[một phương thức] sẽ chỉ được đánh giá khi bạn gọi nó một cách rõ ràng."

Tôi đã tìm kiếm thông qua các tài liệu và tôi không thấy bất cứ điều gì cực kỳ rõ ràng.

Nếu chúng không phản ứng, thì tại sao ví dụ này hoạt động?

<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);
    },
  },
};

Tôi thực sự muốn có một câu trả lời dứt khoát và thỏa mãn mà cộng đồng này có thể tham khảo.


Câu hỏi tuyệt vời - không chắc có câu trả lời "chính thức" đại diện cho thực tế!
— Tyler

Câu trả lời:


4

Dựa trên cách các thay đổi được theo dõi từ các tài liệu, đây là những gì đang diễn ra:

Sơ đồ chu trình phản ứng Vue

  1. Một trình theo dõi đặc biệt được tạo cho phiên bản thành phần để xác định khi nào cần kết xuất lại.

  2. Vue chuyển đổi tất cả các thuộc tính của datagetters và 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. Mẫu được hiển thị. Trong quá trình kết xuất, một cuộc gọi đến isAwesomeđược thực hiện từ mẫu.
  2. Trong cơ thể của isAwesome, getter cho awesomeAnimalIdsđược gọi.
  3. Người theo dõi thiết lập một sự phụ thuộc vào awesomeAnimalIdslĩnh vực data.
  4. Sau khi hết thời gian, awesomeAnimalIdsđược cập nhật, sẽ gọi awesomeAnimalIdssetter.
  5. Bởi vì mẫu phụ thuộc vào datatrường nhận được thông báo, kết xuất lại được kích hoạt.
  6. Lặp lại bước (3).

Từ ví dụ này và ví dụ trên, chúng ta có thể kết luận như sau:

Một cuộc gọi phương thức được thực hiện từ một mẫu thiết lập một phụ thuộc phản ứng vào tập hợp con của datacác trường được sử dụng trong ngăn xếp cuộc gọi phương thức. Nếu các trường bên dưới được cập nhật, nó sẽ kích hoạt kết xuất lại thành phần.

Có một quan niệm sai lầm phổ biến rằng các phương thức "chỉ được gọi một lần" hoặc "bắn và quên" khi được gọi từ một mẫu. Điều này rõ ràng không phải luôn luôn như vậy bởi vì các phương pháp có thể thiết lập một sự phụ thuộc phản ứng .

Vậy khi nào chúng ta nên sử dụng một thuộc tính được tính toán so với một phương thức?

Xem phần hướng dẫn về Bộ nhớ đệm tính toán và Phương thức . Đây là của tôi về nó:

  • Một tài sản được tính toán sẽ chỉ đánh giá lại khi các phụ thuộc phản ứng của nó đã thay đổi. Tức là nó sử dụng bộ nhớ đệm để cải thiện hiệu quả.
  • Tính chất tính toán nên không có tác dụng phụ. Ví dụ, bạn không nên gọi fetchtừ họ.
  • Luôn thích một thuộc tính được tính toán cho một phương thức nếu có thể vì lý do hiệu quả.
  • Sử dụng một phương pháp nếu bạn có tác dụng phụ hoặc nếu bạn cần vượt qua trong một đối số (như đã thấy trong câu hỏi ban đầu).

Đẹp giải thích rõ ràng, cảm ơn.
— Ackroydd

4

Không, phương pháp không phản ứng. Chỉ dữ liệu có thể được phản ứng trong Vue.

NHƯNG điều quan trọng là hiểu cách Vue hoạt động ...

  1. Vue sẽ lấy mẫu của bạn, biên dịch nó thành chức năng kết xuất và chạy chức năng kết xuất
  2. Trong khi chức năng kết xuất đang chạy, Vue giám sát tất cả các data()thành viên (nó luôn thực hiện việc này, không chỉ trong lần kết xuất đầu tiên). Nếu bất kỳ dữ liệu nào được truy cập trong khi kết xuất, Vue biết rằng nội dung của thành viên dữ liệu này ảnh hưởng đến kết quả kết xuất.
  3. Vue sử dụng kiến ​​thức thu thập được ở bước 2. Bất cứ khi nào thành viên dữ liệu "chạm" trong khi thay đổi kết xuất, nó sẽ biết kết xuất lại sẽ xảy ra và thực hiện điều ...

Không thành vấn đề nếu bạn tham chiếu trực tiếp thành viên dữ liệu, sử dụng nó trong computedhoặc trong một method. Nếu dữ liệu bị "chạm" trong khi kết xuất, việc thay đổi dữ liệu sẽ kích hoạt kết xuất lại trong tương lai ...


1

Đây là một trường hợp rất thú vị.

Từ những gì tôi đã đọc và kinh nghiệm của tôi, tôi có thể nói rằng: Không, các phương pháp vốn không phải là phản ứng. Một phương thức phải được gọi một cách rõ ràng để nó thực thi.

Nhưng, làm thế nào tôi có thể giải thích trường hợp của bạn? Tôi đặt mã của bạn vào một hộp cát và chắc chắn, khi bạn đẩy id vào mảng, mẫu cập nhật để hiển thị tên động vật. Điều này sẽ chỉ ra một số phản ứng. Đưa cái gì?

Vâng, tôi đã chạy một thí nghiệm. Tôi đã thêm một đơn giản divcho mỗi vòng lặp tạo ra một số ngẫu nhiên khi được tạo.

<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();
}

Và những gì tôi thấy là mỗi khi một id mới được đẩy vào mảng, tất cả các số ngẫu nhiên sẽ thay đổi. Đây là chìa khóa để hiểu tại sao nó "có vẻ" như thể phương pháp isAwesomenày là phản ứng.

Bằng cách nào đó, khi một ID mới được đẩy vào mảng, Vue sẽ hiển thị lại toàn bộ vòng lặp, do đó thực hiện lại các phương thức. Tôi không thể giải thích các hoạt động bên trong về lý do tại sao vue tái hiện lại toàn bộ vòng lặp, điều đó sẽ cần nghiên cứu thêm.

Để trả lời câu hỏi của bạn. isAwesomekhông phản ứng, nó chỉ là một ảo ảnh được tạo ra bởi sự kết xuất lại của vòng lặp.


1
nó đúng với mọi thuộc tính có thể quan sát được trong một thành phần (prop / data / tính toán). bất cứ khi nào họ đang thay đổi nó trigger updategây ra một re-rendervà gây nên bất kỳ phương pháp mà đang bị ràng buộc trong bản mẫu
— Ohgodwhy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.