Access this / vm instance from props default (VueJS) - vue.js

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.

Related

Props interdependance in VueJS

I want to add some linking dependencies between my props in my VueJS component.
For example in my component on props declaration, i would like to stipulate that if a prop is present, then another one should be required, but not required at all if the previous props is not there.
props: {
url: {
type: String,
required: true,
},
isShared: {
type: Boolean,
default: false,
},
isSharedByOtherMember: {
type: Boolean,
default: false,
},
archivedId: {
type: String,
required: isSharedByOtherMember ? true : false, // This is not working, bit is there a way to do so ?
},
After reading vuejs docs :
Note that props are validated before a component instance is created, so instance properties (e.g. data, computed, etc) will not be available inside default or validator functions.
Is there a way to still do this in props declaration for better readability/understandability after ?
Thanks in advance
You could use the validator property for prop.
Vue docs has this example: (https://v2.vuejs.org/v2/guide/components-props.html#Prop-Validation)
// Custom validator function
propF: {
validator: function (value) {
// The value must match one of these strings
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
You could define a validator method in Vue methods section.
Something like this:
export default {
props: {
isSharedByOtherMember: {
type: Boolean,
default: false
},
archivedId: {
type: String,
default: null,
required: false,
validator: this.validateArchiveId(),
errorMessage: 'Archived ID required when isSharedByOtherMember has value of true.'
}
},
methods: {
validateArchiveId () {
return this.isSharedByOtherMember
}
}
}

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!

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.

Vue prop validation is not called

I create a component with input properties:
export default {
data() {
:
:
},
props: {
rowsContent: {
type: Object,
default: null,
validator: function(value) {
console.log("In validator");
}
},
rowsPerPage: {
type: Number,
default: 10,
},
}
I tried to pass different type of parameters, and got no error message.
Moreover, no "In validator" message is printed to console.
Any idea?
I don't know the reason, but it is working if I use component tag like <tag></tag>. If I use like <tag/>, it does not work. See example here. https://codesandbox.io/s/z6rlzl998p
EDIT: Vue does not support self-closing tags as components: https://github.com/vuejs/vue/issues/8664 (as mentioned in comment)

What's the best way to use global setting?

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'] || {};
}
},
...
},
...
}