Vue-i18n doesn't work properly in the data method? - vue.js

Multilingual folder i18n contents are as follows:
src
lang
cn.js
us.js
index.js
The contents of the index.js file are as follows:
import VueI18n from 'vue-i18n'
import Vue from 'vue'
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: 'cn',
messages:{
'cn': require('./lang/cn'),
'us': require('./lang/us')
}
})
export default i18n;
mina.js
import Vue from 'vue'
import App from './App'
import router from './router'
import i18n from './i18n' //import mutil-lang
Vue.config.productionTip = false
var VueCookie = require('vue-cookie');
Vue.use(VueCookie);
new Vue({
el: '#app',
router,
template: '<App />',
i18n, //import mutil-lang
components: { App }
})
I want to say the write to template tags and JS code, as follows:
<template>
<div class="wrap">
{{ $t('message.the_world') }}
</div>
</template>
and
export default {
name:'dkc-exchange-detail' ,
data(){
return {
showExchangeTypes: false,
exchangetItems: [
//this.$t('message.the_world') Want to get the character of the corresponding language
{id: 1, text: this.$t('message.the_world')},//
{id: 2, text: this.$t('message.the_world_2')}
],
}
},
}
When I switch over multilingual methods:
methods:{
choiceLang: function(lang){
if(lang === this.currentLang)
return;
this.currentLang = lang;
this.showLangSelecor = false;
this.$cookie.set('lang', this.currentLang.lang, { expires: 7 });
window.location.reload();
},
},
In template, multi language syntax behaves as expected, but JS grammar is not. It pays attention to display a certain language,Where is the problem? Thanks!

showLangSelector is spelled wrong. Also reloading the page will destruct the whole vue component and reconstruct one from scratch, so the this.foo = bar settings above reload won't work, because in the reloaded page, they never happened, you only have a fresh new vue component.

Related

access component from .js file vuejs

I am using: https://www.npmjs.com/package/vue-loading-overlay
My main.js file looks like:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
And App.vue:
<template>
<div id="app">
<loading
:active.sync= "isLoading"
:can-cancel= "false"
:is-full-page= "false">
</loading>
<router-view></router-view>
</div>
</template>
<script>
//import Vue from 'vue';
import Loading from 'vue-loading-overlay';
import 'vue-loading-overlay/dist/vue-loading.css';
//Vue.use(Loading);
export default {
data() {
return {
isLoading: true
}
},
name: 'App',
components: {
Loading
}
}
</script>
<style>
</style>
This seems to work fine, but how can I manipulate the isLoading to be true or false, from main.js? I might be building a function or something in main.js for future use, and instead of having the <loading> on each view page, I would prefer to be able to control it globally some how.
I haven't tested this, but based on the referenced answer in my comment, this might work:
main.js
new Vue({
el: '#app',
props: ['isLoading'],
components:{App},
template: '<App v-bind:isLoading="true">'
})
You would have to make isLoading a prop in App.vue. The v-bind part above should make the prop reactive.
Also, you could create a bus and send events from main.js to App.vue, then update isLoading accordingly.
You should use store for it.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let store = new Vuex.Store({
state: {
isLoader: false,
},
getters: {
isLoader(state) {
return state.isLoader
},
},
mutations: {
isLoader(state, status) {
state.isLoader = status
},
},
actions: {
isLoader({commit}, status) {
commit('isLoader', status)
},
}
})
everywhere in your application you can set the isLoader to true using dispatch
vue.$store.dispatch("isLoader", true/false);

I can't access to Vuex data: using vue-cli webpack

Right now, I'm trying to show the contents of state object from store.js on my App.vue.
I've tried vuex examples on Medium and other website, but I'm keep failing: non of them worked: some of them even gave me a WebPack config error.
My App.vue
<template>
<div id="app">
<img src="./assets/logo.png">
<h1>TEST</h1>
</div>
</template>
<script>
import Store from './store/index'
export default {
name: 'App',
Store
}
</script>
My store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
alpha: ['1st data']
},
mutations: {
ADD ({ alpha }) {
const beta = 'new!'
state.alpha.push(beta)
}
}
})
My main.js
import Vue from 'vue'
import App from './App'
import Vuex from 'vuex'
import store from './store/index'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
components: { App },
template: '<App/>'
})
You shouldn't be importing the store in App.vue. It only needs to be included in main.js and passed as an option when constructing the Vue instance. Within a component, the store is thereafter accessible via this.$store.
Second, your mutation should receive a context object as it's first parameter. context consists of properties such including state and commit. Those are the ways in which you access state within a mutation.
// notice context is the first parameter
mutations: {
ADD (context, { param }) {
const beta = 'new!'
context.state.alpha.push(beta)
})
}
// you can also deconstruct context like this
mutations: {
ADD ({state}, { param }) {
const beta = 'new!'
state.alpha.push(beta)
})
}
I also changed the way alpha to param. You don't receive the state's properties unless you destructure even further.
The problem is that in your main.js is missing Vue.use(veux)
you should have something like this:
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App'
import store from './store'
Vue.use(Vuex) // <-- Add this
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
template: '<App/>',
components: { App }
})

Vue.js 2 - How to $emit event from one application/instance Vue to an other?

I use webpack with Single File Component.
I have 1 instance of Vue in my menu header to show a Cart Shopping dropdown :
import Vue from 'vue';
import App from './AppShoppingCart.vue';
new Vue({
el: '#shoppingCartApp',
template: '<App/>',
components: {App}
});
I have an other Vue instance in the same page (the catalog with products) :
import Vue from 'vue';
import App from './AppCatalog.vue';
new Vue({
el: '#catalogApp',
template: '<App/>',
components: {App}
});
I want to $emit an event from one instance to the other :
when Catalog change, I want to call a function in ShoppingCart.
I test eventHub :
import Vue from 'vue';
var eventHub = new Vue();
export default eventHub;
So I import event on each instance :
import eventHub from './events/eventHub';
In Catalog :
eventHub.$emit( "actproductslist-changed" );
In ShoppingCart :
eventHub.$on('actproductslist-changed', function(){ alert('AppShoppingCart') } );
But this won't works. It only works if the $on and $emit are in the same instance of Vue.
I think webpack create 2 modules and I can't share variables between my 2 instances.
Any one have an idea to have global variable with multiple instance with webpack ?
This setup works, where main.js is your entry point.
bus.js
import Vue from "vue"
const bus = new Vue();
export default bus;
main.js
import Vue from 'vue'
import App from './App.vue'
import App2 from './App2.vue'
new Vue({
el: '#app',
render: h => h(App)
})
new Vue({
el:"#app2",
render: h => h(App2)
})
App.vue
<template>
<button #click="sendMessage">Send Message</button>
</template>
<script>
import Vue from "vue"
import bus from "./bus"
export default {
methods:{
sendMessage(){
bus.$emit("testing")
}
}
}
</script>
App2.vue
<template></template>
<script>
import Vue from "vue"
import bus from "./bus"
export default {
mounted(){
bus.$on("testing", ()=> alert("message received"));
}
}
</script>
Post comment edit
To communicate across entry points, you can expose the bus Vue on the window.
webpack.config.js
entry: {
"main": './src/main.js',
"main2": './src/main2.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: '[name].js'
},
bus.js
import Vue from "vue"
window.bus = new Vue();
main.js
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
main2.js
import Vue from 'vue'
import App2 from './App2.vue'
import bus from "./bus"
new Vue({
el:"#app2",
render: h => h(App2)
})
App.vue
<template>
<button #click="sendMessage">Send Message</button>
</template>
<script>
import Vue from "vue"
export default {
methods:{
sendMessage(){
if (bus)
bus.$emit("testing")
}
}
}
</script>
App2.vue
<template></template>
<script>
import Vue from "vue"
export default {
mounted(){
bus.$on("testing", ()=> alert("message received"));
}
}
</script>
Note here that since bus is only imported in main2.js, you need to guard the use of it in App.vue for those cases where it might not exist (because it is only imported in main2.js).

Vue-router can't render component correctly with Element-UI

I am trying to use Vue-router with Element-UI( http://element.eleme.io/#/en-US/component/quickstart ). But I face some weird condition. Following is my app.js, where I create my vue-router instance.
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/zh-TW'
import 'element-ui/lib/theme-default/index.css'
import myComponent from './vue/page/mycomponent.vue'
import App from './vue/app.vue'
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(ElementUI, {locale})
const router = new VueRouter({
routes: [
{path: '/mypage', component: myComponent}
],
})
const app = new Vue({
router: router,
store: store,
el: '#v-app',
render: h => h(App),
})
And I put my router-view tag in app.vue .
<template lang="pug">
#v-app
v-sidebar(:pages="pages")
router-view
</template>
<script>
import Sidebar from './sidebar.vue'
export default {
name: 'App',
data() {
return {
pages: [],
}
},
components: {
'v-sidebar': Sidebar,
},
}
</script>
<style lang="sass" scoped>
</style>
Here is my router-link in sidebar.vue.
<template lang="pug">
#sidebar
template(v-for="page in pages")
router-link(:to="{path: page.prop}")
i(class="chevron right icon")
span {{page.label}}
</template>
<script>
export default {
name: 'Sidebar',
data() {
return {
defaultProps: {
label: 'label',
children: 'children',
},
pages:[{label: 'link-1', prop: 'mypage'}]
}
},
}
</script>
If I strictly go to "/mypage" then it will render correctly. But if I click the link in my sidebar component, the page component won't render completely. I am wonder if there is somewhere I missed or what should I do to fix this kind of situation.

vue 2.0 and vue-router 2.0 build SPA, router-view did not update

Build A Single page app with vue 2 and vue-router 2 and vuex 2, but do not update
/src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'
sync(store, router)
new Vue({
router,
store,
...App
}).$mount('#app')
/src/router/index.js
import Vue from 'vue'
import routes from './routes'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
routes
})
export default router
/src/router/routes.js
import loader from './loader'
const routes = [
{ path: '/index', name: 'index', component: (r) => require(['./../views/index.vue'], r) }
]
export default routes
/src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {}
})
export default store
/src/view/index.vue
<template>
<div>
<h1>Hello index</h1>
</div>
</template>
<script>
import loader from './../../../router/loader'
export default {
name: 'index',
created () {
console.log('This is index')
}
}
</script>
/src/App.vue
<template>
<div id="app">
<router-link :to="'index'">index</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
mounted () {
console.log('Hello App')
}
}
</script>
I do not know what's wrong with the code, the <router-view> do not update when I change the route.
I think your app is not properly initialized yet. You are starting your app as follows:
new Vue({
router,
store,
...App
}).$mount('#app')
You have the spread operator ...App, which is not necessary - it is used to convert array items to function args, and not correct in this context. Instead you should use the render function as provided in webpack template :
/* eslint-disable-line no-new */
new Vue({
el: "#app",
store,
router,
render: h => h(App)
})
Also you have attempted to import loader in routes and index, which is not necessary if you are using vue-cli.
Maybe you can start with the webpack template as base and slowly add functionality one step at a time: start with route definitions and your route components, ensure that everything works, and finally add vuex.
$mount('#app') is fine, I think the problem is your routes.js
Try this instead:
import Index from './../views/index.vue'
const routes = [
{ path: '/index', name: 'index', component: Index }
]
And here is a working webpack template which is already configured vue-router and vuex properly, you can initialize this template via vue-cli, for your reference: https://github.com/CodinCat/vue-webpack-plus