Vue, i18n and vue-meta how to make integration? - vuejs2

how to do that when changing the site language, the meta page also changed?
I use
vue-i18n - https://kazupon.github.io/vue-i18n/
vue-meta - https://www.npmjs.com/package/vue-meta.
App.vue
export default {
name: 'Name',
metaInfo: {
title: 'Title', // set a title
titleTemplate: '%s - title', // %s required
htmlAttrs: {
lang: 'ru',
amp: undefined // "amp" has no value
},
meta: [
{ 'name':'og:title',
'content': 'title',
},
{ 'name':'metatitle',
'content': 'title',
},
{ 'name':'og:description',
'content': 'Description',
},
{ 'name':'description',
'content': 'Description',
}
]
},
data(){return{ }},
mounted() {}

Instead of defining metaInfo as an object, define it as a function and access this as usual.
export default {
metaInfo () {
return { title: this.$t("home.title") }
}
}
Et voilĂ  ! :)

Related

Why props default is not working when I'm trying to use a default title when no props are passed?

I want to show the default title "Introduction Props" in the tag when no props are provided. but I'm getting "Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'title')" error.
<p>{{ section.title }}</p>
export default {
props: {
section: Object,
default: {
type: "section",
title: "Introduction Props",
desc: "",
children: [
{
type: "lecture",
title: "Introduction",
},
],
}
},
};
you have to rearrange your props:
export default {
props: {
section: {
type: Object,
default: () => {
type: "section",
title: "Introduction Props",
desc: "",
children: [
{
type: "lecture",
title: "Introduction",
}
]
}
},
};

Vue2 trying to set chart title

Does not work like this:
<template>
<Bar
:chart-options="chartOptions"
:chart-data="$attrs['chart-data'] || chartData"
:chart-id="chartId"
:dataset-id-key="datasetIdKey"
:plugins="plugins"
:css-classes="cssClasses"
:styles="styles"
:width="width"
:height="height"
/>
</template>
<script>
import { Bar } from 'vue-chartjs/legacy'
import 'chart.js/auto'
export default {
name: 'BarChart',
components: { Bar },
props: {
chartId: {
type: String,
default: 'bar-chart',
},
datasetIdKey: {
type: String,
default: 'label',
},
width: {
type: Number,
default: 400,
},
height: {
type: Number,
default: 400,
},
cssClasses: {
default: '',
type: String,
},
styles: {
type: Object,
default: () => {},
},
plugins: {
type: Object,
default: () => {},
},
},
data() {
return {
chartData: {},
chartOptions: {
responsive: true,
title: {
display: true,
text: 'Custom Chart Title',
},
},
}
},
}
</script>
tried editing even with this: https://codesandbox.io/s/exciting-ully-2wst65?file=/src/components/Bar.vue
but nothing works.
All info gathered from: https://vue-chartjs.org/api/
Registration of components are not needed if you import auto.
maybe some ideas?
You are using v2 syntax in v3, the internal plugins like the tooltip, title, legend and decimation have been moved from the options namespace to the options.plugins namespace.
So you need to nest the title options in a plugins object within the options object. Then it will work
For those like me, who are looking for a solution using vue-chartjs V4.
To show the Title you need to pass the plugin object, for example:
plugins: {
type: Array,
default: () => [Title]
}
and then pass into the chartOptions props the title configuration, for example:
chartOptions: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: "Chart Title",
},
},
}
sandBox full example:

How to track changes in a property stored in Vuex(store) and perform some method based on the value?

I'm trying to change the links based on the variable user_role which is stored in Vuex(store). I'm not able to find an appropriate way to track the change and based on its value I want to perform some method. Any suggestions on how to do it?
------------------------------store.js-------------------------------
export default new Vuex.Store({
state: {
user_role: "User"
},
mutations: {},
actions: {},
modules: {}
});
-----------------------------------component.vue---------------------------
export default {
name: "Navbar",
data() {
return {
links: [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "", route: "" },
{ text: "Resources", route: "/resources" }
],
pers_actions: ["Profile", "LogOut"],
};
},
watch: {
user_role: {
if (user_role === "PM") {
this.links[2] = {
text: "Allocations",
route: "/allocations"
};
} else if (user_role === "PMO") {
this.links[2] = {
text: "Reports",
route: "/reports"
};
} else if (user_role === "User") {
this.links = [
{
text: "Allocations",
route: "/allocations"
}
];
}
}
},
Rather than explicitly mutating your local data in response to some state change, it is better to compute your links within a computed property because it will automatically update whenever some dependent data has changed. It'll "just work".
computed: {
links() {
switch (this.$store.state.user_role) {
case: "PM": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Allocations", route: "/allocations" },
{ text: "Resources", route: "/resources" },
];
case: "PMO": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Reports", route: "/reports" },
{ text: "Resources", route: "/resources" },
];
// For any other role
default: return [
{ text: "Allocations", route: "/allocations" },
];
}
}
}

How to add a submenu to a structure like this in the description - Vue, Quasar

I am trying to add a submenu from a javascriot file.
Default menu works perfectly, but I don't know if it is possible to assign a submenu using that same structure.
export const getTabsMdl = () => {
let r = null
r = [
{ name: 'Saldo', icon: 'receipt', to: '/saldo' },
{ name: 'Vendas', icon: 'receipt', to: '/vendas' },
{ name: 'Account', icon: 'assignment', to: '/conta' },
{ name: 'Clients', icon: 'supervisor_account', to: '/clientes' },
{ name: 'More', [{ name: 'Sub-Item', icon: 'autorenew', to: '/sub-01' }] }
return r
}
<q-route-tab
v-for="(bTab, bTIndex) in getTabsMdl()"
:to="bTab.to"
:label="bTab.name"
:name="bTab.name"
:icon="bTab.icon"
:key="bTIndex"
no-caps
/>
In Quasar, you can define hierarchy of menus.
Please check this one.
https://github.com/quasarframework/quasar/blob/dev/docs/src/examples/QMenu/MenuInMenu.vue

Vue.js vuetify i18n : How to translate dynamically the Toolbar items?

I don't have any problem in localizing the components and views strings but I am lock into finding a way to localize dynamically the Toolbar items ( and of course the same items in the navigation drawer..
Currently they are displayed in App.vue as menuItems[i].title
<v-toolbar-items class="hidden-xs-only">
<v-btn flat :to="menuItems[0].link">
<v-icon left>{{ menuItems[0].icon }}</v-icon>
<span>{{ menuItems[0].title }}</span>
</v-btn>
with the script:
<script>
export default {
data () {
return {
appName: 'myAPP',
sideNav: false,
menuItems: [
{ icon: 'home', title: 'Home', link: '/home' },
{ icon: 'info', title: 'About', menu: [{ title: 'Company', link: '/company' }, { title: 'Office', link: '/office' }] },
{ icon: 'people', title: 'Members', menu: [], link: '/members' },
{ icon: 'local_library', title: 'Blog', link: '/blog' },
{ icon: 'local_grocery_store', title: 'Shopping', link: '/shopping' }
]
}
},
methods: {
switchLocale: function (newLocale) {
this.$store.dispatch('switchI18n', newLocale)
}
}
}
</script>
Should I use a computed value ? or use directly $t() in the template ?
feedback, advices and links appreciated
UPDATE
main.js
Vue.filter('translate', function (value) {
if (!value) return ''
value = 'lang.views.global.' + value.toString()
return i18n.t(value)
})
locales/i18n/en_US
{
"views": {
"global": {
"Home": "Home",
"Section1": "Section 1",
..
Vue provides filter to help us to format the common text.
So I think it will be one of your choices.
You can click above link to follow the guide to set up your filters.
Edit:
I just realized Vue-filters should not be dependent on this context as the Vue author said. So updated my answer as below:
Then the codes will be like below:
// create vue-i18n instance
const i18n = new VueI18n({
locale: getDefaultLanguage(),
messages: langs
})
// create global filter
Vue.filter('myLocale', function (value) {
return i18n.t(value)
})
In your views or components:
<template>
<v-toolbar-items class="hidden-xs-only">
<v-btn flat :to="menuItems[0].link">
<v-icon left>{{ menuItems[0].icon }}</v-icon>
<span>{{ menuItems[0].title | myLocale }}</span>
</v-btn>
</template>
<script>
export default {
data () {
return {
appName: 'myAPP',
sideNav: false,
menuItems: [
{ icon: 'home', title: 'Home', link: '/home' },
{ icon: 'info', title: 'About', menu: [{ title: 'Company', link: '/company' }, { title: 'Office', link: '/office' }] },
{ icon: 'people', title: 'Members', menu: [], link: '/members' },
{ icon: 'local_library', title: 'Blog', link: '/blog' },
{ icon: 'local_grocery_store', title: 'Shopping', link: '/shopping' }
]
}
},
filters: {
myLocaleWhichNotWork: function (value) {
return this.$t(value) // this won't work because filters should not be dependent on this context
}
}
}
</script>