Showing posts with label UI. Show all posts
Showing posts with label UI. Show all posts

Tuesday, 12 July 2022

Event Bus implementation in Vue

 In any application data sharing among various components/services are key to maintain data flow. In vue, different data sharing methods are:

  1. Props: Allow to pass data from parent to child component.
  2. Emit: Allow to pass data from child to parent component.
  3. Vuex Store: Allow to share data across components.
import mitt from 'mitt';
export default mitt();
<template>
<div class="hello">
<input v-model="message" />
<button
@click="onPublish">publish</button>
</div>
</template>
<script>
import eventbus from "@/eventbus";
export default {
name: "HelloMessagePublish",
data() {
return {
message: "",
};
},
methods: {
onPublish() {
eventbus.emit("getMessage", this.$data.message);
},
},
};
</script>
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
import eventbus from "@/eventbus";
export default {
name: "HelloMessageDisplay",
data() {
return {
msg: "",
};
},
mounted() {
eventbus.on("getMessage", (e) => {
this.$data.msg = e;
});

},
};
</script>
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
import eventbus from "@/eventbus";
export default {
name: "HelloMessageDisplay2",
data() {
return {
msg: "",
};
},
mounted() {
eventbus.on("getMessage", (e) => {
this.$data.msg = e;
});

},
};
</script>
<template>
<div id="app">
<HelloMessagePublish />
<HelloMessageDisplay />
<HelloMessageDisplay2 />

</div>
</template>
<script>
import HelloMessageDisplay from "./components/HelloMessageDisplay";
import HelloMessageDisplay2 from "./components/HelloMessageDisplay2";
import HelloMessagePublish from "./components/HelloMessagePublish";
export default {
name: "App",
components: {
HelloMessageDisplay,
HelloMessageDisplay2,
HelloMessagePublish,

},
};
</script>

Monday, 4 July 2022

Custom vuex store module

 If you haven’t read through my previous article here on props vs emit in vue.js, I would recommend to read it first unless you are aware of props and emit concept of vuejs framework. I also expects, you know the basics already about Vue framework.

export default interface IUser {
firstname: string;
lastname: string;
email:string;
};
export {default as IUser} from './i-user'
// our root state is empty because we make use of modules,
// however we do need it for generic arguments and thus we declare it
export default interface IRootState { };
export { default as IRootState } from './i-root-state';
import { StoreOptions } from 'vuex';
import { IRootState } from '../interfaces';
import modules from '../modules';
const config: StoreOptions<IRootState> = {
strict: true,
state() { },
mutations: {},
actions: {},
modules,
};
export default config;
import Vue from 'vue';
import Vuex from 'vuex';
import config from './config';
import { IRootState } from './interfaces';
Vue.use(Vuex);const store = new Vuex.Store<IRootState>(config);export default store;
<template>
<div id="app">
<Home/>
<StoreData/>
</div>
</template>
<script lang="ts">
import Home from './components/Home.vue';
import StoreData from './components/StoreData.vue'
import store from "@/store";
export default {
components: {
Home,
StoreData
},
store
}
</script>
<style>
</style>
export enum GlobalUserActionEnum{
SET_USER = "setUser"
}
export default GlobalUserActionEnum;
import IUser from "@/interfaces/i-user";export enum GlobalUserGetterEnum {
GET_USER = 'getUser'
}
export default GlobalUserGetterEnum;
enum GlobalUserMutationEnum {
Mutate_USER = 'MUTATE_USER',
}
export default GlobalUserMutationEnum;
export const NAMESPACE = 'user';export default NAMESPACE;
import IUser from "@/interfaces/i-user";export type IGlobalUserPayload = Partial<IUser>;
import IUser from "@/interfaces/i-user";export default interface IUserState {
user: IUser;
};
export { default as GlobalUserActionEnum} from './global-user-action-enum';
export { default as GlobalUserMutationEnum } from './global-user-mutation-enum';
export { default as GlobalUserGetterEnum} from './global-user-getters-enum';
export { NAMESPACE } from './global-user-namespace';
export {default as IUSerState } from './i-state-user';
import IUserState from "./static/i-state-user";export const userState: () => IUserState = () => ({
user : {
firstname: '',
lastname: '',
email:''
}
});
import { MutationTree } from 'vuex';
import { GlobalUserMutationEnum } from './static';
import IUserState from "./static/i-state-user";
import { IGlobalUserPayload } from './static/global-user-payload';
export const userMutations: MutationTree<IUserState> = {
[GlobalUserMutationEnum.Mutate_USER](state, payload: IGlobalUserPayload) {
Object.assign(state.user, payload);
},

};
export default userMutations;
import { ActionTree } from 'vuex';
import { GlobalUserActionEnum, GlobalUserMutationEnum } from './static';
import IUserState from './static/i-state-user';
import { IRootState } from '../../interfaces';
import { IGlobalUserPayload } from './static/global-user-payload';
export const userActions: ActionTree<IUserState, IRootState> = {[GlobalUserActionEnum.SET_USER]({ commit }, payload: IGlobalUserPayload) {
commit(GlobalUserMutationEnum.Mutate_USER, payload);
},

};
export default userActions;
import { GetterTree } from 'vuex';
import { IRootState } from '../../interfaces';
import IUser from "@/interfaces/i-user";
import IUserState from './static/i-state-user';
import GlobalUserGetterEnum from './static/global-user-getters-enum';
export const userGetters: GetterTree<IUserState, IRootState> = {[GlobalUserGetterEnum.GET_USER](state): IUser {
return state.user;
},
};
export default userGetters;
import { Module } from 'vuex';
import { IRootState } from '../../interfaces';
import IUserState from "./static/i-state-user";
import { userGetters } from './getters';
import userMutations from './mutations';
import { userActions } from './action';
import { userState } from './state';
const globalUser: Module<IUserState, IRootState> = { namespaced: true,
state: userState,
getters: userGetters,
mutations: userMutations,
actions: userActions,

};
export default globalUser;
import user from './user'export default{
user
};
<template>
<div class="home">
First Name: <input v-model="user.firstname" />
<br />
Last Name: <input v-model="user.lastname" />
<br />
Email: <input v-model="user.email" />
<br />
<button @click="onSave()">Update User in Store</button>
<br />
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { IUser } from "@/interfaces";
import { mapActions, mapGetters } from "vuex";
import {
GlobalUserActionEnum,
GlobalUserGetterEnum,
NAMESPACE,
} from "../store/modules/user/static";
export default Vue.component('Home', {

data() {
return {
user : {
firstname: "",
lastname: "",
email: "",
} as IUser,
};
},
methods:{
onSave(){
this.setUser({
firstname: this.$data.user.firstname,
lastname: this.$data.user.lastname,
email: this.$data.user.email,
}
);
alert('User details are saved to store.')
},
...mapActions(NAMESPACE, {
setUser: GlobalUserActionEnum.SET_USER,
}),
},computed:{
...mapGetters(NAMESPACE, {
getUser: GlobalUserGetterEnum.GET_USER,
}),

},
created(){
//Don
this.$data.user.firstname = this.getUser.firstname;
this.$data.user.lastname = this.getUser.lastname;
this.$data.user.email = this.getUser.email;
}
})
</script>
<template>
<div>
<br /><br />
<h1>User Data (update on click) : {{ userData }}</h1>
<h1>User Data (reactive update) : {{ userComputedData }}</h1>
<button
@click="onFetch()">Read User from Store</button>
<br />
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { mapGetters } from "vuex";
import {
GlobalUserGetterEnum,
NAMESPACE,
} from "../store/modules/user/static";
export default Vue.component('StoreData', {

data() {
return {
userData: String,
};
},
methods:{
onFetch(){
this.$data.userData = this.getUser.firstname + ' ' + this.getUser.lastname + ', '+ this.getUser.email;
},

},
computed:{
...mapGetters(NAMESPACE, {
getUser: GlobalUserGetterEnum.GET_USER,
}),
userComputedData(){
return this.getUser.firstname + ' ' + this.getUser.lastname + ', '+ this.getUser.email;
}

},
created(){
this.onFetch();
}
})
</script>