'How to acccess data property inside setup in vue 3? - javascript

I am trying to access data property inside setup() in vue 3 but is giving me this error
TypeError: Cannot read property '$localStorage' of undefined
data()
data() {
return {
$localStorage: {},
}
setup
setup() {
this.$localStorage
}
How i can access this property inside setup()?

One solution would be importing getCurrentInstance from vue and use it in onMounted lifecycle or in a consumable:
import { onMounted, getCurrentInstance } from "vue";
export default {
data() {
return {
key: "test",
};
},
setup() {
onMounted(() => {
console.log(getCurrentInstance().data.key);
});
},
};
However, this usage is highly discouraged as stated in here.
Instead you could define that data property in setup using ref or reactive like this:
import { ref } from "vue";
export default {
setup() {
const $localStorage = ref({});
},
};
or
import { reactive } from "vue";
export default {
setup() {
const $localStorage = reactive({});
},
};
These solutions will work if your data and setup function will be in the same component.
If you are trying to access to a child component, you can use ref for accomplishing this task. More detailed information about ref is here

Related

Vue 3 - Options API vs Composition API - Load external file into component

I have the following file which is an external file with functions (language.js). I also have created a other component which needs to use language.js (it needs to use the languageText funcion inside language.js). I did used it in a Composition API component. But now I want to get it working in a Options API component. Please check the function inside methods called languageSelector. Inside this function I want to use the global function from language.js (languageText())
Any help?
Options API template (Form.vue)
<script>
import languageText from '#/composables/language';
export default defineComponent({
name: 'Form',
props: {
processingData: Object,
formData: Object
},
emits: ["gateway"],
components: {
Icon
},
data() {
return {
fieldData: this.formData,
}
},
methods: {
languageSelector(data) {
const h = languageText(data) **I want to USE the FUNCTION here.**
console.log(h)
return languageText(data)
},
}
language.js
import { ref, computed, watch } from 'vue';
import { useI18n } from "vue-i18n";
import { useStore } from "vuex";
export default function language() {
const store = useStore();
const i18n = useI18n();
const language = computed(() => {
return store.getters.currentUser.language;
});
function languageText(json) {
const obj = JSON.parse(json)
return obj[language.value]
}
return {
languageText
}
}

Using `useStore` API with vuex 4.x

Follow the official example to export your own useStore, and then use it in the component.
import { createStore, Store, useStore as baseUseStore } from 'vuex';
export const key: InjectionKey<Store<RootState>> = Symbol();
export function useStore() {
return baseUseStore(key);
}
use in the component
setup() {
const store = useStore();
const onClick = () => {
console.log(store)
store.dispatch('user/getUserInfo');
}
return {
onClick,
}
},
After running, store is undefined.
It can be obtained normally when I use it in the methods attribute
methods: {
login() {
this.$store.dispatch('user/getToken')
}
}
why? how to fix it
In that simplifying useStore usage tutorial, you still need to register the store and key in main.ts as they did. You will get undefined if you don't do this:
// main.ts
import { store, key } from './store'
const app = createApp({ ... })
// pass the injection key
app.use(store, key)
The reason is that baseUseStore(key) has no meaning until that's done.

vuex mapped namespaced action "is not a function," error

I am importing a Vuex module. Everything works fine if I don't namespace it, but when I do namespace it is reports that the action is "not a function." when called.
index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import MainWindow from './modules/MainWindow';
import ArtEditor from './modules/ArtEditor';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
MainWindow,
ArtEditor
}
});
ArtEditor module:
const state = {
selectedColor : "#FFFFFF"
}
const getters = {
selectedColor: state => state.selectedColor
};
const actions = {
selectColor({commit}, newColor){
commit('selectColor', newColor);
console.log(newColor)
}
};
const mutations = {
selectColor: (state, newColor) => state.selectedColor = newColor
};
export default {
namespaced: true,
state,
getters,
actions,
mutations
};
in Vue component:
import {mapActions, mapGetters} from 'vuex';
...
methods:{
...mapActions(['ArtEditor/selectColor']),
colorChanged(color){
this.selectColor(color);
}
},
...
when the color is changed, it throws the error this.selectColor is not a function. Most of the documentation on namespaced modules either doesn't import external Vuex modules, or uses dispatch() instead of mapActions(), I really don't know what I'm doing wrong.
Your syntax is off, you need to either do:
...mapActions(['ArtEditor/selectColor']),
colorChanged(color){
this['ArtEditor/selectColor'](color);
}
Or separate the action path while mapping:
...mapActions('ArtEditor', ['selectColor']),
colorChanged(color){
this.selectColor(color);
}
See binding helpers with namespace.

NuxtJS value from Vuex Store undefined

I've created a vuex store like this in Nuxt.
export const state = () => ({
id: "",
type: null,
name: null,
});
export const mutations = {
setProfile(state, profile) {
state.id = profile.idStr;
state.type = profile.type;
state.name = profile.name;
}
};
export const getters = {
name(state) {
return state.name;
}
};
The data is stored with store.commit("profile/setProfile", profile.data); and successfuly set. (Values are shown in chrome dev-tools)
Now I'm trying to access the property name in one of my components using the mapGetters method like this.
import { mapGetters } from "vuex";
export default {
computed: mapGetters({
name: "profile/name"
})
};
My problem is that the getter is not found.
ERROR [vuex] unknown getter: profile/name
What is wrong with this approach?
Do you need to use mapGetters instead of mapState?
as of now (nuxt v2.14.7) the syntax is
export default {
computed: {
...mapGetters({getName: 'profile/name'}),
}
}
then in the component the getter can be used as
this.getName;

vuex and axios debugging

I'm going crazy, I have a working api that sends data, I connected it to a VueJS app and it was working fine. I'm trying to implement Vuex and I'm stuck. Here's my store.js file
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios'
Vue.use(Vuex);
const state = {
message: "I am groot",
articles: []
}
const getters = {
getArticles: (state) => {
return state.articles;
}
}
const actions = {
getArticles: ({ commit }, data) => {
axios.get('/articles').then( (articles) => {
commit('GET_ARTICLES', articles);
console.log(articles); // Trying to debug
}, (err) => {
console.log(err);
})
}
}
const mutations = {
GET_ARTICLES: (state, {list}) => {
state.articles = list;
}
}
const store = new Vuex.Store({
state,
getters,
mutations,
actions,
mutations
});
console.log(store.state.articles); // this lines works but data is empty
export default store
The console.log within axios call doesn't run and store.state.articles is empty. I must be missing something. I'm just trying to console the articles data on page load...
Please help, I'm near insanity :)
Component :
<template>
<div class="container">
<h1>Test component yo !</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
name: 'Test',
computed: {
message() {
return this.$store.state.message
}
},
mounted: () => {
this.$store.dispatch('getArticles')
}
}
</script>
App.js :
import Vue from 'vue';
import ArticlesViewer from './articles_viewer.vue';
import UserArticles from './user_articles.vue';
import App from './app.vue'
import store from './store'
new Vue({
el: '#app-container',
store,
render: h => h(App)
})
You define the mounted lifecycle hook of your component using an arrow function.
As per the documentation:
Don’t use arrow functions on an instance property or callback (e.g. vm.$watch('a', newVal => this.myMethod())). As arrow functions are bound to the parent context, this will not be the Vue instance as you’d expect and this.myMethod will be undefined.
You should define it like so:
mounted: function () {
this.$store.dispatch('getArticles');
}
Or, use the ECMAScript 5 shorthand:
mounted() {
this.$store.dispatch('getArticles');
}
Now, your dispatch method will be called correctly, populating your articles array.

Categories

Resources