验证vue.js中的对象结构

时间:2017-07-12 18:21:17

标签: javascript validation vue.js

我目前正在vue.js中构建一个组件,我有点问题。你知道,你可以给我的组件提供很多参数,所以为了清楚起见,我决定采用下面的方法:

<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>

基本上,我定义了一个包含必要参数的对象,然后将其提供给我的组件。问题是我想为其中一些参数定义一些默认值,这样用户就不必全部列出它们。

现在,我已经阅读了关于Vue.js道具验证的内容,并发现它非常适合我想要做的事情。但是,虽然您可以验证prop是否是对象,但您似乎无法验证对象的结构。例如,我希望能够做到:

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

所以我的问题基本上是......有办法做到吗?

2 个答案:

答案 0 :(得分:1)

使用object binding syntax

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

这将传递所有 defaults的属性,并只验证您需要的属性。

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

否则,您可以将函数用作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,我在一个例子中无法让Vue.$noClientConf完全工作。相反,我刚刚创建了一个默认对象。

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>

答案 1 :(得分:0)

如果您想使用custom validator,最佳做法是使用Set() object

示例:

ExampleComponent 组件所需的对象输入:

const obj = {
    block1: {
      icon: 'example',
      title: 'example',
      content: 'example'
    },
    block2: {
      icon: 'example',
      title: 'example',
      content: 'example'
    }
  };

带有自定义验证程序的组件:

export default {
    name: 'ExampleComponent',
    props: {
      data: {
        type: Object,
        validator: (o) => {
          const set = new Set();
          set.add(!!(o.block1 && o.block1.icon && typeof o.block1.icon === 'string'));
          set.add(!!(o.block1 && o.block1.title && typeof o.block1.title === 'string'));
          set.add(!!(o.block1 && o.block1.content && typeof o.block1.content === 'string'));
          set.add(!!(o.block2 && o.block2.icon && typeof o.block2.icon === 'string'));
          set.add(!!(o.block2 && o.block2.title && typeof o.block2.title === 'string'));
          set.add(!!(o.block2 && o.block2.content && typeof o.block2.content === 'string'));
          return !set.has(false);
        },
      },
      color: {
        type: String,
        validator: value => ['black', 'white'].includes(value),
      },
    },
  };