I'm trying to access an action as a method in component, But got error of
this.delete_notifaction is not a function
notifaction.js
export const actions = {
add_notifaction({ commit }, notifaction) {
commit("ADD_NOTIFACTION", notifaction);
},
delete_notifaction({ commit }, notificationToRemove) {
commit('DELETE_NOTIFACTION', notificationToRemove)
}
};
store/index.js
modules : {
notifaction
},
Component.vue
methods: mapActions('notifaction',["delete_notifaction"]),
mounted() {
this.delete_notifaction(this.notification);
}
Any Help?
Try this
methods: {
...mapActions(['delete_notifaction']),
}
See here for spread syntax
https://stackoverflow.com/a/48137766/10118668
Related
Essentially, in a Vue application, I have a page that lists Contacts. And a search form that is part of a header component. I capture the input search term as a state variable in the vuex store and track it as a computed variable.
I have a method to retrieve contacts that is called within the mounted hook. I want to call the same getContacts method again whenever the state search variable changes. Using a watcher to do this atm, but I have read that watching a computed value is not the right way. Wondering if there is a better way to do this. Script below.
<script>
import API from '#/utils/Api.js'
...
export default ({
...
tableData: [],
}
},
computed: {
search() {
return this.$store.getters.search;
}
},
mounted() {
this.getContacts();
},
methods: {
async getContacts() {
try {
const {data} = await API.get('/contacts?search=' + this.search)
this.tableData = data
} catch (e) {
console.error(e)
}
}
},
watch: {
search () {
this.getContacts();
}
}
})
</script>
Try to watch directly the state item and then pass the new value as parameter for the method, then use immediate:true to replace the mounted hook call :
export default ({
...
tableData: [],
}
},
methods: {
async getContacts(val) {
try {
const {data} = await API.get('/contacts?search=' + val)
this.tableData = data
} catch (e) {
console.error(e)
}
}
},
watch: {
'$store.getters.search': {
handler(newVal)
this.getContacts(newVal);
},
immediate:true
}
}
})
What is the best way to use this data from the Vuex store's Action in the needed component?
import axios from 'axios'
export default {
namespaced: true,
state: {
items: []
},
actions: {
fetchCategories ({state, commit}) {
return axios.get('/api/v1/categories')
.then(res => {
const categories = res.data
commit('setItems', {resource: 'categories', items: categories}, {root: true})
return state.items
})
}
}
}
Component
export default {
components: {
ThreadCreateModal,
ThreadList
},
data () {
return {
...
}
},
computed: {
...
},
created () {
...
},
methods: {
...
}
</script>
Where and how should I use that action for binding the data in this component?
Use mapState by import it from vuex and call it in computed:
computed: {
...mapState(['items']), // if you dont use namespace
...mapState("your_module_name", ['items'] ) // if you use namespace
},
then you can access it by this.items.
However, you can access it directly this.$store.state.items
I have several differents files for a lot of modules.
Some of the share the same action name
There is some page that use 2 or more mapActions for different modules
On my page is something like this:
methods: {
...mapActions({
documents: ['setDocumentImage'],
documentAddress: ['setDocumentImage'],
selfie: ['setDocumentImage']
}),
}
All my modules have a action setDocumentImage
But the problem is that i have to invoke them like: this.setDocumentImage(file)
Is there a way to create an alias for each one of these mapAction that my page can differentiate?
Or how can I fix it?
Yes there is a way ! Here you are :
methods: {
...mapActions('documents', { setDocumentImage: 'setDocumentImage' }),
...mapActions('documentAddress', { setDocumentAddressImage: 'setDocumentImage' }),
...mapActions('selfie', { setSelfieDocumentImage: 'setDocumentImage' }),
}
You can use namespacing if you are using modules in composing your store.
Something like this:
const moduleA = {
namespaced: true, //namespacing set to true.
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
namespacedModuleA: moduleA,
b: moduleB
}
})
Then in your mapAction you can do this :
methods: {
...mapActions({
actionOfA: ['nameSpacedModuleA/actionOfA'],
actionOfB: ['actionOfB'],
}),
}
If you do not want to use mapActions, you can also do
this.$store.dispatch('nameSpacedModuleA/actionOfA')
More on namespacing with modules here
I am trying to use a global eventbus in VueJs but have been unsuccessful so far.
I have the following code. When I navigate from ResetPassword to Login screen, I should see the successMessage with a Your password has been changed successfully. Please login to continue but it always shows a blank.
What could I be doing wrong?
plugins.js:
Vue.prototype.$eventHub = new Vue();
ChangePassword.vue:
methods:
{
ChangePassword()
{
this.$eventHub.$emit('navigation-message', 'Your password has been changed successfully. Please login to continue.');
this.$router.push({ name: 'login'});
},
},
Login.vue:
data() {
return {
successMessage:'',
};
},
created ()
{
this.$eventHub.$once('navigation-message', this.successMessage);
},
beforeDestroy()
{
this.$eventHub.$off('navigation-message');
},
Update: 12/8/2019: I changed the login.vue as per comment by #tony19 but the issue still exists.
Login.vue:
created ()
{
this.$eventHub.$once('navigation-message', (payload)=>
{
updateSuccessMessage(payload);
});
},
methods:
{
updateSuccessMessage(payload)
{
this.successMessage=payload;
},
You need to add this.
created () {
this.$eventHub.$on('navigation-message', payload => {
this.updateSuccessMessage(payload)
})
},
methods: {
updateSuccessMessage(payload) {
this.successMessage = payload
}
}
Also make sure you're actually importing plugin.js globally (e.g. inside your main file where you import Vue) and make sure your components have access to it.
Try this:
created() {
console.log(this.$eventHub)
}
I am new to both vue.js and vuex. I have a component that need to dispatch an action when a specific data is available in the state. How can I do this.
Example:
export default {
name: 'MyComponent',
computed: {
targetItem() {
return this.$store.getters.getTarget(this.$route.params.id);
}
}
}
In the example above i would like to dispatch a new action on the store when targetItem has a value. This is so i can trigger an ajax request via a vuex action to collect more data about targetItem
Thanks
I eventually found a solution that work
export default {
name: 'MyComponent',
computed: {
targetItem() {
return this.$store.getters.getTarget(this.$route.params.id);
}
},
watch: {
shop (newVal, oldVal) {
if(!!newVal && !oldVal) {
const {targetItem} = this;
this.$store.dispatch('ACTION_NAME',{targetItem});
}
}
}
}
Thanks