Phương pháp so với tính toán trong Vue


178

Sự khác biệt chính giữa một phương thức và giá trị được tính toán trong Vue.js là gì?

Chúng trông giống nhau và có thể thay thế cho nhau.



1
@xDreamCoding Câu trả lời mà bạn liên kết xảy ra để giải quyết câu hỏi này thực sự, nhưng không có cách nào câu hỏi này là trùng lặp. Thêm vào đó là nổi tiếng hơn.
Romain Vincent

Tham khảo tài liệu đưa ra ánh sáng về chủ đề này dưới tiêu đề Thuộc
Kshitij Dhyani

Câu trả lời:


242

Các giá trị và phương thức tính toán rất khác nhau trong Vue và chắc chắn không thể thay thế cho nhau trong hầu hết các trường hợp.

Tài sản tính toán

Tên thích hợp hơn cho giá trị được tính là thuộc tính được tính . Trong thực tế, khi Vue được khởi tạo, các thuộc tính được tính toán được chuyển đổi thành thuộc tính của Vue với getter và đôi khi là setter. Về cơ bản, bạn có thể nghĩ về một giá trị được tính là giá trị dẫn xuất sẽ được cập nhật tự động bất cứ khi nào một trong các giá trị cơ bản được sử dụng để tính toán nó được cập nhật. Bạn không gọi một máy tính và nó không chấp nhận bất kỳ tham số nào. Bạn tham chiếu một thuộc tính được tính giống như bạn làm một thuộc tính dữ liệu. Đây là ví dụ kinh điển từ tài liệu :

computed: {
  // a computed getter
  reversedMessage: function () {
    // `this` points to the vm instance
    return this.message.split('').reverse().join('')
  }
}

Được tham chiếu trong DOM như thế này:

<p>Computed reversed message: "{{ reversedMessage }}"</p>

Các giá trị được tính toán rất có giá trị để thao tác dữ liệu tồn tại trên Vue của bạn. Bất cứ khi nào bạn muốn lọc hoặc chuyển đổi dữ liệu của mình, thông thường bạn sẽ sử dụng giá trị được tính cho mục đích đó.

data:{
    names: ["Bob", "Billy", "Mary", "Jane"]
},
computed:{
    startsWithB(){
        return this.names.filter(n => n.startsWith("B"))
    }
}

<p v-for="name in startsWithB">{{name}}</p>

Các giá trị được tính toán cũng được lưu trong bộ nhớ cache để tránh tính toán lặp lại một giá trị không cần tính lại khi nó không thay đổi (ví dụ như nó có thể không nằm trong một vòng lặp).

phương pháp

Một phương thức chỉ là một hàm ràng buộc với thể hiện Vue. Nó sẽ chỉ được đánh giá khi bạn gọi nó một cách rõ ràng. Giống như tất cả các hàm javascript, nó chấp nhận các tham số và sẽ được đánh giá lại mỗi lần nó được gọi. Các phương thức rất hữu ích trong cùng một tình huống, bất kỳ hàm nào cũng hữu ích.

data:{
    names: ["Bob", "Billy", "Mary", "Jane"]
},
computed:{
    startsWithB(){
        return this.startsWithChar("B")
    },
    startsWithM(){
        return this.startsWithChar("M")
    }
},
methods:{
    startsWithChar(whichChar){
        return this.names.filter(n => n.startsWith(whichCharacter))
    }
}

Tài liệu của Vue thực sự tốt và dễ dàng truy cập. Tôi khuyến khích điều đó.


1
nếu có hai đầu vào từ người dùng như chuyển đổi nhiệt độ từ c sang f và ngược lại trong đó cả hai đầu vào có thể xác định giá trị của nhau. Xem albireo.ch/temperatureconverter và hai đầu vào tự động phản ứng mà không cần nhấn nút chuyển đổi. cái nào là phù hợp nhất để sử dụng tính toán hoặc phương pháp?
Bootstrap4

2
Với giao diện người dùng cụ thể đó với mối quan hệ vòng tròn giữa các đầu vào, tôi sẽ đi với các phương thức. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert

2
@ Bootstrap4 Mặc dù, đây là một cái có tính toán tốt, nhưng nó phức tạp hơn. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert

3
> Một phương thức ... sẽ chỉ được đánh giá khi bạn gọi nó một cách rõ ràng. Không theo video này: youtube.com/watch?v=O14qJr5sKXo
Cameron Hudson

2
@CameronHudson Trong ví dụ trong video, các phương thức được đánh giá vì chúng được tham chiếu rõ ràng trong mẫu . Dưới đây là một ví dụ chứng minh sự khác biệt . Lưu ý rằng các phương thức chỉ được gọi khi dữ liệu thay đổi nếu chúng được tham chiếu rõ ràng trong mẫu.
Bert

60

Khi @gleenk yêu cầu một ví dụ thực tế để làm rõ bộ đệm và sự khác biệt phụ thuộc giữa các phương thức và thuộc tính được tính toán, tôi sẽ hiển thị một kịch bản đơn giản:

app.js

new Vue({
    el: '#vue-app',
    data: {
        a: 0,
        b: 0,
        age: 20
    },
    methods: {
        addToAmethod: function(){
            console.log('addToAmethod');
            return this.a + this.age;
        },
        addToBmethod: function(){
            console.log('addToBmethod');
            return this.b + this.age;
        }
    },
    computed: {
        addToAcomputed: function(){
            console.log('addToAcomputed');
            return this.a + this.age;
        },
        addToBcomputed: function(){
            console.log('addToBcomputed');
            return this.b + this.age;
        }
    }
});

Ở đây chúng ta có 2 phương thức và 2 thuộc tính được thực hiện cùng một nhiệm vụ. Các phương thức addToAmethod& addToBmethodvà các thuộc tính được tính toán addToAcomputed& addToBcomputedtất cả thêm +20 (tức là agegiá trị) vào ahoặc b. Về các phương thức, cả hai đều được gọi mỗi khi một hành động được thực hiện trên bất kỳ thuộc tính được liệt kê nào, ngay cả khi các phụ thuộc cho một phương thức cụ thể không thay đổi. Đối với các thuộc tính được tính toán, mã chỉ được thực thi khi thay đổi phụ thuộc; ví dụ: một trong các giá trị thuộc tính cụ thể liên quan đến A hoặc B sẽ kích hoạt addToAcomputedhoặc addToBcomputed, tương ứng.

Phương pháp và mô tả tính toán có vẻ khá giống nhau, nhưng vì @Abdullah Khan đã chỉ định nó, chúng không giống nhau ! Bây giờ chúng ta hãy thử thêm một số html để thực hiện mọi thứ cùng nhau và xem sự khác biệt ở đâu.

Bản demo trường hợp Phương thức

new Vue({
    el: '#vue-app',
    data: {
        a: 0,
        b: 0,
        age: 20
    },
    methods: {
        addToAmethod: function(){
            console.log('addToAmethod');
            return this.a + this.age;
        },
        addToBmethod: function(){
            console.log('addToBmethod');
            return this.b + this.age;
        }
    }
});
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>VueJS Methods - stackoverflow</title>
            <link href="style.css" rel="stylesheet" />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
    
        </head>
        <body>
            <div id="vue-app">
                <h1>Methods</h1>
                <button v-on:click="a++">Add to A</button>
                <button v-on:click="b++">Add to B</button>
                <p>Age + A = {{ addToAmethod() }}</p>
                <p>Age + B = {{ addToBmethod() }}</p>
            </div>
        </body>
        
        <script src="app.js"></script>
    </html>

Kết quả được giải thích

Khi tôi nhấp vào nút "Thêm vào A" , tất cả các phương thức được gọi (xem kết quả màn hình nhật ký giao diện điều khiển ở trên), addToBmethod()cũng được thực hiện nhưng tôi đã không nhấn nút "Thêm vào B" ; giá trị tài sản đề cập đến B không thay đổi. Hành vi tương tự cũng xảy ra nếu chúng ta quyết định nhấp vào nút "Thêm vào B" , bởi vì một lần nữa cả hai phương thức sẽ được gọi độc lập với các thay đổi phụ thuộc. Theo kịch bản này, đây là thực tế tồi vì chúng tôi đang thực hiện các phương thức mọi lúc, ngay cả khi sự phụ thuộc không thay đổi. Điều này thực sự tiêu tốn tài nguyên vì không có bộ đệm cho các giá trị thuộc tính không thay đổi.

phương pháp phương pháp nút

Bản demo trường hợp thuộc tính

new Vue({
    el: '#vue-app',
    data: {
        a: 0,
        b: 0,
        age: 20
    },

    computed: {
        addToAcomputed: function(){
            console.log('addToAcomputed');
            return this.a + this.age;
        },
        addToBcomputed: function(){
            console.log('addToBcomputed');
            return this.b + this.age;
        }
    }
});
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>VueJS Computed properties - stackoverflow</title>
            <link href="style.css" rel="stylesheet" />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
        </head>
        <body>
            <div id="vue-app">
                <h1>Computed Properties</h1>
                <button v-on:click="a++">Add to A</button>
                <button v-on:click="b++">Add to B</button>
                <p>Age + A = {{ addToAcomputed }}</p>
                <p>Age + B = {{ addToBcomputed }}</p>
            </div>
        </body>
        
        <script src="app.js"></script>
    </html>

Kết quả được giải thích

Khi tôi nhấp vào nút "Thêm vào A" , chỉ thuộc tính được tính addToAcomputedđược gọi bởi vì, như chúng tôi đã nói, các thuộc tính được tính chỉ được thực hiện khi thay đổi phụ thuộc. Và vì tôi đã không nhấn nút "Thêm vào B" và giá trị thuộc tính tuổi cho B không thay đổi, không có lý do gì để gọi và thực hiện thuộc tính được tính addToBcomputed. Vì vậy, theo một nghĩa nào đó, thuộc tính được tính đang duy trì giá trị "không thay đổi" cho thuộc tính B giống như một loại bộ đệm. Và trong trường hợp này, điều này được coi là thực hành tốt .

tính toán nút tính toán


3
Tại sao tất cả các phương thức được thực thi khi nhấn 1 nút? Lý do / logic là gì?
Bsienn

1
@Bsienn đó là một câu hỏi hay: lý do là về cơ bản Vue không biết một trong những phương thức cần chạy tùy thuộc vào những gì đã cập nhật. Và đây là loại hoạt động mà các thuộc tính tính toán thực hiện, chúng xem các biến cần được tính toán hoặc tính toán lại và chúng chỉ chạy khi cần.
Giulio Bambini

2
Và những lý do để sử dụng phương pháp là gì? Có vẻ như các thuộc tính được tính toán chỉ tốt hơn (giả sử chúng ta đang nói về các phương thức 'get') ...
user3529607

5
@ user3529607 nhưng các thuộc tính được tính không nhận được đối số.
Rodion Golovushkin

3
@ user3529607 Từ những gì tôi có thể hiểu, các phương thức có thể hữu ích trong khi gắn hoặc tạo thể hiện của vue. Tương tự không thể được thực hiện với các thuộc tính được tính toán. Ngoài ra, chúng ta phải trả về giá trị cho các thuộc tính được tính toán.
Dhaval Chheda

13

Từ docs

.. các thuộc tính được tính toán được lưu trữ dựa trên các phụ thuộc của chúng. Một thuộc tính được tính toán sẽ chỉ đánh giá lại khi một số phụ thuộc của nó đã thay đổi.

Nếu bạn muốn dữ liệu được lưu vào bộ nhớ cache, hãy sử dụng các thuộc tính được tính toán nếu bạn không muốn dữ liệu được lưu vào bộ nhớ cache, hãy sử dụng các thuộc tính Phương thức đơn giản.


1
Xin chào, bạn có thể viết một ví dụ hữu ích để thể hiện sự khác biệt trong sử dụng thực tế không?
Davide De Maestri

@gleenk Tôi sẽ thêm một ví dụ thực tế để cho bạn thấy sự khác biệt về bộ đệm / bộ đệm này giữa các phương thức và các thuộc tính được tính toán. Tôi hy vọng bạn sẽ đánh giá cao nó.
Giulio Bambini

Cảm ơn bạn @GiulioBambini
Davide De Maestri

7

Một trong những khác biệt giữa tính toán và phương pháp. Giả sử chúng ta có một hàm sẽ trả về giá trị bộ đếm. (Bộ đếm chỉ là biến). Chúng ta hãy xem cách hàm hoạt động trong cả tính toánphương thức

Tính toán

Ở lần đầu tiên thực thi, mã bên trong hàm sẽ được thực thi và vuejs sẽ lưu giá trị bộ đếm trong bộ đệm (để truy cập nhanh hơn). Nhưng khi chúng ta gọi lại hàm thì vuejs sẽ không thực thi lại mã được viết bên trong hàm đó. Đầu tiên, nó kiểm tra bất kỳ thay đổi được thực hiện cho bộ đếm hay không. Nếu có bất kỳ thay đổi nào được thực hiện thì chỉ có nó sẽ thực thi lại mã nằm trong hàm đó. Nếu không có thay đổi được thực hiện cho bộ đếm vuejs sẽ không thực hiện lại chức năng. Nó chỉ đơn giản sẽ trả về kết quả trước đó từ bộ đệm.

phương pháp

Đây giống như một phương thức bình thường trong javascript. Bất cứ khi nào chúng ta gọi phương thức, nó sẽ luôn thực thi mã bên trong hàm bất kể các thay đổi được thực hiện đối với bộ đếm.

Phương thức sẽ luôn kiểm tra lại mã bất kể các thay đổi trong mã. khi được tính toán sẽ kiểm tra lại mã sau đó chỉ khi một trong các giá trị phụ thuộc của nó thay đổi. Nếu không, nó sẽ cho chúng ta kết quả trước đó từ bộ đệm mà không cần thực hiện lại


6

Đây là một sự cố của câu hỏi này.

Khi nào sử dụng phương pháp

  • Để phản ứng với một số sự kiện xảy ra trong DOM
  • Để gọi một chức năng khi một cái gì đó xảy ra trong thành phần của bạn.
  • Bạn có thể gọi một phương thức từ các thuộc tính hoặc trình theo dõi.

Khi nào nên sử dụng thuộc tính

  • Bạn cần soạn dữ liệu mới từ các nguồn dữ liệu hiện có
  • Bạn có một biến bạn sử dụng trong mẫu được tạo từ một hoặc nhiều thuộc tính dữ liệu
  • Bạn muốn giảm một tên thuộc tính phức tạp, lồng nhau thành một tên dễ đọc và dễ sử dụng hơn (nhưng cập nhật nó khi thuộc tính ban đầu thay đổi)
  • Bạn cần tham chiếu một giá trị từ mẫu. Trong trường hợp này, tạo một thuộc tính được tính toán là điều tốt nhất, bởi vì nó được lưu trữ.
  • Bạn cần lắng nghe những thay đổi của nhiều thuộc tính dữ liệu

2

Thuộc tính

Các thuộc tính được gọi là giá trị tính toán là tốt. Nó có nghĩa là, họ cập nhật và có thể được thay đổi bất cứ lúc nào. Ngoài ra, nó lưu trữ dữ liệu cho đến khi nó thay đổi. Khi Vue được khởi tạo, các thuộc tính được tính sẽ được chuyển đổi thành thuộc tính.

Một điều nữa tôi muốn chia sẻ, Bạn không thể vượt qua bất kỳ tham số nào trong các thuộc tính được tính toán đó là lý do tại sao trong khi gọi bất kỳ thuộc tính máy tính nào không cần dấu ngoặc đơn.

Phương pháp

Các phương thức giống như chức năng và hoạt động theo cùng một cách. Bên cạnh đó, một phương thức không làm gì trừ khi bạn gọi nó. Ngoài ra, giống như tất cả các hàm javascript, nó chấp nhận các tham số và sẽ được đánh giá lại mỗi lần nó được gọi. Sau đó, họ không thể lưu các giá trị bộ đệm

Trong phương thức gọi dấu ngoặc đơn là có và bạn có thể gửi một hoặc nhiều tham số trong đó.


0

Tình cờ gặp phải câu hỏi tương tự. Đối với tôi nó rõ ràng hơn như thế này:

  1. Khi Vue.js thấy v-on directivetheo sau bởi một phương thức, nó biết chính xác nên gọi phương thức nào và khi nào gọi nó.
<button v-on:click="clearMessage">Clear message</button> // @click
// method clearMessage is only called on a click on this button

<input v-model="message" @keyup.esc="clearMessage" @keyup.enter="alertMessage" />
/* The method clearMessage is only called on pressing the escape key
and the alertMessage method on pressing the enter key */
  1. Khi một phương thức được gọi mà không cóv-on directive phương thức đó sẽ được gọi mỗi khi một sự kiện được kích hoạt trên trang cập nhật DOM (hoặc chỉ cần hiển thị lại một phần của trang). Ngay cả khi phương thức đó không liên quan gì đến sự kiện được kích hoạt.
<p>Uppercase message: {{ messageUppercase() }}</p>
methods: {
   messageUppercase() {
      console.log("messageUpercase");
      return this.message.toUpperCase();
   }
}
/* The method `messageUppercase()` is called on every button click, mouse hover 
or other event that is defined on the page with the `v-on directive`. So every
time the page re-renders.*/
  1. Thuộc tính được tính chỉ được gọi khi giá trị thuộc tính được thay đổi đang được tham chiếu bởi thistừ trong định nghĩa hàm của nó.
<p>Uppercase message: {{ messageUppercase }}</p> 
data() {
 return {
    message: "I love Vue.js"
   }
 },
computed: {
 messageUppercase() {
    console.log("messageUpercase");
    return this.message.toUpperCase();
 }
}
/* The computed property messageUppercase is only called when the propery message is
changed. Not on other events (clicks, mouse hovers,..) unless of course a specific 
event changes the value of message.  */

Điều đáng nói ở đây là cách tốt nhất để sử dụng các computedthuộc tính trong trường hợp phương thức không được gọi với v-on directive.

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 cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.