Passing multiple properties in vuejs - vue.js

I'm quite new with VueJS. I'm working on a new project with VueCLI3 & VuetifyJS.
I'm trying to create a reusable components based on VuetifyJS components and would like to make things easier by passing multiple props in a separate file to render them at once in my new component files.
I found this article that explains a technique to achieve such thing.
https://alligator.io/vuejs/passing-multiple-properties/
Every time I need to render them I must import my seperate file.
component1.vue
<template>
<v-btn v-bind='buttonProps'>
Button 1
</v-btn>
</template>
<script>
import { buttonProps } from './props.js';
export default {
data: () => ({ buttonProps })
}
</script>
component2.vue
<template>
<v-btn v-bind='buttonProps'>
Button 2
</v-btn>
</template>
<script>
import { buttonProps } from './props.js';
export default {
data: () => ({ buttonProps })
}
</script>
Is there any way to register the file globally so it allows me to use it anywhere in the app like this?
props.js
export const buttonProps = {
color: 'primary',
small: true,
outline: true,
block: true,
ripple: true,
href: 'https://alligator.io'
}
main.js
import Props from 'props.js';
component3.vue
<template>
<v-btn v-bind='buttonProps'>
Button 3
</v-btn>
</template>
<script>
... // no import needed
</script>

You can use a mixin and register that mixin globally.
buttonPropsMixin
export default {
data() {
return {
buttonProps: {
color: 'primary',
small: true,
  outline: true,
block: true,
ripple: true,
href: 'https://alligator.io'
}
}
}
}
main.js
import buttonPropsMixin from '...';
Vue.mixin(buttonPropsMixin)
Note That each vue component has its own buttonProps, so if you change in one component the color it will not affect the other components!
If you want buttonProps to have the same state across all your components you can go the vuex way as Igor mentioned and use it with an mixin where you define the mapGetters in that mixin.

If data in props.js doesn't need to be reactive and all the components are children of some root component you could do this:
main.js:
import buttonProps from 'props.js';
new Vue({
el: rootComponentElement,
buttonProps: buttonProps,
render: h => h(rootComponent)
})
component.vue:
<template>
<v-btn v-bind='$root.$options.buttonProps'>
Button 3
</v-btn>
</template>
<script>
... // no import needed
</script>
Otherwise I would advice you to use Vuex or use the global bus method described here.

Related

Can't use a custom element even if it is registered

I have to use a custom element in my project, and it used to work perfectly.
I am now changing the design of the project so I'm restarting it from zero, and now I can't use a custom component.
I haven't changed anything in the custom element itself.
Here is the code for hte page where i want to use the element:
<template >
<v-app>
<body>
<v-img id="background" :src="images.background"></v-img>
<v-img id="logo-transparent" :src="images.logoTransparent"></v-img>
<DraggableDiv class="dragdiv">
<template>
</template>
</DraggableDiv>
</body>
</v-app>
</template>
And here is the script part:
import DraggableDiv from '../components/DraggableDiv.vue'
export default {
name: 'CreationCouches',
data: () => ({
components: {
DraggableDiv,
Palette
}
})
Can you help me ?
In fact I was adding the component into the data() but it has to be outside of it:
import DraggableDiv from '../components/DraggableDiv.vue'
export default {
name: 'CreationCouches',
data: () => ({
//some data
}),
components: {
DraggableDiv,
Palette
}
}

Vuetify v-switch not toggling visually

I'm using v-swich component in one of my child components.
The component itself is rendered at view but when i click on it the toogle doesn't
change the state visually.
I followed this Tutorial to import v-switch manually into child component
https://vuetifyjs.com/en/customization/a-la-carte/#manually-importing
Child Component
<template>
<v-switch v-model="switch1" :label="`Switch 1: ${switch1.toString()}`"></v-switch>
</template>
<script>
import { VSwitch } from 'vuetify/lib'
export default {
name: 'Configurator',
components: {
VSwitch
},
props: ['product', 'variants'],
data()
{
return {
switch1: true
}
}
}
</script>
Main.js
import Vue from 'vue';
import ConfiguratorApp from './components/Configurator.App';
let vm = new Vue({
el: '#configurator-app',
render: h => h(ConfiguratorApp)
});
So what i'm missing here?
Vuetify needs its wrapper v-app in order to function properly.
<template>
<v-app>
<v-switch v-model="switch1" :label="`Switch 1: ${switch1.toString()}`"></v-switch>
</v-app>
</template>
Just add that as your app's root component.

ag-grid in vue display custom component when loading the rows

Am trying to display the v-progress-circular vuetify component when ag-grid is loading the rows, i have been following the ag-grid documentation but that doesn't seems to work. the ag-grid documentation for vue seems to be outdated so i don't know what to do. What i have done so far is the following:
TableProgress.vue
<template>
<v-progress-circular :value="20" color="primary" indeterminate>
</v-progress-circular>
</template>
<script>
export default {
name: 'TableProgress'
}
</script>
MyTable.vue (Relevant parts)
<template>
<ag-grid-vue
:grid-options="gridOptions"
class="ag-theme-material"
:frameworkComponents="frameworkComponents"
:loadingOverlayComponent="loadingOverlayComponent"
/>
</template>
<script>
import TableProgress from "./TableProgress";
export default{
data(){
return{
gridOptions: null,
frameworkComponents: null,
loadingOverlayComponent: null
}
},
beforeMount () {
this.frameworkComponents = {
tableProgress: TableProgress
}
this.gridOptions.loadingOverlayComponent = 'tableProgress'
this.loadingOverlayComponent = 'tableProgress'
},
}
</script>
What am i doing wrong here? Or is it that this simply doesn't work on vue?
I think the attribute is overlayLoadingTemplate in ag-grid instead of loadingOverlayComponent. Kindly visit ag-grid overlays to see how you can add loader to your ag-grid table
You import the TableProgress but you don't use it. You must add it in components.
<script>
import TableProgress from "./TableProgress";
export default {
components: {
TableProgress
},
//...
}
</script>

vue-i18n $t with values attribute is not translating

I am trying to import a .json file to use as the translation file.
<template>
<template v-slot:footer>
<div>{{ $t('menu.file.new.label', $i18n.locale, locale) }}</div> <--Issue outputs menu.file.new.label
</template>
</template>
<script>
import locale from '#/locales/modules/messaging.json'
export default {
data() {
return {
locale: locale
}
}
}
</script>
the locale from messaging.json does not have any errors and works if i instead added the following to the top
<i18n src="#/locales/modules/messaging.json"></i18n>
and changed the function parameters to exclude $i18n.locale and locale and it works. Unfortunately, this is not an option as i want to pass the data to a grandchild component. However, if i can configure the grandchild to use their grandparents translation data that works too..
how can i get either:
The above to work
Alternatively, use the grandparents translation data in the grandchild
Alternatively, dynamically import translation data in the grandchild based on a prop(location of translation file to be imported)
Thanks
First of all, you should create a plugin like below:
src/plugins/i18n.js:
import Vue from 'vue';
import VueI18n from 'vue-i18n';
const DEFAULT_LOCALE = 'en';
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: yourLocale || DEFAULT_LOCALE, // set locale either from localStorage or config
fallbackLocale: DEFAULT_LOCALE,
messages: require('messages.json'), // set locale messages
sharedMessages: require('other.json if exist'),
silentFallbackWarn: true,
});
export default i18n;
Then call it from main.js to globalize:
import i18n from './plugins/i18n.js';
...
new Vue({
i18n,
router,
...
render: h => h(App),
}).$mount('#app');
Then if you want to go on with custom messages, you can set it with i18n block like:
<script>
data(){
...
}
methods: ...
i18n: {
messages: require(your json path....)
}
</script>
Then you can call it like:
$t('test');
I found a solution
<template>
<st-age v-bind:menus="menu" v-bind:locale="locale[$i18n.locale].menu">
<template v-slot:content>message: {{ $route.params }}</template>
<template v-slot:footer>
<div>{{ $t('menu.file.label') }}</div>
</template>
</st-age>
</template>
<script>
import menu from './menu'
import locale from '#/locales/modules/messaging.json'
export default {
data() {
return {
menu: menu,
locale: locale
}
},
i18n: {
messages: locale
},
components: {
'st-age': () => import('#/components/layout/stage/container')
}
}
</script>
<style>
</style>
locale[$i18n.locale].menu is passing the translation data i actually need and not the entire object(which works too)
in the child component, i just pass this data as a prop to the grandchild
in the grandchild i
mounted() {
this.$i18n.setLocaleMessage(this.$i18n.locale, this.locale)
}
where this.locale is the translation data and $t('file') yields whatever i set as en.menu.file in the global translation data originally imported

How to hide a paragraph using v-if through vuex?

I am trying to create a small app in which i can click on the button and hide the paragraph but i am trying to implement that using vuex.I have a paragraph in my Home.vue file and a button in my About.vue File. I want the paragraph hide conditionally in the click of the button but i want to accomplish that using vuex. How would i do that? My store.js, home.vue and About.vue are as follows.
This is how my store looks like.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
show:true,
},
mutations: {
toggle : state => {
state.show = !state.show
}
},
actions: {
}
})
This is the Home.vue file
<template>
<p>This needs to disappear</p>
</template>
<script>
import {mapMutations} from "vuex"
export default {
computed : {
...mapMutations ([
"toggle"
])
}
}
</script>
This is the About.vue file
<template>
<div>
<button #click="toggle">Click Me</button>
</div>
</template>
<script>
import {mapMutations} from "vuex"
export default {
computed : {
...mapMutations ([
"toggle"
])
}
}
</script>
the mapMutations should be used in methods not in computed property :
methods:{
...mapMutations ([
"toggle"
])
}
like you see in the official docs :
You can commit mutations in components with this.$store.commit('xxx'), or use the mapMutations helper which maps component methods to store.commit calls (requires root store injection):