メソッド対Vueで計算


178

Vue.jsのメソッドと計算値の主な違いは何ですか?

それらは同じように見え、交換可能です。


多分あなたに役立つでしょう:vuejs.org/v2/guide/computed.html#Computed-Properties
DunDev

1
@xDreamCodingあなたがリンクする答えはたまたまこの質問に対処しますが、この質問は決して重複ではありません。さらに、それはより有名です。
Romain Vincent

計算されたプロパティとメソッドの見出しの下で、このトピックについていくつかの光を投げるドキュメントを参照してください:vuejs.org/v2/guide/computed.html
Kshitij Dhyani

回答:


242

計算された値とメソッドはVueで大きく異なり、ほとんどの場合、互換性はありません。

計算されたプロパティ

計算値のより適切な名前は、計算プロパティです。実際、Vueがインスタンス化されると、計算されたプロパティはゲッターと、場合によってはセッターを使用してVueのプロパティに変換されます。基本的に、計算値は、計算に使用される基になる値の1つが更新されるたびに自動的に更新される派生値と考えることができます。あなたはしていない呼び出して計算し、それが任意のパラメータを受け付けません。データプロパティと同じように計算プロパティを参照します。ここにドキュメントの古典的な例があります

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

これは、次のようにDOMで参照されます。

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

計算された値は、Vueに存在するデータを操作するのに非常に役立ちます。データをフィルタリングまたは変換する場合は、通常、その目的のために計算値を使用します。

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

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

計算された値は、変更されていないときに再計算する必要のない値を繰り返し計算することを避けるためにキャッシュされます(たとえば、ループにない場合があるため)。

方法

メソッドは、Vueインスタンスにバインドされた関数です。明示的に呼び出す場合にのみ評価されます。すべてのJavaScript関数と同様に、パラメーターを受け入れ、呼び出されるたびに再評価されます。メソッドは、あらゆる機能が役立つ同じ状況で役立ちます。

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

Vueのドキュメントは非常に優れており、簡単にアクセスできます。私はそれをお勧めします。


1
cからfへの温度変換のようなユーザーからの2つの入力があり、両方の入力が互いの値を決定できる場合は、その逆も同様です。albireo.ch/temperatureconverterを参照してください。変換ボタンを押さなくても2つの入力が自動的に反応します。計算またはメソッドを使用するのに最適なのはどれですか?
Bootstrap4 2017年

2
それに特定の入力間の円形の関係で、私は方法となるだろうUI。codepen.io/Kradek/pen/gROQeB?editors=1010
Bert

2
@ Bootstrap4ただし、これも計算されたものですが、より複雑です。codepen.io/Kradek/pen/gROQeB?editors=1010
Bert

3
>メソッド...は、明示的に呼び出す場合にのみ評価されます。このビデオによらない:youtube.com/watch
Cameron Hudson

2
@CameronHudsonビデオ内の例では、テンプレートで明示的に参照されているため、メソッドが評価されます。これが違いを示す例です。方法は、データのみが変化したときに呼ばれていることに注意してください場合は、明示的にテンプレートで参照されています。
バート

60

@gleenkが、メソッドと計算されたプロパティの間のキャッシュと依存関係の違いを明確にするための実用的な例を求めたので、簡単なシナリオを示します。

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

ここには、同じタスクを実行する2つのメソッドと2つの計算されたプロパティがあります。メソッドaddToAmethodaddToBmethodおよび計算されたプロパティaddToAcomputedaddToBcomputedすべてに+20が追加されます(つまり、ageaまたはに値)をしますb。メソッドに関しては、いずれかのアクションが実行されるたびに両方呼び出されます、1つの特定のメソッドの依存関係が変更されていなくても、リストされているプロパティのでれます。計算されたプロパティの場合、コードは依存関係が変更されたときにのみ実行されます。たとえば、AまたはBを参照する特定のプロパティ値の1つは、それぞれ、addToAcomputedまたはをトリガーしaddToBcomputedます。

メソッドと計算された説明はかなり似ているようですが、@ Abdullah Khanがすでに指定しているようにているため、同じではありません!次に、いくつかのhtmlを追加してすべてを一緒に実行し、違いがどこにあるかを確認してみましょう。

メソッドケースデモ

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>

説明された結果

「Add to A」ボタンをクリックすると、すべてのメソッドが呼び出され(上記のコンソールログ画面の結果を参照)、それaddToBmethod()も実行されますが、「Add to B」ボタン押しませんでした。Bを参照するプロパティ値は変更されていません。「Bに追加」ボタンをクリックすると、同じ動作になります。これも、両方のメソッドが依存関係の変更とは無関係に呼び出されるためです。このシナリオによれば、依存関係が変更されていない場合でも毎回メソッドを実行しているため、これは悪い習慣です。変更されていないプロパティ値のキャッシュがないため、これは実際にリソースを消費します。

方法 ボタン方式

計算されたプロパティケースのデモ

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>

説明された結果

「Aに追加」ボタンをクリックすると、計算されたプロパティのみaddToAcomputedが呼び出されます。これは、すでに述べたように、計算されたプロパティは依存関係が変更された場合にのみ実行されるためです。また、「Bに追加」ボタンを押さなかったため、Bの年齢プロパティ値は変更されていないため、計算されたプロパティを呼び出して実行する理由はありませんaddToBcomputed。したがって、ある意味では、計算されたプロパティは、一種のキャッシュのように、Bプロパティの「変更されていない」値を維持しています。そして、この状況では、これは良い習慣と考えられます。

計算された 計算されたボタン


3
1つのボタンが押されたときにすべてのメソッドが実行されるのはなぜですか?理由/ロジックは何ですか?
Bsienn

1
@Bsiennこれは良い質問です。理由は、基本的にVueが、更新された内容に応じて実行する必要があるメソッドの1つを知らないためです。これは、計算されたプロパティが行う種類の操作であり、計算または再計算する必要のある変数を監視し、必要な場合にのみ実行されます。
ジュリオバンビーニ2018

2
そして、メソッドを使用する理由は何ですか?計算されたプロパティの方が優れているようです( 'get'メソッドについて話していると仮定した場合)...
user3529607

5
@ user3529607しかし、計算されたプロパティは引数を受け取りません。
Rodion Golovushkin、2018年

3
@ user3529607私が理解できることから、Vueのインスタンスをマウントまたは作成するときにメソッドが役立つ場合があります。同じことは、計算されたプロパティでは実行できません。また、計算されたプロパティの値を返す必要があります。
Dhaval Chheda

13

から docs

..computedプロパティは、依存関係に基づいてキャッシュされます。計算されたプロパティは、依存関係の一部が変更された場合にのみ再評価されます。

一方、データをキャッシュしたい場合はComputedプロパティを使用し、データをキャッシュしたくない場合は単純なMethodプロパティを使用します。


1
こんにちは、実用的な違いを示すのに役立つ例を書いていただけますか?
Davide De Maestri 2017

@gleenkメソッドと計算されたプロパティの間のこのキャッシュ/依存関係の違いを示すための実用的な例を追加します。よろしくお願いします。
ジュリオバンビーニ2018年

ありがとう@GiulioBambini
Davide De Maestri

7

計算とメソッドの違いの1つ。カウンター値を返す関数があるとします(カウンターは単なる変数です)。計算メソッドの両方で関数がどのように動作するかを見てみましょう

計算済み

最初の実行時に、関数内のコードが実行され、vuejsがカウンター値をキャッシュに格納します(より高速にアクセスするため)。しかし、再び関数を呼び出すとき、vuejsはその関数内に記述されたコードを再度実行しません。まず、カウンターに加えられた変更をチェックします。何らかの変更が行われた場合、その関数内にあるコードのみが再実行されます。カウンターに変更が加えられていない場合、vuejsは関数を再度実行しません。単にキャッシュから前の結果を返します。

方法

これは、JavaScriptの通常のメソッドと同じです。メソッドを呼び出すときはいつでも、カウンターに加えられた変更に関係なく、常に関数内のコードを実行します。

メソッドは、コードの変更に関係なく、常にコードを再実行します。ここで、計算されると、依存関係の値の1つが変更された場合にのみ、コードが再実行されます。それ以外の場合は、再実行せずにキャッシュから以前の結果を取得します


6

これがこの質問の内訳です。

メソッドを使用する場合

  • DOMで発生するイベントに対応するには
  • コンポーネントで何かが発生したときに関数を呼び出す。
  • 計算されたプロパティまたはウォッチャーからメソッドを呼び出すことができます。

計算されたプロパティを使用する場合

  • 既存のデータソースから新しいデータを作成する必要がある
  • 1つ以上のデータプロパティから構築されたテンプレートで使用する変数があります
  • 複雑でネストされたプロパティ名を読みやすく、使いやすい名前に減らしたい(ただし、元のプロパティが変更されたときに更新する)
  • テンプレートから値を参照する必要があります。この場合、計算されたプロパティはキャッシュされるため、作成することをお勧めします。
  • 複数のデータプロパティの変更をリッスンする必要がある

2

計算されたプロパティ

計算されたプロパティは計算値とも呼ばれます。つまり、更新され、いつでも変更できます。また、変更されるまでデータをキャッシュします。Vueがインスタンス化されると、計算されたプロパティはプロパティに変換されます。

共有したいもう1つのことは、計算されたプロパティにパラメーターを渡すことができないためです。これは、コンピューターのプロパティを呼び出すときに、かっこは必要ないためです。

方法

メソッドは関数と同じであり、同じように機能します。また、メソッドは、呼び出さない限り何もしません。また、すべてのjavascript関数と同様に、パラメーターを受け入れ、呼び出されるたびに再評価されます。その後、値をキャッシュできません

かっこを呼び出すメソッドにあり、そこに1つ以上のパラメーターを送信できます。


0

同じ質問に出くわした。私にはそれはこのようにもっと明確です:

  1. Vue.jsは、v-on directive後続のメソッドを検出すると、呼び出すメソッドと呼び出すタイミングを正確に認識します。
<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. メソッドを呼び出さv-on directiveに呼び出すと、DOMを更新する(または単にページの一部を再レンダリングする必要がある)ページでイベントがトリガーされるたびに呼び出さます。そのメソッドがトリガーされるイベントとは関係がない場合でもです。
<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. 計算されたプロパティは、その関数定義内の単語によって参照されているプロパティ値が変更されたときにのみ呼び出されます。this
<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.  */

ここで重要なのはcomputed、メソッドがで呼び出されていない場合に備えて、プロパティを使用することがベストプラクティスであることv-on directiveです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.