What's the best way to use global setting? - vuejs2

I wanna a vue component's prop has a global default value if its not setting. Follow bellow I use window['globalClasses'] to get the global setting. But I know in server side, window is not exists. So what's the best way to get the global setting.
export default {
props: {
classes: {
type: Object,
default() {
return window['globalClasses'] || {};
}
},
...
},
...
}

Related

Where to store the object with methods in Vue?

What's the right way to store complex objects with methods in Vue? For example, the following object:
const behavior = {
onClick() {
console.log('click')
},
onDoubleClick() {
console.log('double click');
},
onMounted() {
console.log('mounted')
},
beforeMounted() {
console.log('before mounted')
},
// and so on
}
It's needed to pass to my custom component:
<custom-component :behavior="behavior"/>
It's need to note: it's not the appropriate approach to pass each method through props, because behavior might change dynamically.
You should probably use mixins for this. Check out the docs.

How to compute a property based on an object with fallback

I have a component that receives an object as prop, like this:
props: ['propObject']
Then, there's a default object defined (I use VueX, so it's actually defined as a $store getter, but to make it simpler, let's say it's defined in the data method) in the data:
data() {
return {
dataObject: {defaultValueA: 1, defaultValueB: 2}
}
}
And I'd like to have a computed property that would behavior like this:
computed: {
computedObject() {
return Object.values(this.propObject).length > 0 ? this.propObject : this.dataObject;
}
}
However, I know this is not possible because Vue watchers don't watch for changes in the key/value pairs of an object.
I have tried to go with a watched property, like this:
props: ['propObject'],
data() {
return {
object: {},
defaultObject: {}
}
},
watch: {
propObject: {
handler: function() {
this.setComputedObject();
},
deep: true
}
},
methods: {
setComputedObject() {
this.object = Object.values(this.propObject).length > 0 ? this.propObject : this.defaultObject;
}
},
mounted() {
this.setComputedObject();
}
However, the watcher handler is not being called at all when the propObject changes, but if I call it directly via console, it works. Is there any way that I can make the computedObject become reactive?
you need to use Vue.set/vm.$set where you change the props (in source component)
for example
changeProp(){
this.$set(propObject,'newprop','newval');
}
and then just you regualr compouted in the target component (the component which receive the prop)
source : https://v2.vuejs.org/v2/guide/list.html#Object-Change-Detection-Caveats

How to pass a prop with a default value in case the prop is empty without using the prop's "default" property

I'm using a third party multi-language package where translation values can only be obtained/used from component's template, not from component's logic (at least I can't find how to the latter).
I need to pass such translation value in some component as a default prop value:
:placeholder="{ propValue ? propValue : $t('value') }
If placeholder is explicitly specified then use that. If not, use $t('value') instead. What's the right way to write this?
I tried this in reaction to #Michael's answer:
import i18n from "#/utilities/i18n";
export default {
data() {
return {
test: i18n.t('register.agreeTermsCaptionLink')
};
}
};
Getting this error:
_utilities_i18n__WEBPACK_IMPORTED_MODULE_7__.default.t is not a function
Solution 1
Just remove brackets from prop expression: :placeholder="propValue ? propValue : $t('value')"
Sotution 2
More complicated but helps to keep templates cleaner...
where translation values can only be obtained/used from component's template, not from component's logic
With vue-i18n you can of course obtain translation directly in code by using $t function injected into your component instance like this: this.$t('key.to.translation')
Only problem is, this is not possible to use to initialize props default values because this is just not available there.
But $t in fact just returns instance function of VueI18n global object. So if you setup your VueI18n like this:
import Vue from "vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
const messages = {
en: {
messages: {
placeholder: "Placeholder"
}
},
cz: {
messages: {
placeholder: "Zástupný symbol :)"
}
}
};
export default new VueI18n({
locale: "en",
messages
});
You can do this to provide translation as default value of your prop:
import i18n from "../i18n";
export default {
name: "HelloWorld",
props: {
placeholder: {
type: String,
// default: this.$t("value") - Wont work as `this` is not Vue instance
default: i18n.t("messages.placeholder")
}
}
};
Demo
You can set default value to prop like this:
props: {
propValue: {
type: String,
default: this.$t('value')
}
}
With that in your template you need just to assign that value like: :placeholder="propValue"
Is that what you trying to achive?
Good luck!

Access this / vm instance from props default (VueJS)

I have a plugin that sets some variables to vue's object prototype.
I need to access these variables from a prop's default property. How
can I achieve this?
Using the following example, webpack throws some undefined error.
//...
props: {
size: {
type: String,
required: false,
default: this.$myPlugin.size
}
}
For Vue 2, you can specify the default as a function that returns the default value. That should have access to the current instance as this.
props: {
size: {
type: String,
required: false,
default () {
return this.$myPlugin.size
}
}
}
The relevant line in the Vue source code is here if you're curious. Note that the function is explicitly called with vm as its this value.

Vue data variable not updating after language change

I have a data variable as follows:
data(){
return {
amount: {
active: false,
name: this.$i18n.t('key_name'),
value: this.$i18n.t('key_value')
}
}
}
The data variable is using localized string. The issue is that, when I change the language from a dropdown, the amount variable is not updating until any other event occurs. I believe this has something to do with the $nextTick().
But not sure how to handle this properly as to have the changes reflected immediately in the amount variable.
I can't make it as a computed property as I've to assign values to this variable at a later point.
like this:
this.amount.active = true
How can I solve this?
It's hard to tell how you use Vue i18n, but you can use a watcher as it is stated in the docs and watch for the global i18n.locale object, something like:
<script>
export default {
name: 'app',
data () {
return {
amount: {
active: false,
name: this.$i18n.t('key_name'),
value: this.$i18n.t('key_value')
}
}
},
watch: {
this.$i18n.locale (val) {
this.amount.active = true
}
}
}
</script>
Depends how it's configured in your project.