संचार प्रकार
Vue एप्लिकेशन (या वास्तव में, किसी भी घटक आधारित अनुप्रयोग) को डिज़ाइन करते समय, विभिन्न संचार प्रकार होते हैं जो इस बात पर निर्भर करते हैं कि हम किन चिंताओं से निपट रहे हैं और उनके अपने संचार चैनल हैं।
व्यावसायिक तर्क: आपके ऐप और उसके लक्ष्य के लिए विशिष्ट सभी चीज़ों को संदर्भित करता है।
प्रस्तुति तर्क: कुछ भी जो उपयोगकर्ता के साथ बातचीत करता है या उपयोगकर्ता से बातचीत के परिणामस्वरूप होता है।
ये दो चिंताएं इस प्रकार के संचार से संबंधित हैं:
- अनुप्रयोग स्थिति
- अभिभावक-बच्चे
- बाल-माता-पिता
- एक माँ की संताने
प्रत्येक प्रकार को सही संचार चैनल का उपयोग करना चाहिए।
संचार कढ़ी
एक चैनल एक ढीला शब्द है जिसका उपयोग मैं एक Vue ऐप के आसपास डेटा का आदान-प्रदान करने के लिए ठोस कार्यान्वयन का उल्लेख करने के लिए करूंगा।
सहारा: अभिभावक-बाल प्रस्तुति तर्क
प्रत्यक्ष अभिभावक-बाल संचार के लिए Vue में सबसे सरल संचार चैनल । यह ज्यादातर प्रस्तुति तर्क से संबंधित डेटा को पारित करने के लिए या पदानुक्रम के नीचे डेटा के एक प्रतिबंधित सेट के लिए उपयोग किया जाना चाहिए।
संदर्भ और तरीके: प्रस्तुति विरोधी पैटर्न
जब एक बच्चे को माता-पिता से एक घटना को संभालने के लिए एक प्रोप का उपयोग करने का कोई मतलब नहीं है, तो बच्चे के घटक को स्थापित करना ref
और उसके तरीकों को कॉल करना ठीक है।
ऐसा मत करो, यह एक विरोधी पैटर्न है। अपने घटक आर्किटेक्चर और डेटा प्रवाह पर पुनर्विचार करें। यदि आप स्वयं को माता-पिता से एक बच्चे के घटक पर एक विधि को कॉल करना चाहते हैं, तो संभवतया यह समय है कि वह राज्य को ऊपर उठाएं या यहां वर्णित अन्य तरीकों पर विचार करें।
घटनाएँ: बाल-अभिभावक प्रस्तुति तर्क
$emit
और $on
। प्रत्यक्ष बाल-अभिभावक संचार के लिए सबसे सरल संचार चैनल। पुन: प्रस्तुति तर्क के लिए उपयोग की जानी चाहिए।
घटना बस
अधिकांश उत्तर ईवेंट बस के लिए अच्छे विकल्प देते हैं, जो दूर के घटकों या वास्तव में कुछ भी उपलब्ध संचार चैनलों में से एक है।
यह तब उपयोगी हो सकता है, जब सभी जगह से नीचे तक गहराई से नेस्टेड बच्चों के घटकों के बीच से गुजरते हुए, लगभग कोई अन्य घटक न हो जिसके बीच में इनकी आवश्यकता होती है। ध्यान से चयनित डेटा के लिए संयम से उपयोग करें।
सावधान रहें: बाद में खुद को घटना बस में बांधने वाले घटकों का निर्माण एक से अधिक बार बाध्य होगा - जिससे कई हैंडलर ट्रिगर और लीक हो जाएंगे। मैंने व्यक्तिगत रूप से कभी भी उन सभी सिंगल पेज ऐप्स में इवेंट बस की आवश्यकता महसूस नहीं की, जिन्हें मैंने अतीत में डिज़ाइन किया है।
निम्नलिखित दर्शाता है कि कैसे एक साधारण गलती एक रिसाव की ओर ले जाती है जहां Item
घटक अभी भी ट्रिगर होता है भले ही डोम से हटा दिया गया हो।
// A component that binds to a custom 'update' event.
var Item = {
template: `<li>{{text}}</li>`,
props: {
text: Number
},
mounted() {
this.$root.$on('update', () => {
console.log(this.text, 'is still alive');
});
},
};
// Component that emits events
var List = new Vue({
el: '#app',
components: {
Item
},
data: {
items: [1, 2, 3, 4]
},
updated() {
this.$root.$emit('update');
},
methods: {
onRemove() {
console.log('slice');
this.items = this.items.slice(0, -1);
}
}
});
<script src="https://unpkg.com/vue@2.5.17/dist/vue.min.js"></script>
<div id="app">
<button type="button" @click="onRemove">Remove</button>
<ul>
<item v-for="item in items" :key="item" :text="item"></item>
</ul>
</div>
destroyed
जीवन चक्र हुक में श्रोताओं को हटाने के लिए याद रखें ।
केंद्रीकृत स्टोर (व्यावसायिक तर्क)
Vuex राज्य प्रबंधन के लिए Vue के साथ जाने का तरीका है । यह केवल घटनाओं की तुलना में बहुत अधिक प्रदान करता है और यह पूर्ण पैमाने पर अनुप्रयोग के लिए तैयार है।
और अब आप पूछते हैं :
[S] क्या मैं प्रत्येक छोटी संचार के लिए vuex का स्टोर बनाता हूं?
यह वास्तव में चमकता है जब:
- अपने व्यापार तर्क से निपटने,
- बैकएंड के साथ संचार (या किसी भी डेटा दृढ़ता परत, स्थानीय भंडारण की तरह)
इसलिए आपके घटक वास्तव में उन चीज़ों पर ध्यान केंद्रित कर सकते हैं, जो उपयोगकर्ता इंटरफेस को प्रबंधित करने के लिए हैं।
इसका मतलब यह नहीं है कि आप इसे घटक तर्क के लिए उपयोग नहीं कर सकते हैं, लेकिन मैं उस तर्क को केवल आवश्यक वैश्विक UI स्थिति के साथ एक नामांकित Vuex मॉड्यूल के लिए गुंजाइश दूँगा।
वैश्विक राज्य में सब कुछ की एक बड़ी गड़बड़ी से निपटने के लिए, स्टोर को कई नामांकित मॉड्यूल में अलग किया जाना चाहिए।
घटक प्रकार
इन सभी संचारों को ऑर्केस्ट्रा करने और पुन: प्रयोज्य को आसान बनाने के लिए, हमें घटकों को दो अलग-अलग प्रकारों के बारे में सोचना चाहिए।
- ऐप विशिष्ट कंटेनर
- जेनेरिक घटक
फिर, इसका मतलब यह नहीं है कि एक जेनेरिक घटक का पुन: उपयोग किया जाना चाहिए या यह कि ऐप विशिष्ट कंटेनर का पुन: उपयोग नहीं किया जा सकता है, लेकिन उनकी अलग-अलग ज़िम्मेदारियाँ हैं।
ऐप विशिष्ट कंटेनर
ये केवल सरल Vue घटक हैं जो अन्य Vue घटकों (जेनेरिक या अन्य ऐप विशिष्ट कंटेनरों) को लपेटते हैं। यह वह जगह है जहां Vuex स्टोर संचार होना चाहिए और इस कंटेनर को अन्य सरल साधनों जैसे प्रॉप्स और ईवेंट श्रोताओं के माध्यम से संवाद करना चाहिए।
इन कंटेनरों में मूल डोम तत्व भी नहीं हो सकते हैं और जेनेरिक घटकों को टेंपलेटिंग और उपयोगकर्ता इंटरैक्शन से निपटने देते हैं।
गुंजाइश किसी भी तरह events
या stores
भाई बहन घटकों के लिए दृश्यता
यह वह जगह है जहाँ स्कूपिंग होता है। अधिकांश घटकों की दुकान के बारे में पता नहीं है और इस घटक (अधिकतर) एक का उपयोग दुकान मॉड्यूल के एक सीमित सेट के साथ namespaced चाहिए getters
और actions
प्रदान की साथ लागू Vuex बाध्यकारी सहायकों ।
जेनेरिक घटक
इन्हें प्रॉपर से अपना डेटा प्राप्त करना चाहिए, अपने स्वयं के स्थानीय डेटा में परिवर्तन करना चाहिए और सरल घटनाओं का उत्सर्जन करना चाहिए। अधिकांश समय, उन्हें पता नहीं होना चाहिए कि एक Vuex स्टोर बिल्कुल मौजूद है।
उन्हें कंटेनर भी कहा जा सकता है क्योंकि उनकी एकमात्र जिम्मेदारी अन्य UI घटकों को भेजने की हो सकती है।
सहोदर संचार
तो, इस सब के बाद, हमें दो भाई घटकों के बीच कैसे संवाद करना चाहिए?
एक उदाहरण के साथ समझना आसान है: कहते हैं कि हमारे पास एक इनपुट बॉक्स है और इसका डेटा ऐप (पेड़ के विभिन्न स्थानों पर भाई-बहनों) के साथ साझा किया जाना चाहिए और बैकएंड के साथ जारी रहना चाहिए।
सबसे खराब स्थिति के साथ शुरू , हमारे घटक प्रस्तुति और व्यापार तर्क मिश्रण होगा ।
// MyInput.vue
<template>
<div class="my-input">
<label>Data</label>
<input type="text"
:value="value"
:input="onChange($event.target.value)">
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
value: "",
};
},
mounted() {
this.$root.$on('sync', data => {
this.value = data.myServerValue;
});
},
methods: {
onChange(value) {
this.value = value;
axios.post('http://example.com/api/update', {
myServerValue: value
})
.then((response) => {
this.$root.$emit('update', response.data);
});
}
}
}
</script>
इन दोनों चिंताओं को अलग करने के लिए, हमें अपने कंपोनेंट को एक ऐप स्पेसिफिक कंटेनर में लपेटना चाहिए और प्रेजेंटेशन लॉजिक को अपने जेनेरिक इनपुट कंपोनेंट में रखना चाहिए।
हमारे इनपुट घटक अब पुन: प्रयोज्य है और बैकएंड और भाई-बहनों के बारे में नहीं जानते हैं।
// MyInput.vue
// the template is the same as above
<script>
export default {
props: {
initial: {
type: String,
default: ""
}
},
data() {
return {
value: this.initial,
};
},
methods: {
onChange(value) {
this.value = value;
this.$emit('change', value);
}
}
}
</script>
हमारा ऐप विशिष्ट कंटेनर अब व्यावसायिक तर्क और प्रस्तुति संचार के बीच का सेतु हो सकता है।
// MyAppCard.vue
<template>
<div class="container">
<card-body>
<my-input :initial="serverValue" @change="updateState"></my-input>
<my-input :initial="otherValue" @change="updateState"></my-input>
</card-body>
<card-footer>
<my-button :disabled="!serverValue || !otherValue"
@click="saveState"></my-button>
</card-footer>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
import { NS, ACTIONS, GETTERS } from '@/store/modules/api';
import { MyButton, MyInput } from './components';
export default {
components: {
MyInput,
MyButton,
},
computed: mapGetters(NS, [
GETTERS.serverValue,
GETTERS.otherValue,
]),
methods: mapActions(NS, [
ACTIONS.updateState,
ACTIONS.updateState,
])
}
</script>
चूंकि Vuex स्टोर की कार्रवाइयां बैकएंड संचार से संबंधित हैं, इसलिए हमारे कंटेनर को यहां axios और बैकएंड के बारे में जानने की आवश्यकता नहीं है।
$emit
v-model
अनुकरण करने के लिए संयुक्त.sync
। मुझे लगता है कि आपको Vuex रास्ता जाना चाहिए