विधि बनाम गणना


178

Vue.js में एक विधि और एक गणना मूल्य के बीच मुख्य अंतर क्या है?

वे समान और विनिमेय दिखते हैं।


हो सकता है कि आपके लिए उपयोगी हो: vuejs.org/v2/guide/computed.html#Computed-Properties
डंडदेव

1
@xDreamCoding इस प्रश्न को संबोधित करने के लिए आपके द्वारा लिंक किया गया उत्तर वास्तव में होता है, लेकिन किसी भी तरह से यह प्रश्न दोहराव नहीं है। साथ ही यह अधिक प्रसिद्ध है।
रोमेन विंसेंट

प्रलेखन का संदर्भ लें जो इस विषय पर कुछ संपत्तियों की गणना बनाम विधियों के तहत कुछ प्रकाश फेंकता है: vuejs.org/v2/guide/computed.html
क्षितिज ध्यानी

जवाबों:


242

गणना किए गए मान और विधियाँ Vue में बहुत भिन्न हैं और अधिकांश मामलों में निश्चित रूप से विनिमेय नहीं हैं।

गणना की गई संपत्ति

एक गणना मूल्य के लिए एक अधिक उपयुक्त नाम एक गणना की गई संपत्ति है । वास्तव में, जब Vue को तत्काल किया जाता है, तो गणना किए गए गुणों को एक गटर और कभी-कभी एक सेटर के साथ Vue की संपत्ति में परिवर्तित किया जाता है। मूल रूप से आप एक गणना मूल्य को एक व्युत्पन्न मान के रूप में सोच सकते हैं जो कि जब भी गणना करने के लिए उपयोग किए गए अंतर्निहित मूल्यों में से एक को स्वचालित रूप से अपडेट किया जाएगा। आप एक गणना नहीं कहते हैं और यह किसी भी पैरामीटर को स्वीकार नहीं करता है। आप एक गणना की गई संपत्ति को उसी तरह संदर्भित करते हैं जैसे आप एक डेटा संपत्ति चाहते हैं। यहाँ प्रलेखन से क्लासिक उदाहरण है :

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

इस तरह डोम में संदर्भित है:

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

कम्प्यूटेड वैल्यू आपके वीयू पर मौजूद डेटा में हेरफेर करने के लिए बहुत मूल्यवान हैं। जब भी आप अपने डेटा को फ़िल्टर या बदलना चाहते हैं, तो आमतौर पर आप उस उद्देश्य के लिए एक गणना मूल्य का उपयोग करेंगे।

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 उदाहरण के लिए एक फ़ंक्शन है। इसका मूल्यांकन केवल तब होगा जब आप इसे स्पष्ट रूप से कहेंगे। सभी जावास्क्रिप्ट फ़ंक्शंस की तरह यह मापदंडों को स्वीकार करता है और हर बार इसे फिर से मूल्यांकन किया जाएगा। विधियाँ उन्हीं स्थितियों में उपयोगी होती हैं जब कोई कार्य उपयोगी होता है।

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 और इसके विपरीत तापमान रूपांतरण जहां दोनों इनपुट एक दूसरे का मान निर्धारित कर सकते हैं। देखें albireo.ch/temperatureconverter और दो आदानों परिवर्तित बटन दबाए बिना स्वचालित रूप से प्रतिक्रिया करता है। गणना या विधियों का उपयोग करने के लिए कौन सा सबसे अच्छा है?
बूटस्ट्रैप

2
उस विशिष्ट UI के साथ जहां इनपुट्स के बीच परिपत्र संबंध के साथ, मैं विधियों के साथ जाऊंगा। codepen.io/Kradek/pen/gROQeB?editors=1010
बर्ट

2
@ बूटस्ट्रैप 4 हालांकि, यहां एक गणना के साथ एक है, लेकिन इसकी अधिक जटिल है। codepen.io/Kradek/pen/gROQeB?editors=1010
बर्ट

3
> एक विधि ... केवल तब मूल्यांकन किया जाएगा जब आप इसे स्पष्ट रूप से कहते हैं। इस वीडियो के अनुसार नहीं: youtube.com/watch?v=O14qJr5sKXo
कैमरून हडसन

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 संगणित गुण हैं जो समान कार्य करते हैं। विधियाँ addToAmethodऔर addToBmethodसंगणित गुण addToAcomputedऔर addToBcomputedसभी जोड़ते हैं +20 (यानी ageमान) aया तो b। विधियों के संबंध में, वे दोनों को हर बार बुलाया जाता है जब किसी भी सूचीबद्ध गुणों पर कार्रवाई की गई हो , भले ही एक विशिष्ट विधि के लिए निर्भरताएं नहीं बदली गई हों। गणना की गई संपत्तियों के लिए, कोड को केवल तभी निष्पादित किया जाता है जब एक निर्भरता बदल गई हो; उदाहरण के लिए, ए या बी को संदर्भित करने वाले विशिष्ट संपत्ति मूल्यों में से एक क्रमशः ट्रिगर addToAcomputedया addToBcomputed, होगा।

विधि और संगणित विवरण बहुत समान लगते हैं, लेकिन जैसा कि @ अब्दुल्ला खान ने पहले ही निर्दिष्ट कर दिया है, वे एक ही बात नहीं हैं ! अब सब कुछ एक साथ निष्पादित करने के लिए कुछ 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 को संदर्भित करने वाला गुण मान परिवर्तित नहीं हुआ है। यदि हम "ऐड टू बी" बटन पर क्लिक करने का निर्णय लेते हैं तो एक ही व्यवहार आता है , क्योंकि फिर से दोनों तरीकों को स्वतंत्र रूप से निर्भरता परिवर्तन कहा जाएगा। इस परिदृश्य के अनुसार यह बुरा व्यवहार है क्योंकि हम हर बार तरीकों को अंजाम दे रहे हैं, भले ही निर्भरताएं नहीं बदली हैं। यह वास्तव में संसाधन खपत है क्योंकि संपत्ति के मूल्यों के लिए कैश नहीं है जो बदल नहीं गए हैं।

तरीका बटन विधि

कम्प्यूटेड संपत्ति केस डेमो

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>

समझाया गया परिणाम

जब मैं "एक में जोड़ें" बटन पर क्लिक करता हूं , तो केवल गणना की गई संपत्ति addToAcomputedको बुलाया जाता है, क्योंकि जैसा कि हमने पहले ही कहा था, गणना की गई संपत्तियों को केवल तभी निष्पादित किया जाता है जब एक निर्भरता बदल गई हो। और जब से मैंने "एड टू बी" बटन नहीं दबाया और बी के लिए आयु संपत्ति मूल्य नहीं बदला है, तो गणना की गई संपत्ति को कॉल करने और निष्पादित करने का कोई कारण नहीं है addToBcomputed। इसलिए, एक निश्चित अर्थ में, गणना की गई संपत्ति एक प्रकार के कैश की तरह बी संपत्ति के लिए "समान अपरिवर्तित" मूल्य बनाए रख रही है। और इस परिस्थिति में यह अच्छा अभ्यास माना जाता है

गणना बटन गणना


3
जब 1 बटन दबाया जाता है तो सभी तरीके क्यों निष्पादित होते हैं? कारण / तर्क क्या है?
बाइसन

1
@Bennenn यह एक अच्छा सवाल है: कारण यह है कि मूल रूप से Vue को नहीं पता है कि अपडेट किए गए तरीकों के आधार पर तरीकों में से एक को चलाने की आवश्यकता है। और यह इस तरह के ऑपरेशन हैं जो संपत्तियों की गणना करते हैं, वे उन चर को देखते हैं जिनकी गणना या पुनर्गणना करने की आवश्यकता होती है और वे केवल तब चलते हैं जब जरूरत होती है।
ग्यूलियो बम्बिनी

2
और तरीकों का उपयोग करने के कारण क्या हैं? ऐसा लगता है कि गणना किए गए गुण बस बेहतर हैं (यह मानते हुए कि हम 'पाने' के तरीकों के बारे में बात कर रहे हैं) ...
user3529607

5
@ user3529607 लेकिन गणना किए गए गुण तर्क प्राप्त नहीं करते हैं।
रोडियन गोलोवुस्किन

3
@ user3529607 जो मैं समझ सकता हूं, वे विधि से बढ़ते या वाउ का उदाहरण बनाते समय उपयोगी हो सकते हैं। गणना संपत्तियों के साथ नहीं की जा सकती। साथ ही, हमें गणना किए गए गुणों के लिए मूल्य वापस करना होगा।
धवल छेदा

13

वहाँ से docs

..संबद्ध गुणों को उनकी निर्भरता के आधार पर कैश किया जाता है। एक गणना की गई संपत्ति का केवल तभी मूल्यांकन होगा जब उसकी कुछ निर्भरताएं बदल गई हों।

यदि आप चाहते हैं कि डेटा को कैश्ड उपयोग किया जाए तो दूसरी ओर यदि आप डेटा को कैश्ड उपयोग नहीं करना चाहते हैं तो सरल विधि गुणों का उपयोग करें।


1
नमस्ते, क्या आप व्यावहारिक-उपयोग अंतर दिखाने के लिए एक उपयोगी उदाहरण लिख सकते हैं?
डेविड डी मास्त्री

@gleenk मैं आपको इस कैश / निर्भरता के तरीकों और गणना किए गए गुणों के बीच अंतर दिखाने के लिए एक व्यावहारिक उदाहरण जोड़ूंगा। मुझे आशा है कि आप इसकी सराहना करेंगे।
गियुलियो बम्बिनी

आप @GiulioBambini धन्यवाद
डेविड डी Maestri

7

गणना और विधि के बीच अंतर। मान लीजिए कि हमारे पास एक फ़ंक्शन है जो काउंटर मान लौटाएगा। (काउंटर सिर्फ चर है)। आइए देखें कि गणना और विधि दोनों में कार्य कैसे व्यवहार करता है

संगणित

निष्पादन के पहले समय में फ़ंक्शन के अंदर कोड निष्पादित किया जाएगा और vuejs कैश में काउंटर वैल्यू (तेजी से एक्सेस करने के लिए) को स्टोर करेंगे। लेकिन जब हम फिर से फ़ंक्शन को कॉल कर रहे हैं, तो vuejs उस फ़ंक्शन के अंदर लिखे कोड को फिर से निष्पादित नहीं करेंगे। यह पहले काउंटर पर किए गए किसी भी परिवर्तन की जाँच करता है या नहीं। यदि कोई परिवर्तन किया जाता है, तो केवल उस कोड को फिर से निष्पादित करेगा जो उस फ़ंक्शन के अंदर है। यदि काउंटर में कोई बदलाव नहीं किए गए हैं तो vuejs फिर से फ़ंक्शन को निष्पादित नहीं करेंगे। यह केवल पिछले परिणाम को कैश से लौटाएगा।

तरीका

यह जावास्क्रिप्ट में एक सामान्य विधि की तरह है। जब भी हम विधि को कॉल करते हैं, तो यह फ़ंक्शन के अंदर कोड को हमेशा काउंटर के लिए किए गए परिवर्तनों के बावजूद निष्पादित करेगा।

विधि हमेशा कोड में परिवर्तनों के बावजूद कोड को पुन: व्यवस्थित करेगी। जहां गणना के रूप में कोड reexecute होगा केवल तभी अगर यह निर्भरता के मूल्यों में से एक बदल गया है। अन्यथा यह हमें कैश से बिना किसी परिणाम के पिछले परिणाम देगा


6

यहाँ इस प्रश्न का एक विराम है।

तरीकों का उपयोग कब करें

  • DOM में हो रही कुछ घटना पर प्रतिक्रिया करने के लिए
  • एक फ़ंक्शन को कॉल करने के लिए जब आपके घटक में कुछ होता है।
  • आप गणना की गई संपत्तियों या देखने वालों से एक विधि कह सकते हैं।

गणना किए गए गुणों का उपयोग कब करें

  • आपको मौजूदा डेटा स्रोतों से नए डेटा की रचना करने की आवश्यकता है
  • आपके पास अपने टेम्पलेट में उपयोग किया जाने वाला एक चर है जो एक या अधिक डेटा गुणों से बनाया गया है
  • आप एक जटिल, नेस्टेड संपत्ति का नाम अधिक पठनीय और एक का उपयोग करने के लिए आसान कम करना चाहते हैं (लेकिन मूल संपत्ति में परिवर्तन होने पर इसे अपडेट करें)
  • आपको टेम्पलेट से एक मूल्य को संदर्भित करने की आवश्यकता है। इस मामले में, गणना की गई संपत्ति बनाना सबसे अच्छी बात है, क्योंकि यह कैश है।
  • आपको एक से अधिक डेटा प्रॉपर्टी के बदलावों को सुनना होगा

2

संगणित गुण

संगणित गुणों को संगणित मूल्य भी कहा जाता है। इसका मतलब है, वे अपडेट करते हैं और कभी भी बदले जा सकते हैं। इसके अलावा, यह डेटा को तब तक कैश करता है जब तक कि वह बदल न जाए। जब Vue को तत्काल किया जाता है, तो गणना किए गए गुणों को एक संपत्ति में बदल दिया जाता है।

एक और बात जो मैं साझा करना चाहता हूं, आप गणना किए गए गुणों में किसी भी पैरामीटर को पारित नहीं कर सकते हैं, इसलिए किसी भी कंप्यूटर संपत्ति को कॉल करते समय कोई कोष्ठक आवश्यक नहीं है।

तरीके

कार्यप्रणाली के तरीके समान हैं और उसी तरह काम करते हैं। इसके अलावा, एक विधि तब तक कुछ नहीं करती जब तक आप इसे नहीं बुलाते। इसके अलावा, सभी जावास्क्रिप्ट फ़ंक्शंस की तरह, यह मापदंडों को स्वीकार करता है और हर बार इसका मूल्यांकन करने के बाद फिर से मूल्यांकन किया जाएगा। उसके बाद, वे मूल्यों को कैश नहीं कर सकते

में विधि कोष्ठक बुला रहा है और आप उस में एक या एक से अधिक पैरामीटर भेज सकते हैं।


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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.