vue组件开发props验证的实现

使用props

在Vue中父组件向子组件中传送数据是通过props实现的,一个简单的使用props的例子:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component :foo-message="fooMessage"></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: ['fooMessage'],
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 123
    }
  });

</script>
</body>
</html>

为什么要有props验证

但是上面这种方式是建立在大家都很遵守约定的情况下的,想象一下当有一个人要使用foo-component组件的时候,他可能对于其要接受的参数有什么要求并不是很清楚,因此传入的参数可能会在开发子组件的人的意料之外,程序就会发生错误,就像我们在函数调用之前先检查一下函数一样,props也可以进行一个预先检查。

平时调用函数的时候在函数开头的地方都是一坨糊糊的参数检查,这种写法很不好了,所有后来就有了校验器模式(别去百度了,我随口取的名字),校验器模式就是指把在函数开头的对参数校验的部分提取出来作为一个公共的部分来管理,让一个什么东西来专门负责校验,当类型不正确的时候就抛个异常根本不去调用这个函数,很多框架设计时都是这么设计的(Spring MVC、Struts2等等),props也提供了这个功能,想一下如果没有这个功能的话,为了保证正确性我们可能需要在每次使用props属性之前都写一坨代码来检查。校验器最大的好处就是大多数情况下我们只需要声明我需要什么样的数据,让校验器检查好了再塞给我。

type

可以使用type来声明这个参数可以接受的数据的类型,当检查规则只有一个的时候type可以略写:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component :foo-message="fooMessage"></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: Number
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 123
    }
  });

</script>
</body>
</html>

当传入的参数类型不正确的时候Vue会发出提示:

type接受多个类型

当参数可以是多种类型的其中一个的时候,使用数组来表示。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component :foo-message="fooMessage"></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: [Number, String]
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 123
    }
  });

</script>
</body>
</html>

type能够指定的类型

type可以是以下原生类型:

  • String
  • Number
  • Boolean
  • Function
  • Object
  • Array
  • Symbol

required

可以使用required选项来声明这个参数是否必须传入。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component :foo-message="fooMessage"></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: {
        type: Number,
        required: true
      }
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 256
    }
  });

</script>
</body>
</html>

当未传入参数时:

default

使用default选项来指定当父组件未传入参数时props变量的默认值:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: {
        type: Number,
        default: 128
      }
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 256
    }
  });

</script>
</body>
</html>

当父组件未传入参数时子组件的值是128,当父组件传入参数时是其指定的参数,比如这里可以是256。

当type的类型为Array或者Object的时候default必须是一个函数:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: {
        type: Array,
        default: function(){
          return ['foo', 'bar'];
        }
      }
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: ['f', 'o', 'o']
    }
  });

</script>
</body>
</html>

required && default ???

那么required和default是否能同时出现在一个props变量中呢?

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: {
        type: Number,
        required: true,
        default: 128
      }
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 256
    }
  });

</script>
</body>
</html>

渲染结果:

尽管控制台上Vue报了错误,但是props变量fooMessage还是使用了设置的default值。

事情不会这么简单,再测试一下其它的情况,比如当传入的参数验证不通过的时候:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component :foo-message="fooMessage"></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: {
        type: Number
      }
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 'foobar'
    }
  });

</script>
</body>
</html>

渲染结果:

fooMessage要求的类型是Number,传入了一个String类型的,尽管在控制台提示报了错,但是仍然将其渲染了出来。

由此可以得出一个结论:Vue的props校验只是提供一个参考,并不是强制性的。

validator

当校验规则很复杂,默认提供的校验规则无法满足的时候可以使用自定义函数来校验。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Study</title>
</head>
<body>

  <div id="app">
    <foo-component :foo-message="fooMessage"></foo-component>
  </div>

<script type="text/javascript" src="lib/vue.js"></script>
<script type="text/javascript">

  var fooComponent = {
    props: {
      fooMessage: {
        validator: function(value){
          return value>=0 && value<=128;
        }
      }
    },
    template: '<div> {{ fooMessage }} </div>'
  };

  var vm = new Vue({
    components: {
      'foo-component': fooComponent
    },
    el: '#app',
    data: {
      fooMessage: 100
    }
  });

</script>
</body>
</html>

一个综合的例子

props: {
  // fooA只接受数值类型的参数
  fooA: Number,
  // fooB可以接受字符串和数值类型的参数
  fooB: [String, Number],
  // fooC可以接受字符串类型的参数,并且这个参数必须传入
  fooC: {
    type: String,
    required: true
  },
  // fooD接受数值类型的参数,如果不传入的话默认就是100
  fooD: {
    type: Number,
    default: 100
  },
  // fooE接受对象类型的参数
  fooE: {
    type: Object,
    // 当为对象类型设置默认值时必须使用函数返回
    default: function(){
      return { message: 'Hello, world' }
    }
  },
  // fooF使用一个自定义的验证器
  fooF: {
    validator: function(value){
      return value>=0 && value<=100;
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Vue props用法详解(小结)

    Vue props用法详解 组件接受的选项之一 props 是 Vue 中非常重要的一个选项.父子组件的关系可以总结为: props down, events up 父组件通过 props 向下传递数据给子组件:子组件通过 events 给父组件发送消息. 父子级组件 比如我们需要创建两个组件 parent 和 child.需要保证每个组件可以在相对隔离的环境中书写,这样也能提高组件的可维护性. 这里我们先定义父子两个组件和一个 Vue 对象: var childNode = { templat

  • Vue props 单向数据流的实现

    1.props通信 注意:DOM模板的驼峰命名props要转为短横分割命名. <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <title>Vue</title> </head> <body> <div id="app"> <my-component m

  • 简单理解vue中Props属性

    本文实例为大家解析了vue中Props的属性,供大家参考,具体内容如下 使用 Props 传递数据 组件实例的作用域是孤立的.这意味着不能并且不应该在子组件的模板内直接引用父组件的数据.可以使用 props 把数据传给子组件. "prop" 是组件数据的一个字段,期望从父组件传下来.子组件需要显式地用 props 选项 声明 props: Vue.component('child', { // 声明 props props: ['msg'], // prop 可以用在模板内 // 可以

  • 浅谈Vue初学之props的驼峰命名

    在vue的中文官网有这样的说明:HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符.这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名. 重申一次,如果你使用字符串模板,那么这个限制就不存在了. 以以下代码为例: 1.当组件中template及props等使用驼峰式命名,在html中对应的改成短横线命名方式. 2.当组件中template及props等使用字符串模板

  • Vue 组件参数校验与非props特性的方法

    子组件接收父组件的参数的时候,props注册接收的参数 props:['count'] 子组件可以对接收的参数校验. 例如规定接收的count参数要求是String props:{ count:String } 如果count是别的类型就会报错 组件的参数校验 组件的参数校验指的是什么呢?你父组件向子组件传递的内容,子组件有权对这个内容进行一些约束,这个约束我们可以把它叫做参数的校验. <div id="root"> <child content="hell

  • Vue中的Props(不可变状态)

    组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息.接下来通过本文给大家介绍Vue中Props,一起看看吧! 单向数据流 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行.这样会防止从子组件意外改变父级组件的状态

  • Vue Prop属性功能与用法实例详解

    本文实例讲述了Vue Prop属性功能与用法.分享给大家供大家参考,具体如下: 1 Prop 的大小写 (camelCase vs kebab-case) HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符.这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名: html: <div id="app-1"> <!-- HTML 中是 keb

  • 从vue源码看props的用法

    前言 平时写vue的时候知道 props 有很多种用法,今天我们来看看vue内部是怎么处理 props 中那么多的用法的. vue提供的props的用法 1. 数组形式 props: ['name', 'value'] 2. 对象形式 对象形式内部也提供了三种写法: props: { // 基础的类型检查 name: String, // 多个可能的类型 value: [String, Number], // 对象形式 id: { type: Number, required: true } }

  • 解决vue props 拿不到值的问题

    方案一: 在子组件中设置v-if='flag',初始值false,在成功获取数据后设置为true // 子组件 <echarts :datas="conditionStatisticsData" v-if="flag"></echarts> // 成功获取数据后 flag设置成true homeResource.getConditionData().then((res) => { this.flag = true if (res.dat

  • Vue中props的使用详解

    props属性是父子组件之间的通信桥梁.何为父子组件?从子组件的观点来看,他的上一级实例或组件即为他的父组件.我们知道,处于安全考虑,组件模板里我们无法直接使用父组件的data数据,使用props这个属性可以将父组件的数据传给子组件. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>props的测试</titl

  • Vue组件中prop属性使用说明实例代码详解

    Prop 的大小写 (camelCase vs kebab-case) HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符.这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名: Vue.component('blog-post', { // 在 JavaScript 中是 camelCase 的 props: ['postTitle'], template: '<h

随机推荐