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.
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.
Câu trả lời:
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 đó.
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:
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
& addToBmethod
và các thuộc tính được tính toán addToAcomputed
& addToBcomputed
tất cả thêm +20 (tức là age
giá trị) vào a
hoặ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 addToAcomputed
hoặ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.
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>
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.
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>
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ừ 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.
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án và phươ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
Đây là một sự cố của câu hỏi này.
Khi nào sử dụng phương pháp
Khi nào nên sử dụng thuộc tính
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 đó.
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:
v-on directive
theo 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 */
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.*/
this
từ 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 computed
thuộc tính trong trường hợp phương thức không được gọi với v-on directive
.