How to set Vue component that is imported globally to have preset attributes? - vue.js

For example, I'm using vue-numeric.
Every time I need it, I always use at least this classes and attributes.
<vue-numeric
class="form-control border-input text-right"
:separator="."
:minus=false
/>
Is it possible to declare some of the attributes when registering the component, so that I don't need to type it each time I need vue-numeric?
And also that maybe one day I decided to change the class, I just need to change it in 1 file, e.g in main.js. I don't want to change it from node_modules.
I would like to do something like this.
Vue.component('vue-numeric', VueNumeric, {
class:"form-control border-input text-right",
separator:".",
minus: false
}
so then in template, I just need to add some specific attributes.
<vue-numeric v-model="price" :min=0 />

Create a functional wrapper component which applies the default prop values:
Vue.component('vue-numeric-default', {
functional: true,
render(h, ctx) {
return h('vue-numeric', Object.assign({}, ctx.data, {
// Apply default class only if no class was defined
staticClass: ctx.data.class || ctx.data.staticClass
? ctx.data.staticClass
: 'form-control border-input text-right',
// Apply default props
props: Object.assign({
separator: '.',
minus: false,
}, ctx.props),
}), ctx.children);
},
});
You could also use
{ separator: '.', ...ctx.props }
syntax instead of
Object.assign({ separator: '.' }, ctx.props)
if it is supported.

You can specify the classes in component's root element. And apply default props in mounted hook.

You can define the default value to the props methods in a component and if you
want to override it must be called it else it has the default value,
you should add below code to the "vue-numeric" component file
props: {
class: {
type: String,
default: 'form-control border-input text-right'
},
separator: {
type: String,
default: '.'
}
minus: {
type: Boolean,
default: false
}
}

Related

How do I check whether or not a typed property has a value in Vue

I'm using Vue in vanilla JS and have a property defined in my data of type string which looks like this
data() {
return {
DimensionSetting: { type : String }
}
}
I have an element in my template that I want to toggle off when a value is passed into DimensionSetting however I can't figure out how I need to check for it in the v-if logic. I tried v-if="!this.DimensionSetting" and v-if="this.DimensionSetting === undefined" and v-if="this.DimensionSetting === null". None of these make the element visible when the value is empty. What do I need to do to properly check that kind of property?
It looks like you're incorrectly mixing a data property declaration with a props declaration.
If DimensionSetting is supposed to be a public property that receives values from a parent component, it should be declared under props:
export default {
props: {
DimensionSetting: {
type: String,
}
}
}
On the other hand, if DimensionSetting is supposed to be a local property, private to the component itself, then it should be returned from data(). There is no type field like there is for props declarations:
export default {
data() {
return {
DimensionSetting: ''
}
}
}
In either case, using the ! operator on the prop should be enough to check for an empty string:
<p v-if="!DimensionSetting">Empty</p>
demo
try adding,
data(){
return{
DimensionSetting: { type : String ,default:false}
}
}
and then v-if="!DimensionSetting"

"Is not in camelCase" warning when props are individually generated from a unique object

I pass an object configObject as prop to my child component:
<custom-button v-bind="configObject" />
This object contains various properties which I define individually inside my child component in order to extract the corresponding values:
props: {
button_id: {
type: String,
default: ''
},
is_external_link: {
type: Boolean,
default: true
},
display_button: {
type: Boolean,
default: true
},
...
},
This works perfectly, but Vue complains that these props aren't in camelCase. Yet if I rename them camelCase-style (button_id -> buttonId), the data isn't passed anymore such that buttonId is empty for example.
How to resolve this dilemma?
EDIT: `configObject' looks like below.
{
button_id: '123',
text: 'blabla',
link: 'https://google.com',
is_external_link: true,
image: 'https://cdn.image.jpg',
...
}
I'm not familiar with the syntax you use to pass props, but my approach would be like this:
<custom-button :config="configObject" />
props: {
config: {
type: Object,
default: ()=>({...}) // give schema if you like.
},
},
data() {
return {
...this.config,
otherKey: "other value",
}
}
I ended up accessing, from my child component, the prop object's properties directly - configObject.property, after retrieving it the regular way:
props: {
configObject: {
type: Object,
default: null
}
},

VueJs how to set prop type to any?

I have props with defined types but I want the last one of them to accept any kind of value
props: {
Size: String,
Label: String,
Name: String,
value: Any
}
Hpw can I achieve this?
From VueJS docs:
null and undefined values will pass any type validation
Or you can use array and place in it all required types:
propB: [String, Number]
To support props type any when you have props with defined types:
props: {
custom1: null, // set as `null`
custom2: undefined, // or `undefined`
// if you need to add extra rules, simply don't set the `type` prop
custom3: {
required: true,
//... rest of your props
}
}
DEMO: https://jsfiddle.net/xa91zoyq/4/
Here is what I'm doing to pass lint validation.
You could of corse do real validation here.
There are many handy methods that lodash provides for checking types
value: {
required: true,
validator: v => true
},

Vue.js - v-model with a predefined text

I have an input attribute that I want to have text from a source and is two-way binded
// messages.html
<input type="textarea" v-model="newMessage">
// messages.js
data () {
newMessage: ''
},
props: {
message: {
type: Object,
required: true,
default () {
return {};
}
}
// the message object has keys of id, text, and hashtag
I would like the initial value of input to be message.text. Would it be appropriate to do something like newMessage: this.message.text?
EDIT
I tried adding :value="message.text" in input but that didn't really show anything
Yes, you can reference the props in the data function.
data(){
return {
newMessage: this.message.text
}
}

Vue - default values of nested properties

How can I set a default value of a nested property of a Object prop?
Apparently, Vue parse default value of nested properties only if the first level Object prop is undefined.
Example:
Vue.component('example', {
props: {
options: {
type: Object,
default: function() {
return {
nested: {
type: Object,
default: function(){
return 'default value'
}
}
}
}
}
})
Apparently, Vue parse default value of nested properties only if the
fist level Object prop is not undefined.
Yes and it makes sense because if you don't have outer object, you won't be able to have inner or nested properties.
So I think it's even more readable just set as default {} an emtpy object for the first level object and you should make your own defensive validations against undefined or null, like the bellow example:
<script>
export default {
props: {
option: {
type: Object,
default: () => {},
required: false
}
},
computed: {
optionReceived: function () {
const defaultNestedValue = 'Some default value'
const option = this.option.nested || defaultNestedValue;
return option;
}
}
}
</script>
I think it is always better to make your data structure easy to use and as flat as possible. Because nested props in Vue is never a good choice.
Assume the options you mentioned in your Vue component have a lot of properties inside.
Example:
props: {
options: {
bookAttributes: {
colorAttributes: { coverColor: 'red', ribbonColor: 'green' },
sizeAttributes: { coverSize: 10, ribbonSize: 2 },
...
}
}
}
you could make them flat like this for better comprehension.
props: {
coverSize: 10,
coverColor: 'red',
ribbonColor: 'green,
ribbonSize: 2 ...
}
And then you and your colleagues could happily use your component like this:
<your-component>
coverSize="15"
coverColor="blue"
ribbonColor="red"
ribbonSize="3"
</your-component>
Good luck and wish you well.