Skip to content
Advertisement

Validating object structure in vue.js

I’m currently building a component in vue.js and I have a bit of a problem. You see, there’s a lot of parameters you can give to my component, so for the sake of clarity, I decided to go with the approach below:

<script type="text/javascript">
    Vue.$noClientConf = {
    'cmp_name':         'NoClient', 
    'cmp_title':        'Selection du client',
    'url':              'ajax/getclients.php',
    'parent':           null,
    'opt_texte':        'NomClientFR',
    'opt_valeur':       'NoClient',
    'cmp_max_options':  3,
    'opt_custom':       null,
    'data_size':        10,
    'data_style':       'btn btn-default btn-sm',
    'data_live_search': 'true'
    };
</script>

<div id="app">

  <div class="col-lg-2">
    <flex-select ref="NoClient" :conf="Vue.$noClientConf"></flex-select>
  </div>

</div>

<script type="text/javascript">
    var app = new Vue({
      el: "#app",
      data:{Vue}
    });
</script>

Basically, I define an object containing the necessary parameters and I give that to my component. The thing is that I’d like to define some default values for some of these parameters so that the user wouldn’t have to list them all.

Now, I’ve read about Vue.js props validation and find it would fit extremely well with what I’d like to do. However, while you can validate if a prop is an object, it doesn’t seem like you can validate the object’s structure. For example, I’d like to be able to do:

props: {
        config.cmp_name: {
            type:String,
            required: true
        },
        config.cmp_title:{
            type:String,
            required: true
        }
    }

So my question is basically… is there a way to do the above?

Advertisement

Answer

Use the object binding syntax.

<flex-select ref="NoClient" v-bind="defaults"></flex-select>

That will pass all the properties of defaults and just validate the ones you need.

props: {
  cmp_name: {
    type:String,
    required: true
  },
  cmp_title:{
    type:String,
    required: true
  }
}

Otherwise you can use a function as a custom validator.

props:{
  conf: {
    validator(config){
      let cmp_name = config.cmp_name && typeof config.cmp_name === "string"
      let cmp_title = config.cmp_title && typeof config.cmp_title === "string"
      return cmp_name && cmp_title
    }
  }
}

FWIW, I’m not able to get Vue.$noClientConf to work at all in an example. Instead, I just created a defaults object.

console.clear()

const defaults = {
  'cmp_name':         'NoClient', 
  'cmp_title':        'Selection du client',
  'url':              'ajax/getclients.php',
  'parent':           null,
  'opt_texte':        'NomClientFR',
  'opt_valeur':       'NoClient',
  'cmp_max_options':  3,
  'opt_custom':       null,
  'data_size':        10,
  'data_style':       'btn btn-default btn-sm',
  'data_live_search': 'true'
};

Vue.component("flex-select",{
  props: {
  cmp_name: {
    type:String,
    required: true
  },
  cmp_title:{
    type:String,
    required: true
  }
},
  template:`
    <div>{{cmp_name}} {{cmp_title}}</div>
  `
})

new Vue({
  el:"#app",
  data:{
    defaults
  }
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
  <flex-select v-bind="defaults"></flex-select>
  {{defaults}}
</div>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement