zoukankan      html  css  js  c++  java
  • vue 组件开发 props 验证

    使用props

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component :foo-message="fooMessage"></foo-component>  
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: ['fooMessage'],
    18         template: '<div> {{ fooMessage }} </div>'
    19     };
    20  
    21     var vm = new Vue({
    22         components: {
    23             'foo-component': fooComponent
    24         },
    25         el: '#app',
    26         data: {
    27             fooMessage: 123
    28         }
    29     });
    30  
    31 </script>
    32 </body>
    33 </html>
    复制代码

    为什么要有props验证

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

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

    type

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component :foo-message="fooMessage"></foo-component>  
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: Number
    19         },
    20         template: '<div> {{ fooMessage }} </div>'
    21     };
    22  
    23     var vm = new Vue({
    24         components: {
    25             'foo-component': fooComponent
    26         },
    27         el: '#app',
    28         data: {
    29             fooMessage: 123
    30         }
    31     });
    32  
    33 </script>
    34 </body>
    35 </html>
    复制代码

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

    type接受多个类型

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component :foo-message="fooMessage"></foo-component>  
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: [Number, String]
    19         },
    20         template: '<div> {{ fooMessage }} </div>'
    21     };
    22  
    23     var vm = new Vue({
    24         components: {
    25             'foo-component': fooComponent
    26         },
    27         el: '#app',
    28         data: {
    29             fooMessage: 123
    30         }
    31     });
    32  
    33 </script>
    34 </body>
    35 </html>
    36  
    复制代码

    type能够指定的类型

    type可以是以下原生类型:

    String

    Number

    Boolean

    Function

    Object

    Array

    Symbol

    required

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component :foo-message="fooMessage"></foo-component>  
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: {
    19                 type: Number,
    20                 required: true
    21             }
    22         },
    23         template: '<div> {{ fooMessage }} </div>'
    24     };
    25  
    26     var vm = new Vue({
    27         components: {
    28             'foo-component': fooComponent
    29         },
    30         el: '#app',
    31         data: {
    32             fooMessage: 256
    33         }
    34     });
    35  
    36 </script>
    37 </body>
    38 </html>
    复制代码

    当未传入参数时:

    default

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component></foo-component>
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: {
    19                 type: Number,
    20                 default: 128
    21             }
    22         },
    23         template: '<div> {{ fooMessage }} </div>'
    24     };
    25  
    26     var vm = new Vue({
    27         components: {
    28             'foo-component': fooComponent
    29         },
    30         el: '#app',
    31         data: {
    32             fooMessage: 256
    33         }
    34     });
    35  
    36 </script>
    37 </body>
    38 </html>
    复制代码

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

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component></foo-component>
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: {
    19                 type: Array,
    20                 default: function(){
    21                     return ['foo', 'bar'];
    22                 }
    23             }
    24         },
    25         template: '<div> {{ fooMessage }} </div>'
    26     };
    27  
    28     var vm = new Vue({
    29         components: {
    30             'foo-component': fooComponent
    31         },
    32         el: '#app',
    33         data: {
    34             fooMessage: ['f', 'o', 'o']
    35         }
    36     });
    37  
    38 </script>
    39 </body>
    40 </html>
    复制代码

    required && default ???

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component></foo-component>
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: {
    19                 type: Number,
    20                 required: true,
    21                 default: 128
    22             }
    23         },
    24         template: '<div> {{ fooMessage }} </div>'
    25     };
    26  
    27     var vm = new Vue({
    28         components: {
    29             'foo-component': fooComponent
    30         },
    31         el: '#app',
    32         data: {
    33             fooMessage: 256
    34         }
    35     });
    36  
    37 </script>
    38 </body>
    39 </html>
    复制代码

    渲染结果:

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

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component :foo-message="fooMessage"></foo-component>  
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: {
    19                 type: Number
    20             }
    21         },
    22         template: '<div> {{ fooMessage }} </div>'
    23     };
    24  
    25     var vm = new Vue({
    26         components: {
    27             'foo-component': fooComponent
    28         },
    29         el: '#app',
    30         data: {
    31             fooMessage: 'foobar'
    32         }
    33     });
    34  
    35 </script>
    36 </body>
    37 </html>
    复制代码

    渲染结果:

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

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

    validator

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

    复制代码
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8">
     5     <title>Vue Study</title>
     6 </head>
     7 <body>
     8  
     9     <div id="app">
    10         <foo-component :foo-message="fooMessage"></foo-component>  
    11     </div>
    12  
    13 <script type="text/javascript" src="lib/vue.js"></script>
    14 <script type="text/javascript">
    15  
    16     var fooComponent = {
    17         props: {
    18             fooMessage: {
    19                 validator: function(value){
    20                     return value>=0 && value<=128;
    21                 }
    22             }
    23         },
    24         template: '<div> {{ fooMessage }} </div>'
    25     };
    26  
    27     var vm = new Vue({
    28         components: {
    29             'foo-component': fooComponent
    30         },
    31         el: '#app',
    32         data: {
    33             fooMessage: 100
    34         }
    35     });
    36  
    37 </script>
    38 </body>
    39 </html>
    复制代码

    一个综合的例子

    复制代码
     1 props: {
     2     // fooA只接受数值类型的参数
     3     fooA: Number,
     4     // fooB可以接受字符串和数值类型的参数
     5     fooB: [String, Number],
     6     // fooC可以接受字符串类型的参数,并且这个参数必须传入
     7     fooC: {
     8         type: String,
     9         required: true
    10     },
    11     // fooD接受数值类型的参数,如果不传入的话默认就是100
    12     fooD: {
    13         type: Number,
    14         default: 100
    15     },
    16     // fooE接受对象类型的参数
    17     fooE: {
    18         type: Object,
    19         // 当为对象类型设置默认值时必须使用函数返回
    20         default: function(){
    21             return { message: 'Hello, world' }
    22         }
    23     },
    24     // fooF使用一个自定义的验证器
    25     fooF: {
    26         validator: function(value){
    27             return value>=0 && value<=100;
    28         }
    29     }
    30 }
    复制代码
  • 相关阅读:
    【小贴士】zepto find元素以及ios弹出键盘可能让你很头疼
    【iScroll源码学习04】分离IScroll核心
    【iScroll源码学习03】iScroll事件机制与滚动条的实现
    展望14,献给困惑的初级前端,理想不甘消磨,目标不能停滞!
    【iScroll源码学习02】分解iScroll三个核心事件点
    原生andriod浏览器回退后dom(click)事件全体失效问题探究
    【iScroll源码学习01】准备阶段
    【iScroll源码学习00】模拟iScroll
    【再探backbone 03】博客园单页应用实例(提供源码)
    【再探backbone 02】集合-Collection
  • 原文地址:https://www.cnblogs.com/hpx2020/p/8949470.html
Copyright © 2011-2022 走看看