क्या मैं Vue.Js में गणना की गई संपत्तियों में पैरामीटर पारित कर सकता हूं


199

क्या यह संभव है कि Vue.Js. मैं देख सकता हूँ कि जब गणना / सेटर का उपयोग करके गणना की जाती है, तो वे एक पैरामीटर ले सकते हैं और इसे एक चर में निर्दिष्ट कर सकते हैं। प्रलेखन से यहाँ की तरह :

// ...
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

क्या यह भी संभव है:

// ...
computed: {
  fullName: function (salut) {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}
// ...

जहां गणना की गई संपत्ति एक तर्क लेती है और वांछित आउटपुट देती है। हालाँकि जब मैं यह कोशिश करता हूँ, मुझे यह त्रुटि मिल रही है:

vue.common.js: 2250 बिना पढ़े टाइपरोर: फुलनाम एक फंक्शन नहीं है (…)

क्या मुझे ऐसे मामलों के लिए तरीकों का उपयोग करना चाहिए?


5
नहीं, आप गणना की गई संपत्तियों के लिए पैरामीटर पारित नहीं कर सकते। हां, विधियों का उपयोग करना सबसे आसान तरीका है।
nils

जवाबों:


267

सबसे शायद आप एक विधि का उपयोग करना चाहते हैं

<span>{{ fullName('Hi') }}</span>

methods: {
  fullName(salut) {
      return `${salut} ${this.firstName} ${this.lastName}`
  }
}

लंबी व्याख्या

तकनीकी रूप से आप इस तरह एक पैरामीटर के साथ एक गणना की गई संपत्ति का उपयोग कर सकते हैं:

computed: {
   fullName() {
      return salut => `${salut} ${this.firstName} ${this.lastName}`
   }
}

(इसके Unirgyलिए आधार कोड के लिए धन्यवाद ।)

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

यदि आपको मापदंडों की आवश्यकता है, तो आमतौर पर इस तरह के मामले में एक विधि पर एक गणना संपत्ति फ़ंक्शन का उपयोग करने का कोई लाभ नहीं है। यद्यपि यह आपको वीयू उदाहरण के लिए पैराट्राइज्ड गेटटर फ़ंक्शन के लिए बाध्य करता है, लेकिन आप कैशिंग खो देते हैं इसलिए वास्तव में कोई लाभ नहीं होता है, वास्तव में, आप प्रतिक्रियाशीलता (AFAIU) को तोड़ सकते हैं। आप इसके बारे में Vue प्रलेखन https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods में अधिक पढ़ सकते हैं

एकमात्र उपयोगी स्थिति तब होती है जब आपको एक गेटर का उपयोग करना होता है और इसे पैरामीट्रिक करने की आवश्यकता होती है। उदाहरण के लिए यह स्थिति Vuex में होती है । Vuex में यह स्टोर से क्रियाओं के परिणाम को समकालिक रूप से प्राप्त करने का एकमात्र तरीका है। इस प्रकार यह दृष्टिकोण आधिकारिक वीयूएक्स प्रलेखन द्वारा इसके गेटर्स https://vuex.vuejs.org/guide/getters.html#method-style-access के लिए सूचीबद्ध है


1
<span v-text="fullName('Hi')"></span>इसके बजाय का उपयोग, भी काम करता है।
साल्चीपापा

2
मुद्दा यह था कि <span :text="message"></span>, अब Vue 2.0 के लिए काम नहीं करता है, किसी को इसके बजाय उपयोग करना है: <span v-text="message"></span>या <span>{{ message }}</span>जैसा कि इस कोडपेन में दिखाया गया है: codepen.io/Ismael-VC/pen/dzGzJa
साल्चीपापा

1
आप सही हे। मैंने यह नहीं देखा कि इसे 2.0 में बदल दिया गया है। सुधारों के लिए धन्यवाद!
डेमियनिक्स

4
गणना किए गए गुण ईएस 5 गेट्टर सिंटैक्स का उपयोग करते हैं जो इसे किसी भी पैरामीटर के साथ कॉल करने का समर्थन नहीं करता है (कोई कोष्ठक नहीं है)। तो यह एक भाषा-स्तरीय सीमा है और इसे Vue.js. में शामिल किया गया है।
डेमियनिक्स

1
बहुत देर से प्रतिक्रिया @PedroMoreira के लिए क्षमा करें, मुझे अभी इसका विश्लेषण करने के लिए कुछ समय मिला है। वास्तव में आप सही हैं कि मैंने जो लिखा था वह स्पष्ट और मिश्रित नहीं था :) मैंने जवाब तय किया और इसे और अधिक स्पष्ट और सटीक बनाने के लिए इसे पुनःप्रकाशित करने की पूरी कोशिश की। यदि आप अभी स्पष्ट हैं तो आप मुझे बता सकते हैं। धन्यवाद।
डेमियनिक्स

27

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

आप इस तरह से गणना की गई संपत्तियों के लिए तर्क पारित कर सकते हैं (दस्तावेज नहीं, लेकिन अनुरक्षकों द्वारा सुझाव दिया गया है, जहां याद नहीं है):

computed: {
   fullName: function () {
      var vm = this;
      return function (salut) {
          return salut + ' ' + vm.firstName + ' ' + vm.lastName;  
      };
   }
}

EDIT: कृपया इस समाधान का उपयोग न करें, यह केवल बिना किसी लाभ के कोड को जटिल बनाता है।


यदि आप एक संदर्भ प्रदान कर सकते हैं तो यह वास्तव में सहायक होगा। यह काम करना चाहिए।
सौरभ

@saurabh खेद है कि यह वास्तव में जीथब में नहीं वर्णनात्मक मुद्दे के लिए एक समाधान था, और मैं इसे अभी नहीं ढूँढ सकता ...
अनिरंगी

यह मेरे लिए काम करता है, लेकिन केवल एक चीज जो मैं प्रशंसक नहीं हूं, वह यह है कि यह वास्तविक संपत्ति के बजाय एक फ़ंक्शन देता है, इसलिए VueJS devtools कहीं भी परिणाम नहीं दिखाता है। मुझे यकीन नहीं है कि अगर यह गणना की गई संपत्तियों के लिए विशिष्ट है, लेकिन यह थोड़ा कठिन समस्या निवारण करता है।
नैट रिटर

4
यह कैशिंग कैसे संभालता है? पैरामीटर बदलने पर क्या यह ठीक से काम करेगा?
डेमियनिक्स

मुझे विश्वास नहीं है कि यह रिटर्न फ़ंक्शन के अंदर कुछ भी कैश करेगा। विधियों का अंतर विशुद्ध रूप से कन्वेंशन का होगा (तरीकों का प्रभाव होता है, गणना केवल पुनर्प्राप्ति के लिए होती है)
Unirgy

8

ठीक है, तकनीकी रूप से हम एक पैरामीटर को एक गणना फ़ंक्शन में पास कर सकते हैं, उसी तरह हम एक पैरामीटर को वीएक्सएक्स में एक गेट्टर फ़ंक्शन को पास कर सकते हैं। ऐसा फंक्शन एक फंक्शन होता है जो एक फंक्शन लौटाता है।

उदाहरण के लिए, किसी स्टोर के गेटर्स में:

{
  itemById: function(state) {
    return (id) => state.itemPool[id];
  }
}

इस गेटर को एक घटक के गणना कार्यों के लिए मैप किया जा सकता है:

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ])
}

और हम अपने टेम्पलेट में इस गणना किए गए फ़ंक्शन का उपयोग कर सकते हैं:

<div v-for="id in ids" :key="id">{{itemById(id).description}}</div>

हम एक समान पद्धति बनाने के लिए एक ही दृष्टिकोण लागू कर सकते हैं जो एक पैरामीटर लेता है।

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ]),
  descriptionById: function() {
    return (id) => this.itemById(id).description;
  }
}

और इसे हमारे टेम्पलेट में उपयोग करें:

<div v-for="id in ids" :key="id">{{descriptionById(id)}}</div>

यह कहा जा रहा है, मैं यहाँ यह नहीं कह रहा हूँ कि यह Vue के साथ काम करने का सही तरीका है।

हालाँकि, मैं देख सकता था कि जब निर्दिष्ट आईडी के साथ आइटम को स्टोर में म्यूट किया गया है, तो दृश्य इस आइटम के नए गुणों के साथ स्वचालित रूप से अपनी सामग्री को ताज़ा करता है (बाध्यकारी बस ठीक काम करता है)।


woah तो यह मेरे लिए काम किया, vuex का उपयोग नहीं। यह भी जानना चाहेंगे कि क्या यह संपत्तियों की गणना करने का एक वैध तरीका है।
यिदिक्सन

1
जबकि यह काम करता है, यह अनिवार्य रूप से गणना की गई संपत्ति को एक विधि के रूप में मानता है। यानी यह एक गणना की संपत्ति के कैशिंग लाभ खो देता है। इसलिए, इस पद्धति का उपयोग करने का कोई वास्तविक लाभ नहीं है। "ध्यान दें कि तरीकों के माध्यम से प्राप्त गेटर्स हर बार जब आप उन्हें कॉल करेंगे, और परिणाम कैश नहीं होगा।" Vuex.vuejs.org/en/getters.html
जेम्स

@ james.brndwgn, लेकिन मुझे पूरा यकीन है कि जब अंतर्निहित डेटा को बदल दिया जाता है, तो वे फिर से चालू नहीं होंगे। यही सब मैं वास्तव में देख रहा हूँ।
एलेक्स

@ एलेक्स तब आपको एक द्रष्टा का उपयोग करना चाहिए। vuejs.org/v2/guide/computed.html#Watchers
जेम्स

@ james.brndwgn मैं बहुत अगर संभव हो तो एक द्रष्टा की तुलना में एक गणना की संपत्ति का उपयोग करेंगे। मैं केवल आपके कथन के साथ समस्या ले रहा था: "तो, इस पद्धति का उपयोग करने पर कोई वास्तविक लाभ नहीं है।" जैसा कि कैशिंग के बिना भी एक महत्वपूर्ण अंतर है।
एलेक्स

4

फिल्टर Vue घटकों द्वारा प्रदान की जाने वाली एक कार्यक्षमता है जो आपको अपने टेम्पलेट डायनामिक डेटा के किसी भी भाग में स्वरूपण और परिवर्तन लागू करने देती है।

वे एक घटक के डेटा या कुछ भी नहीं बदलते हैं, लेकिन वे केवल आउटपुट को प्रभावित करते हैं।

कहते हैं कि आप एक नाम छाप रहे हैं:

new Vue({
  el: '#container',
  data() {
    return {
      name: 'Maria',
      lastname: 'Silva'
    }
  },
  filters: {
    prepend: (name, lastname, prefix) => {
      return `${prefix} ${name} ${lastname}`
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="container">
  <p>{{ name, lastname | prepend('Hello') }}!</p>
</div>

फ़िल्टर लागू करने के लिए सिंटैक्स पर ध्यान दें, जो है | फ़िल्टर। यदि आप यूनिक्स से परिचित हैं, तो यह यूनिक्स पाइप ऑपरेटर है, जिसका उपयोग ऑपरेशन के आउटपुट को अगले इनपुट के रूप में पास करने के लिए किया जाता है।

घटक का फिल्टर गुण एक वस्तु है। एक एकल फ़िल्टर एक फ़ंक्शन है जो एक मान को स्वीकार करता है और दूसरा मान लौटाता है।

लौटाया गया मान वास्तव में Vue.js टेम्पलेट में मुद्रित किया गया है।


3

आप किसी फ़ंक्शन को वापस करके प्राप्तकर्ताओं के लिए तर्क भी पास कर सकते हैं। जब आप स्टोर में किसी सरणी को क्वेरी करना चाहते हैं तो यह विशेष रूप से उपयोगी होता है:

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

ध्यान दें कि तरीकों के माध्यम से प्रवेश पाने वाले हर बार जब आप उन्हें कॉल करेंगे, और परिणाम कैश नहीं होगा।

इसे मेथड-स्टाइल एक्सेस कहा जाता है और इसे Vue.js डॉक्स पर प्रलेखित किया जाता है


2

आप पैरामीटर पास कर सकते हैं लेकिन या तो यह एक v.js तरीका नहीं है या आप जिस तरह से कर रहे हैं वह गलत है।

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

<template>
    <div>
        Your name is {{get_name}} <!-- John Doe at the beginning -->
        <button @click="name = 'Roland'">Change it</button>
    </div>
</template>

और स्क्रिप्ट

export default {
    data: () => ({
        name: 'John Doe'
    }),
    computed:{
        get_name: {
            get () {
                return this.name
            },
            set (new_name) {
                this.name = new_name
            }
        },
    }    
}

जब बटन पर क्लिक किया जाता है तो हम गणना की गई संपत्ति को 'रोलैंड' और 'इन' नाम देते हैं set() देते हैं हम 'जॉन डो' से 'रोलैंड' नाम बदल रहे हैं।

नीचे एक सामान्य उपयोग का मामला है जब गणना का उपयोग गटर और सेटर के साथ किया जाता है। कहो कि आपके पास फॉलो स्टोर है:

export default new Vuex.Store({
  state: {
    name: 'John Doe'
  },
  getters: {
    get_name: state => state.name
  },
  mutations: {
    set_name: (state, payload) => state.name = payload
  },
})

और अपने घटक में आप v-modelएक इनपुट में जोड़ना चाहते हैं लेकिन vuex स्टोर का उपयोग कर।

<template>
    <div>
        <input type="text" v-model="get_name">
        {{get_name}}
    </div>
</template>
<script>
export default {
    computed:{
        get_name: {
            get () {
                return this.$store.getters.get_name
            },
            set (new_name) {
                this.$store.commit('set_name', new_name)
            }
        },
    }    
}
</script>

1

मुझे पूरा यकीन नहीं है कि आप क्या हासिल करने की कोशिश कर रहे हैं, लेकिन लगता है कि आप गणना के बजाय विधि का उपयोग करके पूरी तरह से ठीक हो जाएंगे!


1
computed: {
  fullName: (app)=> (salut)=> {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}

जब आप उपयोग करना चाहते हैं

<p>{{fullName('your salut')}}</p>

1

गणना की जा सकती है पर विचार एक समारोह है। इस तरह से वैधता पर छूट के लिए आप स्पष्ट रूप से कुछ कर सकते हैं:

    methods: {
        validation(attr){
            switch(attr) {
                case 'email':
                    const re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
                    return re.test(this.form.email);
                case 'password':
                    return this.form.password.length > 4
            }
        },
        ...
    }

जिसका आप उपयोग कर रहे हैं:

  <b-form-input
            id="email"
            v-model="form.email"
            type="email"
            :state="validation('email')"
            required
            placeholder="Enter email"
    ></b-form-input>

बस ध्यान रखें कि आप अभी भी गणना के लिए विशिष्ट कैशिंग को याद करेंगे।


0

हाँ विधियों में परम का उपयोग करने के लिए हैं। ऊपर वर्णित उत्तरों की तरह, आपके उदाहरण में निष्पादन के बाद से विधियों का उपयोग करना सबसे अच्छा है।

केवल संदर्भ के लिए, ऐसी स्थिति में जहां विधि जटिल है और लागत अधिक है, आप परिणाम को इस तरह से कैश कर सकते हैं:

data() {
    return {
        fullNameCache:{}
    };
}

methods: {
    fullName(salut) {
        if (!this.fullNameCache[salut]) {
            this.fullNameCache[salut] = salut + ' ' + this.firstName + ' ' + this.lastName;
        }
        return this.fullNameCache[salut];
    }
}

नोट: इसका उपयोग करते समय, हजारों के साथ व्यवहार करने पर मेमोरी के लिए वॉचआउट करें

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