ক্লাস নং-১৬ vue-statemangement-pinia
state management কি এবং কেন ব্যাবহার করব?
Table of contents
- আজকের ক্লাসের বিষয় হলো pinia for state management.
- তো চলুন দেখা যাক কিভাবে কাজ করে থাকে state-management.
- এবার আসি আমাদের একটি views এর মধ্যে কি কি ফাইল থাকে এবং কোন টা কি ।
- এবার আসি আমাদের pinia store এর কাজ নিয়ে
- এবার আসি আমাদের ভিউ পেইজ এ আমরা যে ওখানে state এর মধ্যে ডেটা লিখলাম সেগুলো ভিউ পেইজ এ কিভাবে শো করব ?
- এবার আসি আমাদের parent and child components এর ডেটা পাঠানো রিসিভ করা নিয়ে।
- এবার আসি ডিলিট অ্যাকশন এ।
- এবার আসি আমাদের getters এ
- All To-dos ,Pending To-dos, Completed To-dos
আজকের ক্লাসের বিষয় হলো pinia for state management.
বড় ধরনের প্রজেক্ট করার সময় আমাদের ডেটা,প্রসেস সব কিছু গুছিয়ে কাজ করতে বেশ বেগ পেতে হয় ।তাই এইগুলো সিকুয়েন্স অনুযায়ী খুব সুন্দর ভাবে শো করানোর জন্য আমরা state-management ব্যাবহার করে থাকি। এখন বর্তমানে state-management এর জন্য pinia suggested তবে আপনারা vuex ও ব্যাবহার করতে পারেন।
তো চলুন দেখা যাক কিভাবে কাজ করে থাকে state-management.
-প্রথমেই আমরা একটা প্রজেক্ট তৈরি করে নেব এবং আমাদের প্রজেক্ট তৈরি করার সময় কয়েকটি প্রশ্ন আসবে সেখান থেকে আমাদের যা লাগে (yes) করব এবং না লাগলে default ভাবেই no করা থাকে। তবে আমাদের এই প্রজেক্ট এর জন্য রাউটার এবং state-management এর জন্য pinia এর সময় (yes) করে দেব।
-এবার আমাদের প্রয়োজনীয় প্যাকেজ গুলো install করে configure করে নেব যেমন tailwind CSS
ওকে এবার আমাদের প্রজেক্ট এর প্রয়োজনীয় ফাইল গুলো বাদ দিয়ে ডিফল্ট গুলো আমরা ডিলেট করে দিতে পারি।
এবার আসি আমাদের একটি views এর মধ্যে কি কি ফাইল থাকে এবং কোন টা কি ।
এগুলো সম্পর্কে যদি ক্লিয়ার ধারনা না থাকে তাহলে আমাদের state-management pinia বুঝতে একটু কঠিন হয়ে যাবে। আমাদের view file এর মধ্যে থাকে।
data()--এটার মধ্যে আমাদের বিভিন্ন টাইপের ডেটা থাকে।
computed:{ }--এই প্রপার্টির মধ্যে আমাদের প্রয়োজনীয় কোড থাকে ডায়নামিক্যালি আমাদের ডেটার রেজাল্ট রিটার্ন করে।
--আর এখানে আমাদের বিভিন্ন function গুলো থাকে যেগুলো আমরা এখান থেকে কল করে থাকি।
data(){
return{ }
}
computed:{
}
methods:{
}
এই কোডগুলো আমাদের প্রত্যেক টা ভিউ তেই কাজে লাগে।
এবার আসি আমাদের pinia store এর কাজ নিয়ে
প্রথমেই আপনাকে একটা ফাইল তৈরি করতে হবে তাহলে যদি ফাইল তৈরি করি আমার ফাইলের নাম লেখার নিয়ম কি?
প্রথমেই আপনার প্রজেক্ট যে নামে খুলবেন সেই নাম দিয়ে তারপর store লাগিয়ে দেবেন। যেমন প্রজেক্ট যদি হয় todo এর সেক্ষেত্রে Todo Store দিলে সুন্দর মিনিংফুল নাম হবে।এবং বোঝা যাবে যে এটা একটা store এর ফাইল।
-এবার আমাদের যে ফাইল টা তৈরি করলাম stores এর মধ্যে সেখানে আমাদের pinia থেকে প্রয়োজনীয় কোড import করতে হবে। তো আমরা কাজ করব পিনিয়া এর define Store নিয়ে তাহলে আমরা সেটা import করে নেই।
defineStore()
এর দুইটা agreement থাকে
-first agreement
-second agreement
এখানে first agreement এর নাম টা ইউনিক ভাবে দিতে হবে যাতে করে অন্য ফাইলের মধ্যে গিয়ে কনফ্লিক্ট না করতে পারে। এবং second agreement আমাদের object return করে।এবার আমাদের define Store() কে একটা variable এর মধ্যে রেখে সেটা কে export করতে হবে। এবং সেই variable এর নাম দিয়ে আমরা তার আগে use বসিয়ে দেব।
তাহলে আমরা নাম দিতে পারি।
export const useTodoStore = defineStore('TodoStore',{
});
এখন আমরা যদি আমাদের এই store file এবং আমাদের view file compare করি তাহলে আমরা দেখতে পারবো আমাদের দুই যায়গার সব কিছু সেইম শুধুমাত্র syntax ভিন্ন।
তাহলে আমাদের এই ফাইলের মধ্যে কি কি থাকে চলুন দেখে নেই।
--state --action --getters
এবং আমাদের vuex এ আরেকটা বেশি থাকে সেটা হলোঃ
--state --action --getters --mutation
তো আজকে আমরা --state --action --getters
এই ৩ টা নিয়ে আলোচনা করব।
আমাদের ভিউ ফাইল এবং আমাদের স্টোর ফাইলের কোডের সাথে যদি তূলনা করি তাহলে আমরা দেখতে পাব।
state == data
action == methods
getters == computed
তাহলে আমাদের state কিভাবে লিখতে পারি।
state: () => ({
todos : [
{id:1, title:'Todo 1', completed: false},
{id:2, title:'Todo 2', completed: true},
{id:3, title:'Todo 3', completed: false},
{id:4, title:'Todo 4', completed: true},
{id:5, title:'Todo 5', completed: false}, ]
}),
এবার আসি আমাদের ভিউ পেইজ এ আমরা যে ওখানে state এর মধ্যে ডেটা লিখলাম সেগুলো ভিউ পেইজ এ কিভাবে শো করব ?
আমরা আমাদের ভিউ পেইজ থেকে যদি ডেটা রিসিভ করতে চাই তাহলে আমাদের ভিউ তেও পিনিয়া import করে নিতে হবে এবং আমরা যে স্টোর পেইজ এ ফাংশন তৈরি করলাম সেই ফাংশন import করতে হবে এবং এই পেইজ এ পিনিয়া আবার কিছু ডেটা রিটার্ন করে যেমনঃ
-map state এর সাহায্যে।
-getter এর ক্ষেত্রে -map getter
-action এর ক্ষেত্রে -map action এর সাহায্যে আমরা ডেটা গুলো এখানে রিটার্ন করতে পারব।
এখন আমাদের ভিউ ফাইলের মধ্যে কোথায় কোনটা রিটার্ন করে এটা একটা জানার বিষয় ।
আমাদের ভিউ ফাইলের computed: এর মধ্যে map State use করা হয়।
computed: { ...mapState(useTodoStore,[Todos]), },
এখানে একটা বিষয় আছে সেটা হলো আমাদের এই computed এর মধ্যে অবশ্যই অবশ্যই split operator দিতে হবে। কারন আমাদের এর সাথে আরো ডেটা আসবে সেগুলো আমাদের ফাংশনের সাহায্যে নিয়ে আসতে হবে আর ফাংশন তাই split operator দিলে আমাদের map state এর সাথে এটাও কাউন্ট হবে । আর যদি না দেই তাহলে আমাদের map state এর নিচে যাবেই না তাই এটা অবশ্যই দিতে হবে।
এবার আসি আমরা আমাদের যে ডেটা গুল তৈরি করেছি এখন নতুন করে ডেটা কিভাবে add করব বা অন্যান্য অপারেশন গুলো চালাবো। এবার আমাদের methods এর মধ্যে একটা function make করতে হবে এবং এই function ta button এ কল করতে হবে। এবং আমাদের যে variable এ ডেটা রাখছিলাম সেই variable কে function এর মধ্যে দিয়ে নতুন একটা action আমাদের todoStore থেকে নিয়ে এসে ডেটা গুলো সেট করতে হবে । তাহলে কিভাবে করা যায় চলুন দেখে আসি।
//view page
methods:{
addTodo(){ useTodoStore().addTodo({ id: this.todos.length + 1, title: "Todo " + (this.todos.length + 1), completed: false, })
} }
//store page
//action
actions:{ addTodo(todo){ console.log(todo);
this.todos.push(todo); },
}
এখন আমরা চাইলে এই li টা কে অন্য components বানিয়ে সেখান থেকেও import করতে পারি।
এবার আসি আমাদের parent and child components এর ডেটা পাঠানো রিসিভ করা নিয়ে।
এবং এখানে একটা বিষয় আছে সেটা হলো(map, filter, find)এগুলো কিভাবে কাজ করে কখন কোনটা ব্যাবহার করব। অলরেডি এটা নিয়ে বিস্তারিত একটা পোস্ট লিখেছি আপনারা চাইলে সেটা পড়ে আসতে পারেন।
এবার আসি ডিলিট অ্যাকশন এ।
deleteTodo(id){
this.todos = this.todos.filter(todo =>todo.id !== id);
}
এবং এই action টা আমরা আবার আমাদের single page এর মেথড এর মধ্যে ব্যাবহার করতে পারব এবং এখানে আমরা
methods: {
handleDelete(){ useTodoStore().deleteTodo(this.todo.id); }
}
এভাবেও id pass করে খুব সুন্দর এবং সহজ ভাবে কাজ করতে পারব।
এভাবে করলে আমাদের আগের ক্লাসের মত $emit করে আর ডেটা পাঠানো লাগছে না এবং অন্য পেইজ এ গিয়ে ডেটা রিসিভ করে আবার ফাংশন লিখে কাজ করা লাগছে না খুব সহজেই আমরা এই কাজ টি করতে পারছি।
এটাই হলো মূলত আমাদের state-management এর মজা।
এবার আসি আমাদের getters এ
--কিভাবে আমরা getters লিখবো এবং এই getters কিভাবে কাজ করে যদিও আমি আগেই বলেছি আমাদের ভিউ পেইজের কোড গুলোর সাথে মিল রেখে getters টা আমাদের Computed এর সাথে সামঞ্জস্যপুর্ন। getters সাধারনত object return করে।
getters: {
}
এখানে একটা বিষয় আছে সেটা হলো আমরা যে ডেটা গুলো অন্য পেইজ থেকে ব্যাবহার করছি সেটা দুইটা ভাবে করা যায়
--সরাসরি ভাবে state টা কে ব্যাবহার
--getter ঘুরিয়ে নিয়ে এসে state টা কে ব্যাবহার
তবে অনেকেই দুই নং টা কেই বেশি প্রাধান্য দেই গেটার ঘুরিয়ে নিয়ে ডেটা access.
তাহলে আমরা কিভাবে গেটার ঘুরিয়ে নিয়ে আসবো?
আমাদের todo page এ
computed: {
...mapState(useTodoStore,['alltodos']),
},
এখানে আপনি চাইলে এই alltodos কে আরেকটা variable এর মধ্যে রেখে সেটাকে v-for করতে পারেন।এখানে যদি আপনার প্রয়োজন হয় তাহলে কিভাবে করতে পারি সেটা?
computed: { ...mapState(useTodoStore,{ todos :"alltodos" }),
},
এবং আমাদের TodoStorage এ
//getters
getters: {
alltodos:(state) =>state.todos,
}
এবার আসি আমরা তো জানি true ,false Boolean type data কিন্ত আমাদের string data কে কিভাবে আমরা true false করে রিটার্ন করতে পারি সেটা দেখে নেই।
data(){
return{ message:"hello" !!message }
},
!!message
এটাকে আপনারা v-if এর মধ্যে ব্যাবহার করতে পারবেন।যদি কোন value থাকে তাহলে true দেখাবে আর যদি কোন value না থাকে তাহলে সেটা false দেখাবে।
এবার আসি আমাদের getters এর মধ্যে বিভিন্ন ধরনের কাউন্ট নিয়ে কিভাবে আমরা সেটা করতে পারি আমাদের vue page এর computed property এর মত গতক্লাসে আমরা যেমন টা করেছিলাম।
//getters
getters: { alltodos: (state) => state.todos,
pendingTodos: (state) => state.todos.filter(todo => !todo.completed), completedTodos: (state) => state.todos.filter(todo => todo.completed), allTodosCount: (state) => state.todos.length,
pendingTodosCount: (state) => state.todos.filter(todo => !todo.completed).length, completedTodosCount: (state) => state.todos.filter(todo => todo.completed).length,
}
এই কাজ টা আমরা খুব সহজেই করে ফেলতে পারি কিভাবে মনে আছে গত ক্লাসে আমরা কিভাবে computed property এর মধ্যে কাজ গুলো করেছিলা খুব সহজেই আমরা আমাদের রানিং ডেটার আপডেট পেয়েছিলাম আমরা ঠিক সেই কাজ টাই করতে যাচ্ছি এই getters এর মাধ্যমে।
আবার আপনি আপনার todo page প্রথমে এভাবে variable এর মাধ্যমে রেখে সেগুলোকে আপনি v-for করে দিবেন।
computed: {
...mapState(useTodoStore,{ todos: "alltodos", pending:"pendingTodos", completed:"completedTodos",
}),
All To-dos ,Pending To-dos, Completed To-dos
এবং আমরা আমাদের single todo page এ একটা বাটন add করব যেটা দিয়ে আমরা আমাদের pending job গুলোকে complete করতে পারব এবং complete গুলোকে pending করতে পারব।
এবার আসি আমরা কেন pinia use করব এবং আমাদের আসলেই pinia দিয়ে real time কাজ কি যদিও আমরা ওপরে দেখেছি পিনিয়া ব্যাবহার করে খুব সহজেই আমরা ডেটা অপারেশন চালাতে পারছি এখন দেখব completed কোন কিছু যদি আমরা করতে চাই সেক্ষেত্রে আমরা কিভাবে এটাকে ব্যাবহার করতে পারি।
--মনে করেন আপনার একটা ফাইল আছে যেটা components এর মধ্যে কিন্তু আপনার store কিংবা আপনার ভিউ বা components এর অন্য কোন ফাইল এর সাথে সম্পর্ক নেই কিন্তু আপনার সেই পেইজ এ ডেটা পাঠাতে হবে যদিও আমরা দেখেছি props আকারে ডেটা পাঠাতে কিন্তু এটা nested file system হলে props আকারে ডেটা পাঠানো বেশ ডিফিকাল্ট তাহলে আমরা সেটা কিভাবে করব,।
এই কাজ টা আমরা কিভাবে করতে পারি?
প্রথমেই আমরা আমাদের এর ওপরে আমাদের কে import করে নেব।
এবং আমাদের menu section মধ্যে প্রথমেই আমাদের pinia থেকে {useTodoStore} এবং {map State} import করে নেব।
import {
useTodoStore} from "../stores/TodoStore"; import {mapState} from "pinia";
এরপর আমরা export করে সুন্দর ভাবে আমাদের variable গুলো রেখে ডাটা শো করতে পারি।
export default {
name: "MenuSection",
computed: { ...mapState(useTodoStore,['allTodosCount','pendingTodosCount','completedTodosCount']),
},
}
আপনি যদি বুঝতে পারেন তাহলে অবশ্যই বিষয় টি আপনার ভাল লাগতে বাধ্য কারন খুব সিম্পল ভাবে আমরা ডেটাগুলো কে কেবল মাত্র store file গুলো import করা ছাড়া আর কিছু import না করেই সহজেই ডেটাগুলো কে শো করাতে পেরেছি app.vue file এর মধ্যে দিয়ে।
আরেকটা বিষয় আপনি খুব সহজেই এই store file এর মধ্যে api call করেও ডেটাগুলো কে শো করাতে পারবেন।
//action
actions: {
addTodo(todo) {
console.log(todo); this.todos.push(todo); },
}
তাহলে আমরা কখন এই pinia use করব । আমাদের প্রজেক্ট যদি একটু complicated হয় এবং আমাদের যদি nested file এর মধ্যে props পাঠানো লাগে এবং বেশ confusing মনে হয় তখন আমরা state-management হিসেবে pinia ব্যাবহার করতে পারি।
এছাড়া আমরা যদি ২,৩ টা ফাইলের মধ্যে props আকারে ডেটা পাঠিয়ে সেটাকে complete করতে পারি তাহলে আমাদের pinia না ব্যাবিহার করলেও হবে।
আজকে পিনিয়া নিয়ে এতটুকুই আরো অনেক interesting বিষয় গুলো আছে পিনিয়ার আপনি চাইলে vue.org এর অফিসিয়াল ওয়েবসাইট থেকে আরো ভাল ভাবে পড়ে নিতে পারেন।
Happy Learning
Rakibul Islam