I built a simple vuejs app with vuex but I would like to use mapGetters, how can I implement that function on it? - vuex

I built a simple vuejs app with vuex but I would like to use mapGetters, how can I implement that function on it?
this is my index.js:
import { mapGetters } from 'vuex'
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
state: {
counter: 0,
colourCode: 'blue'
},
getters: {
counterSquared(state){
return state.counter * state.counter
}
},
and currently this how the vue component looks like:
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<div
:style="{color: $store.state.colourCode}"
class="counter">
{{$store.state.counter}}
</div>
<div class="counter-squared">
{{$store.state.counter}}
<sup>2</sup> =
{{$store
.getters.counterSquared}}
</div>
How can I change it to using mapGetters?

Here's what you can do, in VUE 3
<script>
import { computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup () {
const store = useStore()
return {
counterSquared: computed(() => store.getters.counterSquared)
}
}
}
</script>
Using setup template :
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
const store = useStore()
const counterSquared: computed(() => store.getters.counterSquared)
}
}
</script>
Vue 2
<script>
import { mapGetters } from 'vuex'
export default {
// you can call it like this.counterSquad, counterSquad(in template)
computed: {
...mapGetters([
'counterSquared',
// ...
])
}
// OR
// you can call it like this.cS, cS(in template) base on defined name.
computed: {
...mapGetters({
cS: 'counterSquared'
})
])
}
}
</script>

Related

How to use $store.commit in Nuxt with #vue/composition-api

<template>
<div>
<h1>Vuex Typescript Test</h1>
<button #click="handleLogin">click</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from '#vue/composition-api'
export default defineComponent({
setup() {
return {
handleLogin() {
// something....
},
}
},
})
</script>
#vue/composition-api do not apply useStore
I want to use store in setup function.
You should be able to access the useStore composable in the setup function according to the documentation of Vuex.
Your script section will look like this:
import { defineComponent } from '#vue/composition-api';
import { useStore } from 'vuex';
export default defineComponent({
setup() {
return {
const store = useStore();
return {
handleLogin {
store.dispatch('auth/login');
},
};
}
},
});
The proper way to structure the content of setup would be to move the handleLogin as a separate const and expose the constant in the return, in order to keep the return section more readable like this:
setup() {
const store = useStore();
const handleLogin = () => {
store.dispatch('auth/login');
};
return {
handleLogin,
}
}

Vuex useStore is giving me undefined in this component

<template>
<div :style="styles">
<Spinner v-if="showSpinner" class="w-14 h-14" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Spinner from '../common/Spinner.vue';
export default defineComponent({
name: 'FullQuestionnaire',
components: { Spinner },
});
</script>
<script setup lang="ts">
import { withDefaults, defineProps, computed, ref, toRefs, watch } from 'vue';
import { useStore } from 'vuex';
const props = withDefaults(
defineProps<{
isLoading?: boolean;
additions: AdditionalParameters;
questionnaireConfig: QuestionnaireConfig;
questionnaireStyling?: RawQuestionnaireStyles | null;
submitAnswers: SubmitAnswersFunction;
goBack: () => void;
}>(),
{ isLoading: undefined, questionnaireStyling: null }
);
const store = useStore();
const redirectUrl = computed(
() => thankYouScreenInfo.value.properties.redirect_url ?? ''
);
const processedRedirectUrl = computed(() => {
const url = populatePlaceholdersInLinkQueryParameters(
redirectUrl.value,
''
// store.getters.userProfile
);
});
</script>
Hi, I am new to Vue and still learning. As you can see in the code I am importing useStore from vuex but when I tried to console.log(store) after this declaration const store = useStore(); its giving me undefined.
Vue Document
When I look into the vuex documentation. the example is using the useStore when setting up. Can I call const store = useStore(); outside of the setup?
Why is that?

vuex module axios in vue3 composition api

I am new to vue and working with vue 3 and the composition API. It is really hard to find stuff related to the composition API, so I try to get help here. I am using axios in combination with vuex modules for consuming APIs.
How can I transfere this code from options API to composition API?
TestApi.js
import axios from 'axios'
const posts = {
namespaced: true,
state: {
posts: []
},
mutations: {
SET_POSTS(state, data){
state.posts = data
}
},
actions: {
loadPosts({commit}) {
axios
.get('https://jsonplaceholder.typicode.com/posts')
.then( res => {
commit('SET_POSTS', res.data)
} )
.catch(error => console.log(error))
}
},
getters: {
getPosts(state){
return state.posts
}
}
}
export default posts
App.vue
<template>
<div class="post" v-for="post in getPosts" :key="post.id">
<h1>{{ post.title }}</h1>
<p>{{ post.body }}</p>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { computed } from 'vue'
export default {
computed: {
...mapGetters('posts', ['getPosts'])
},
created(){
this.$store.dispatch('posts/loadPosts')
}
}
</script>
<style>
.post{
margin-bottom: 20px;
}
</style>
I tried something like this. But it does not work:
import { useStore } from 'vuex'
import { computed } from 'vue'
export default {
setup(){
getData();
const store = useStore()
function getData(){
store.dispatch('posts/loadPosts');
}
const getPosts = computed(() => store.getters['getPosts'])
return{ getPosts }
}
}
Error: Uncaught (in promise) TypeError: Cannot read property 'dispatch' of undefined
You shoul run the function after initializing the store :
setup(){
const store = useStore()
getData();
...

[Vue warn]: Property or method "stateSidebar" is not defined on the instance but referenced during render

I know this seems like a question that would be easy to find, but my code worked some time ago. I am using a Vuex binding to check if my sidebar should be visible or not, so stateSidebar should be set within my entire project.
default.vue
<template>
<div>
<TopNav />
<SidebarAuth v-if="stateSidebar" />
<Nuxt />
</div>
</template>
<script>
import TopNav from './partials/TopNav';
import SidebarAuth from './partials/SidebarAuth';
export default {
components: {
TopNav,
SidebarAuth
},
methods: {
setStateSidebar(event, state) {
this.$store.dispatch('sidebar/setState', state)
}
}
}
</script>
store/sidebar.js
export const state = () => ({
stateSidebar: false
});
export const getters = {
stateSidebar(state) {
return state.stateSidebar;
}
};
export const mutations = {
SET_SIDEBAR_STATE(state, stateSidebar) {
state.stateSidebar = stateSidebar;
}
};
export const actions = {
setState({ commit }, stateSidebar) {
commit('SET_SIDEBAR_STATE', stateSidebar);
},
clearState({ commit }) {
commit('SET_SIDEBAR_STATE', false);
}
};
plugins/mixins/sidebar.js
import Vue from 'vue';
import { mapGetters } from 'vuex';
const Sidebar = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
stateSidebar: 'sidebar/stateSidebar'
})
}
})
}
}
Vue.use(Sidebar);
nuxt.config.js
plugins: ["./plugins/mixins/validation", "./plugins/axios", "./plugins/mixins/sidebar"],
If you're creating a mixin, it should be in /mixins
So for example /mixins/my-mixin.js.
export default {
// vuex mixin
}
Then import it like this in default.vue
<script>
import myMixin from '~/mixins/my-mixin`
export default {
mixins: [myMixin],
}
This is not what plugins should be used for tho. And IMO, you should definitively make something simpler and shorter here, with less boilerplate and that will not be deprecated in vue3 (mixins).
This is IMO the recommended way of using it
<template>
<div>
<TopNav />
<SidebarAuth v-if="stateSidebar" />
<Nuxt />
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState('sidebar', ['stateSidebar']) // no need to use object syntax nor a getter since you're just fetching the state here
},
}
</script>
No mixin, no plugin entry.

Can't access store from Vuex [Quasar]

I'm trying Quasar for the first time and trying to use the Vuex with modules but I can't access the $store property nor with ...mapState. I get the following error 'Cannot read property 'logbook' of undefined' even though I can see that the promise logbook exists on Vue Devtools. Print from Devtools
Here is my store\index.js
import Vue from 'vue';
import Vuex from 'vuex';
import logbook from './logbook';
Vue.use(Vuex);
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
logbook,
},
strict: process.env.DEV,
});
return Store;
}
Here is the component
<template>
<div>
<div>
<h3>RFID</h3>
<q-btn #click="logData"
label="Save"
class="q-mt-md"
color="teal"
></q-btn>
<q-table
title="Logbook"
:data="data"
:columns="columns"
row-key="uid"
/>
</div>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
name: 'RFID',
mounted() {
this.getLogbookData();
},
methods: {
...mapActions('logbook', ['getLogbookData']),
...mapGetters('logbook', ['loadedLogbook']),
...mapState('logbook', ['logbookData']),
logData: () => {
console.log(this.loadedLogbook);
},
},
data() {
return {
};
},
};
</script>
<style scoped>
</style>
Here is the state.js
export default {
logbookData: [],
};
Error that I get on the console
Update: Solved the problem by refactoring the way I declared the function. I changed from:
logData: () => { console.log(this.loadedLogbook); }
to
logData () { console.log(this.loadedLogbook); }
Check the .quasar/app.js file. Is there a line similar to import createStore from 'app/src/store/index', and the store is later exported with the app in that same file?
I think you confused all the mapx functions.
...mapState and ...mapGetters provide computed properties and should be handled like this
export default {
name: 'RFID',
data() {
return {
};
},
mounted() {
this.getLogbookData();
},
computed: {
...mapGetters('logbook', ['loadedLogbook']),
...mapState('logbook', ['logbookData']),
}
methods: {
...mapActions('logbook', ['getLogbookData']),
logData: () => {
console.log(this.loadedLogbook);
},
}
};