Following a simple example in VueMaster course and can't seem to read state from the store. Here's my main.js:
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
import App from './App.vue'
import router from './router'
import store from './store'
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
And here's my index.js in the /store folder:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
user: { id: 'abc123', name: 'Adam Jahr' },
},
mutations: {},
actions: {},
modules: {}
})
Then, I try and read the state object from a component:
<template>
<div>
<h1>Create an Event, {{ $store.state.user.name }}</h1>
</div>
</template>
I don't see anything in the browser for the component. Console shows an error "TypeError: Cannot read property 'name' of undefined".
Any idea why this very simple example doesn't work? Thanks.
Shouldn't your import look like this:
import store from './store/index'
since that is where you are creating your store, check the folder structure, maybe that is the problem.
I didn't see any problem with your code, it's working as expected.
Here is sandbox link - https://codesandbox.io/s/silly-poitras-sosvs?file=/src/App.vue
You need to provide the store in your component
Something in computed like
return this.$store.state.user
Related
I think i have a rare question. I've separate main.js and store.js file, so in store.js file i've imported Vuex and setup a new vuex store then exported it. After that, i've imported this file in main.js file and set up its requirement (import Vuex again in main.js and Vue.use(Vuex) here). But it doesn't work in this way. I've to write Vue.use(Vuex) inside store.js file, Otherwise it throws this error: Error: [vuex] must call Vue.use(Vuex) before creating a store instance.
main.js file:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
import App from './App.vue'
import {store} from './store/store.js';
new Vue({
el: '#app',
store: store,
render: h => h(App)
})
and store.js file:
import Vuex from "vuex";
export const store = new Vuex.Store({
state: {
counter: 0
}
});
Although i've called import {store} from './store/store.js'; after Vue.use(Vuex), so Vuex instance inside store.js file doesn't get executed before Vue.use(Vuex)
I suspect that problem is webpack based, but i can't be sure.
Change store.js to import Vue and use Vuex:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
counter: 0
}
});
Then remove Vue.use(Vuex) from main.js file:
import Vue from 'vue'
import App from './App.vue'
import {store} from './store/store.js';
new Vue({
el: '#app',
store: store,
render: h => h(App)
})
It's perfectly okay to have a use statement in store.js. This is in fact how it would be (at least at one point) generated using a tool like #vue/cli if you select the vuex option.
Hopefully that helps!
In Vue components, I can easily use imported libraries, such as vue-router. I can access the route parameter I need with this.$route.params.myVar. However, if I try to do the same within a Vuex module, I get the error: TypeError: Cannot read property 'myVar' of undefined. How can I extend the Vue object I defined in my main.js to my modules?
Here's my main.js:
import router from './router'
import Vuex from 'vuex'
import myModule from './my.module';
Vue.use(Vuex)
// Register VueX modules
const store = new Vuex.Store({
modules: {
myModule
}
})
new Vue({
router,
render: h => h(App),
store
}).$mount('#app')
And my.module.js:
export default {
namespaced: true,
state: {
...
},
mutations: {
...
},
actions: {
someAction() {
console.log(this.$route.params.myVar)
}
}
}
Obviously, this isn't defined. I tried instantiating a new Vue object at the top of my module like so:
var vm = new Vue()
And changing this to vm, but I get a similar Cannot read property 'myVar' of undefined error. I also tried re-instantiating the route class at the the module:
import route from 'vue-router'
And changing my failing code to route.params.myVar, but I still get the Cannot read property 'myVar' of undefined error.
The way I see it, you have two options.
Pass param.myvar from outside inside vuex action
Import router into vuex module and use it
For the second option make sure to import your router declaration and not the library. For example.
import router from '#/router'
router.currentRoute.params.myVar
I have tried to import and define a library globally as below, but somehow it does not recognize the global variable.
in main.js,
import Vue from 'vue'
import App from './App'
import router from './router'
import VueJwtDecode from 'vue-jwt-decode'
Vue.config.productionTip = false
Vue.use(VueJwtDecode)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
in Signup.vue,
...
const payload = VueJwtDecode.decode(res.jwt);
...
and the error shows that VueJwtDecode is not defined.
If you are trying to use the named reference of VueJwtDecode, you need to reimport the library in your Signup.vue compoenent since Signup.vue doesn't understand what VueJwtDecode means.
import VueJwtDecode from 'vue-jwt-decode'
const payload = VueJwtDecode.decode(res.jwt);
However, since you have globally installed the library, it has been installed to the Vue instance, meaning that it is available from the this context within your component. As a result, you can also access it from the component context without reimporting:
const payload = this.$jwtDec(res.jwt);
As document, in your component, you need to use
this.$jwtDec(res.jwt)
instead of
VueJwtDecode.decode(res.jwt);
I'm starting with VueRouter in Vue.js and I'm getting this errors:
[Vue warn]: $attrs is readonly.
found in
---> <RouterLink>
<SecondNav> at resources\assets\js\modules\livegame\player\SecondNav.vue
<Player> at resources\assets\js\modules\livegame\player\Player.vue
<Root>
[Vue warn]: $listeners is readonly.
found in
---> <RouterLink>
<SecondNav> at resources\assets\js\modules\livegame\player\SecondNav.vue
<Player> at resources\assets\js\modules\livegame\player\Player.vue
<Root>
I have reduced everything I could and the result is that problem is only in router. I did it according docs and I don't have any idea where is problem. Here are my components:
SecondNav.vue
<template>
<div class="row second-top-nav">
<div class="col-md-offset-1 col-md-11">
<ul class="nav">
<li>
<router-link to='/public/livegame/player/history'>
History
</router-link>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {}
</script>
Player.vue
<template>
<div>
<second-nav></second-nav>
</div>
</template>
<script>
import SecondNav from './SecondNav';
export default {
components: {
SecondNav
},
}
</script>
router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import History from './history/History';
export default new VueRouter({
mode: 'history',
routes: [
{path: '/public/livegame/player/history', component: History, name: 'player_history'},
],
linkActiveClass: "active", // active class for non-exact links.
});
Start point player.js
window.Event = new Vue();
import Vue from 'vue';
import router from './router'
import Player from './Player.vue';
let vm = new Vue({
el: '#player',
router,
components: {
Player
},
});
window.vm = vm;
I don't know where is problem or what I'm doing wrong. Everything in application seems to work without problem but these notifications doesn't look that all is right. I'm using Vue.js version 2.5.16 and VueRouter version 3.0.1.
Having multiple Vue instances can lead to this problem...
I fixed this warning: Vue warn $attrs is readonly. found in ...
by removing line: import Vue from 'vue'
while keeping: import VueRouter from 'vue-router'
Reason why it fixed: vue was being loaded twice. Vue is imported at the top of VueRouter. There's no need to import it before VueRouter.
Having multiple Vue instances can lead to this problem. In your player.js file you do you
window.Event = new Vue();
then immediately after:
let vm = new Vue({ ... })
Try removing the first new Vue, that should help. Since you are registering the router globally by calling Vue.use(VueRouter) you have two vue instances, both with their own router. When the second instance mounts and tries to register the router, since the first instance already did so, you get the readonly error.
Also import instances are hoisted to the top of the file, so although you declare window.Event = new Vue at the top, realistically the import instances are occurring before any variable declaration and assignment.
I am new to vuejs, While writing one js code inside laravel framework, I am getting error :
[Vue warn]: Unknown custom element: <app> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
App.js
import Vue from 'vue'
import Vcinfo from './Vcinfo.vue'
import router from './router'
const app = new Vue({
el: '#vcinfo',
components: { Vcinfo },
template: '<app></app>',
router
})
please suggest what to do?
This is for future reader.
I made the mistake I had to use it like this.
import Vue from 'vue'
import Vcinfo from './Vcinfo.vue'
import router from './router'
const app = new Vue({
el: '#vcinfo',
components: { Vcinfo },
template: '<vcinfo></vcinfo>',
router
})
as per this import import Vcinfo from './Vcinfo.vue'