I'm already trying to translate my table header in a vue.js ponent for a few nights, but it doesn't work for me. Probably this is due the fact that I'm new to Vue.js and probably that I'm forgetting something but I'm not able to find the clue. The translation within the HTML wording is working fine, but as soon as I would like to translate an attribute within the script tag (e.g. data attributes) I'm getting console errors that certain fields cannot be found.
What I did, first I initialized the i18n ponent within the main.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
import App from './App'
import router from './router'
import axios from './api'
import VueAxios from 'vue-axios'
import VueI18n from 'vue-i18n'
Vue.use(BootstrapVue)
Vue.use(VueAxios, axios)
Vue.prototype.$axios = axios;
Vue.use(VueI18n)
// Ready translated locale messages
const messages = {
en: require('./locales/en_GB.json'),
nl: require('./locales/nl_NL.json')
}
// Create VueI18n instance with options
const i18n = new VueI18n({
locale: 'nl', // set locale
fallbackLocale: 'en',
messages // set locale messages
})
// TODO load messages async, otherwise all messages will be loaded at once: .html
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
i18n,
template: '<App/>',
ponents: {
App
}
})
Then within my script tag of the Users ponent I'm trying to translate the table header that is defined in there. However for some reason I'm getting console errors like TypeError: "o is undefined"
.
data: () => {
return {
items_data: [],
fields: [
{key: this.$i18n.t('next')}, //<-- Translate table header values
{key: 'name'},
{key: 'registered'},
{key: 'role'},
{key: 'status'}
],
currentPage: 1,
perPage: 5,
totalRows: 0
}
See full file here below:
<template>
<b-row>
<b-col cols="12" xl="6">
<transition name="slide">
<b-card :header="caption">
<b-table :hover="hover" :striped="striped" :bordered="bordered" :small="small" :fixed="fixed" responsive="sm" :items="items" :fields="fields" :current-page="currentPage" :per-page="perPage" @row-clicked="rowClicked">
<template slot="id" slot-scope="data">
<strong>{{data.item.id}}</strong>
</template>
<template slot="name" slot-scope="data">
<strong>{{data.item.name}}</strong>
</template>
<template slot="status" slot-scope="data">
<b-badge :variant="getBadge(data.item.status)">{{data.item.status}}</b-badge>
</template>
</b-table>
<nav>
<b-pagination size="sm" :total-rows="5" :per-page="perPage" v-model="currentPage" :prev-text="$t('previous')" :next-text="$t('next')" hide-goto-end-buttons/>
</nav>
</b-card>
</transition>
</b-col>
</b-row>
</template>
<script>
var usersData = null;
export default {
name: 'Test Users',
props: {
caption: {
type: String,
default: 'Users 2'
},
hover: {
type: Boolean,
default: true
},
striped: {
type: Boolean,
default: true
},
bordered: {
type: Boolean,
default: false
},
small: {
type: Boolean,
default: false
},
fixed: {
type: Boolean,
default: false
}
},
data: () => {
return {
items_data: [],
fields: [
{key: this.$i18n.t('next')}, //<-- Translate table header values
{key: 'name'},
{key: 'registered'},
{key: 'role'},
{key: 'status'}
],
currentPage: 1,
perPage: 5,
totalRows: 0
}
},
mounted() {
this.axios.getAll()
.then(response => {
//this.$log.debug("Data loaded: ", response.data)
this.items_data = response.data
}).catch(error => {
//this.$log.debug(error)
this.error = "Failed to load todos"
})
},
puted: {
items: function () {
return this.items_data;
}
},
methods: {
getBadge (status) {
return status === 'Active' ? 'success'
: status === 'Inactive' ? 'secondary'
: status === 'Pending' ? 'warning'
: status === 'Banned' ? 'danger' : 'primary'
},
getRowCount (items) {
return items.length
},
userLink (id) {
return `users/${id.toString()}`
},
rowClicked (item) {
const userLink = this.userLink(item.id)
this.$router.push({path: userLink})
}
}
}
</script>
<style scoped>
.card-body >>> table > tbody > tr > td {
cursor: pointer;
}
</style>
I would be very thankful when someone could help me to tell how I should translate these type of texts. I tried to find my solution via Google, but according to Google this is more or less how it should work.
I'm already trying to translate my table header in a vue.js ponent for a few nights, but it doesn't work for me. Probably this is due the fact that I'm new to Vue.js and probably that I'm forgetting something but I'm not able to find the clue. The translation within the HTML wording is working fine, but as soon as I would like to translate an attribute within the script tag (e.g. data attributes) I'm getting console errors that certain fields cannot be found.
What I did, first I initialized the i18n ponent within the main.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
import App from './App'
import router from './router'
import axios from './api'
import VueAxios from 'vue-axios'
import VueI18n from 'vue-i18n'
Vue.use(BootstrapVue)
Vue.use(VueAxios, axios)
Vue.prototype.$axios = axios;
Vue.use(VueI18n)
// Ready translated locale messages
const messages = {
en: require('./locales/en_GB.json'),
nl: require('./locales/nl_NL.json')
}
// Create VueI18n instance with options
const i18n = new VueI18n({
locale: 'nl', // set locale
fallbackLocale: 'en',
messages // set locale messages
})
// TODO load messages async, otherwise all messages will be loaded at once: http://kazupon.github.io/vue-i18n/guide/lazy-loading.html
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
i18n,
template: '<App/>',
ponents: {
App
}
})
Then within my script tag of the Users ponent I'm trying to translate the table header that is defined in there. However for some reason I'm getting console errors like TypeError: "o is undefined"
.
data: () => {
return {
items_data: [],
fields: [
{key: this.$i18n.t('next')}, //<-- Translate table header values
{key: 'name'},
{key: 'registered'},
{key: 'role'},
{key: 'status'}
],
currentPage: 1,
perPage: 5,
totalRows: 0
}
See full file here below:
<template>
<b-row>
<b-col cols="12" xl="6">
<transition name="slide">
<b-card :header="caption">
<b-table :hover="hover" :striped="striped" :bordered="bordered" :small="small" :fixed="fixed" responsive="sm" :items="items" :fields="fields" :current-page="currentPage" :per-page="perPage" @row-clicked="rowClicked">
<template slot="id" slot-scope="data">
<strong>{{data.item.id}}</strong>
</template>
<template slot="name" slot-scope="data">
<strong>{{data.item.name}}</strong>
</template>
<template slot="status" slot-scope="data">
<b-badge :variant="getBadge(data.item.status)">{{data.item.status}}</b-badge>
</template>
</b-table>
<nav>
<b-pagination size="sm" :total-rows="5" :per-page="perPage" v-model="currentPage" :prev-text="$t('previous')" :next-text="$t('next')" hide-goto-end-buttons/>
</nav>
</b-card>
</transition>
</b-col>
</b-row>
</template>
<script>
var usersData = null;
export default {
name: 'Test Users',
props: {
caption: {
type: String,
default: 'Users 2'
},
hover: {
type: Boolean,
default: true
},
striped: {
type: Boolean,
default: true
},
bordered: {
type: Boolean,
default: false
},
small: {
type: Boolean,
default: false
},
fixed: {
type: Boolean,
default: false
}
},
data: () => {
return {
items_data: [],
fields: [
{key: this.$i18n.t('next')}, //<-- Translate table header values
{key: 'name'},
{key: 'registered'},
{key: 'role'},
{key: 'status'}
],
currentPage: 1,
perPage: 5,
totalRows: 0
}
},
mounted() {
this.axios.getAll()
.then(response => {
//this.$log.debug("Data loaded: ", response.data)
this.items_data = response.data
}).catch(error => {
//this.$log.debug(error)
this.error = "Failed to load todos"
})
},
puted: {
items: function () {
return this.items_data;
}
},
methods: {
getBadge (status) {
return status === 'Active' ? 'success'
: status === 'Inactive' ? 'secondary'
: status === 'Pending' ? 'warning'
: status === 'Banned' ? 'danger' : 'primary'
},
getRowCount (items) {
return items.length
},
userLink (id) {
return `users/${id.toString()}`
},
rowClicked (item) {
const userLink = this.userLink(item.id)
this.$router.push({path: userLink})
}
}
}
</script>
<style scoped>
.card-body >>> table > tbody > tr > td {
cursor: pointer;
}
</style>
I would be very thankful when someone could help me to tell how I should translate these type of texts. I tried to find my solution via Google, but according to Google this is more or less how it should work.
Share asked Mar 30, 2019 at 19:04 Danny GloudemansDanny Gloudemans 2,6977 gold badges42 silver badges59 bronze badges3 Answers
Reset to default 6According to the documentation:
The fields prop is used to customize the table columns headings, and in which order the columns of data are displayed. The field object keys are used to extract the value from each item row...
meaning in your fields
property, the key's value needs to match the items
keys.
For example, first_name
:
fields: [
{ key: 'first_name'}
],
items: [
{ first_name: 'John' },
{ first_name: 'Jane' }
]
If you want to customize your headers, like translated titles, you can use label
:
fields: {
{
next: { label: this.$i18n.t('next') },
name: { label: this.$i18n.t('name') },
registered: { label: this.$i18n.t('registered') },
role: { label: this.$i18n.t('role') },
status: { label: this.$i18n.t('status') }
}
}
var usersData = null;
import i18n from 'your-path/i18n';
export default {
name: 'Test Users',
props: {
caption: {
type: String,
default: 'Users 2'
},
hover: {
type: Boolean,
default: true
},
striped: {
type: Boolean,
default: true
},
bordered: {
type: Boolean,
default: false
},
small: {
type: Boolean,
default: false
},
fixed: {
type: Boolean,
default: false
}
},
data: () => {
return {
items_data: [],
fields: [
{key: i18n.t('next')}, //<-- Add Like this, you need to recreate your ponent
{key: 'name'},
{key: 'registered'},
{key: 'role'},
{key: 'status'}
],
currentPage: 1,
perPage: 5,
totalRows: 0
}
},
mounted() {
this.axios.getAll()
.then(response => {
//this.$log.debug("Data loaded: ", response.data)
this.items_data = response.data
}).catch(error => {
//this.$log.debug(error)
this.error = "Failed to load todos"
})
},
puted: {
items: function () {
return this.items_data;
}
},
methods: {
getBadge (status) {
return status === 'Active' ? 'success'
: status === 'Inactive' ? 'secondary'
: status === 'Pending' ? 'warning'
: status === 'Banned' ? 'danger' : 'primary'
},
getRowCount (items) {
return items.length
},
userLink (id) {
return `users/${id.toString()}`
},
rowClicked (item) {
const userLink = this.userLink(item.id)
this.$router.push({path: userLink})
}
}
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<b-row>
<b-col cols="12" xl="6">
<transition name="slide">
<b-card :header="caption">
<b-table :hover="hover" :striped="striped" :bordered="bordered" :small="small" :fixed="fixed" responsive="sm" :items="items" :fields="fields" :current-page="currentPage" :per-page="perPage" @row-clicked="rowClicked">
<template slot="id" slot-scope="data">
<strong>{{data.item.id}}</strong>
</template>
<template slot="name" slot-scope="data">
<strong>{{data.item.name}}</strong>
</template>
<template slot="status" slot-scope="data">
<b-badge :variant="getBadge(data.item.status)">{{data.item.status}}</b-badge>
</template>
</b-table>
<nav>
<b-pagination size="sm" :total-rows="5" :per-page="perPage" v-model="currentPage" :prev-text="$t('previous')" :next-text="$t('next')" hide-goto-end-buttons/>
</nav>
</b-card>
</transition>
</b-col>
</b-row>
</template>
Use the Computed Property For This,Its more Efficient:
enter code here
<b-table :fields="fields" />
...
methods: {
translateCol (colName) {
return this.$i18n.t('.fields.' + colName + '.label')
}
},
puted: {
fields () {
return [
{ key: 'id', label: this.translateCol('id'), sortable: true },
{ key: 'name', label: this.translateCol('name'), sortable: true },
{ key: 'description', label: this.translateCol('description'), sortable: true },
]
}
}