How to track changes in a property stored in Vuex(store) and perform some method based on the value? - vue.js

I'm trying to change the links based on the variable user_role which is stored in Vuex(store). I'm not able to find an appropriate way to track the change and based on its value I want to perform some method. Any suggestions on how to do it?
------------------------------store.js-------------------------------
export default new Vuex.Store({
state: {
user_role: "User"
},
mutations: {},
actions: {},
modules: {}
});
-----------------------------------component.vue---------------------------
export default {
name: "Navbar",
data() {
return {
links: [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "", route: "" },
{ text: "Resources", route: "/resources" }
],
pers_actions: ["Profile", "LogOut"],
};
},
watch: {
user_role: {
if (user_role === "PM") {
this.links[2] = {
text: "Allocations",
route: "/allocations"
};
} else if (user_role === "PMO") {
this.links[2] = {
text: "Reports",
route: "/reports"
};
} else if (user_role === "User") {
this.links = [
{
text: "Allocations",
route: "/allocations"
}
];
}
}
},

Rather than explicitly mutating your local data in response to some state change, it is better to compute your links within a computed property because it will automatically update whenever some dependent data has changed. It'll "just work".
computed: {
links() {
switch (this.$store.state.user_role) {
case: "PM": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Allocations", route: "/allocations" },
{ text: "Resources", route: "/resources" },
];
case: "PMO": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Reports", route: "/reports" },
{ text: "Resources", route: "/resources" },
];
// For any other role
default: return [
{ text: "Allocations", route: "/allocations" },
];
}
}
}

Related

Add a Class if element is in viewport vuejs nuxt

I want give an element a class when it's in the viewport and I don't know how I can handle it. I watched a few Videos on Youtube but nothing helped me.
I work with a boilerplate so I can't implement additional plugins.
My script looks actually like this.
export default {
head() {
return {
title: this.$t("headData.index.title"),
meta: [
{
hid: "description",
name: "description",
content: this.$t("headData.index.description")
}
]
}
},
data() {
return {
debugSingleScroll: true,
}
},
methods: {
handleScroll() {
if(this.debugSingleScroll) {
this.scrollToNextModule()
this.scrollToLastModule()
this.debugSingleScroll = false;
}
},
scrollToNextModule() {
this.$refs.factsModule.triggerAnimation();
},
scrollToLastModule() {
},
},
mounted () {
window.addEventListener('scroll', this.handleScroll);
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll);
},
}

how to pass i18n data $t as prop to a component

in a normal way with out translation but i want to translate the two object array and bind into a component
<InfoNews
v-for="infonew in infonews"
:id="infonew.id"
:title="infonew.title"
:content="infonew.content"
/>
data() {
return {
infonews: [
{
id: "01",
title: "what we do",
content:"industke aecimen book. ",
},
{
id: "02",
title: "our mission",
content:"ggdddg",
},
],
};
Make infonews a computed property. The title and content of each should be the translation keys.
export default {
computed: {
infonews() {
return [
{
id: "01",
title: this.$t("what we do"),
content: this.$t("industke aecimen book"),
},
{
id: "02",
title: this.$t("our mission"),
content: this.$t("ggdddg"),
},
]
};
}
}

structure of xstate config which has condion included & which can be used in vue-kanban pkg

I'm trying to create xstate Machine which has condition to be check when moving to another state(Using VueJs).
issue is the way tried which is not working with vue-kanban(https://github.com/BrockReece/vue-kanban) pkg
below is my sample state machine config :
stateMachineConfig: {
id: "kanban",
initial: "on-hold",
states: {
"on-hold": {
on: {
IN_PROGRESS:"in-progress",
}
},
"in-progress": {
on: {
RELINQUISH_TASK: "on-hold",
PUSH_TO_QA: "needs-review",
},
},
"needs-review": {
on: {
REQUEST_CHANGE: "in-progress",
PASS_QA: "approved",
},
},
approved: {
type: "final",
},
},
},
this is the UI of kanban(https://ibb.co/6rWxN0F)
after i changing above config by adding condition to "on-hold" state then i can't move to anywhere from "on-hold" state.
below is the new config:
const searchValid = (context) => {
console.log(`context.status `, context);
return true;
};
stateMachineConfig: {
id: "kanban",
initial: "on-hold",
states: {
"on-hold": {
on: {
PICK_UP: [
{
target: "in-progress",
cond: searchValid
}
]
}
},
"in-progress": {
on: {
RELINQUISH_TASK: "on-hold",
PUSH_TO_QA: "needs-review",
},
},
"needs-review": {
on: {
REQUEST_CHANGE: "in-progress",
PASS_QA: "approved",
},
},
approved: {
type: "final",
},
},
},
any help to fix it!
I have tested your machine using the XState visualizer and all works properly, you can check it here

XState.js How to send context to a machine?

I am new to XState.js.
I want to use a simple ID in my context. How do I update the context using machine.send()?
const fetchMachine = Machine(
{
id: 'test',
initial: 'init',
context: {
id: '',
},
states: {
init: {
on: {
LOGIN: 'fetch',
},
},
fetch: {
on: {
LOGOUT: 'init',
},
},
}
})
const machine = interpret(fetchMachine).start()
How do I pass an ID to the context?
This does NOT do the trick:
machine.send({ type: 'LOGIN', id })
You have to use the assign action to update the context. I've updated your example to the following:
import { Machine, assign } from 'xstate';
// Action to assign the context id
const assignId = assign({
id: (context, event) => event.id
});
export const testMachine = Machine(
{
id: 'test',
initial: 'init',
context: {
id: '',
},
states: {
init: {
on: {
LOGIN: {
target: 'fetch',
actions: [
assignId
]
}
},
},
fetch: {
on: {
LOGOUT: 'init',
},
},
}
},
{
actions: { assignId }
}
);
Now once you call the following:
import { testMachine } from './machines';
const testService = interpret(testMachine).start();
testService.send({type: 'LOGIN', id: 'test' });
//or testService.send('LOGIN', { id: 'test'});
the action assignId will assign data from the event to your context

Computed property depends on vuex store. How to update the cached value?

The value of this.$store.state.Auth.loginToken is modified by one of its child components. The initial value of this.$store.state.Auth.loginToken is undefined. But still, the update in its value has no effect in the cached value of navItems thus it always returns the second value.
computed: {
navItems () {
return this.$store.state.Auth.loginToken != undefined ?
this.items.concat([
{ icon: 'add', title: 'Add new journal entry', to: '/' },
{ icon: 'power_settings_new', title: 'Logout', to: '/logout'}
]) :
this.items.concat([
{ icon: 'play_arrow', title: 'Login', to: '/login' }
])
}
}
Is there a better way to keep a watch on this.$store.state.Auth.loginToken so that it can be used same as navItems?
I created a basic example of how you can use vuex getters and Auth token (codepen):
const mapGetters = Vuex.mapGetters;
var store = new Vuex.Store({
state: {
Auth: {
loginToken: ''
},
menuItems: [
{ icon: 'home', title: 'Home', to: '/' },
{ icon: 'about', title: 'About', to: '/about' },
{ icon: 'contact', title: 'Contact', to: '/contact' }
]
},
mutations: {
SET_LOGIN_TOKEN(state, data) {
state.Auth.loginToken = 1
}
},
getters: {
menuItems(state, getters) {
if(state.Auth.loginToken !== '') {
return state.menuItems.concat([{
icon: 'profile', title: 'Profile', to: '/profile'
}])
}
return state.menuItems
},
loggedIn(state) {
return state.Auth.loginToken !== ''
}
},
actions: {
doLogin({commit}) {
commit('SET_LOGIN_TOKEN', 1)
}
}
});
new Vue({
el: '#app',
store,
data: function() {
return {
newTodoText: "",
doneFilter: false
}
},
methods: {
login() {
this.$store.dispatch('doLogin')
}
},
computed: {
...mapGetters(['menuItems', 'loggedIn'])
}
})
This is just an example so you can ignore the actual login action. Also, the store should be a directory, the getters, mutations and actions should have their own files which are then imported in the index.js in the store like in this example