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可以略写:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Vue Study</title>
</head>
<body>
 
    <div id="app">
        <input type="text" v-model="fooMessage" placeholder="请输入...">
        <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">
        <input type="text" v-model.number="parentInput" placeholder="请输入...">
        <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">
        <input type="text" v-model="fooMessage" placeholder="请输入...">
        <foo-component :foo-message="fooMessage"></foo-component> 
     <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 } }, 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-message="fooMessage"></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">
        <input type="text" v-model.number="fooMessage" placeholder="请输入...">
        <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>

一个组合的例子:

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset=” utf-8” > 
    <title>数据验证</title>
    <script src="../../vue.js" type="text/javascript"></script>
</head> 
<body>
    <div id="app" v-cloak>
        当props需要验证时,就需要对象写法。一般当你的组件提供给别人使用时推荐进行数据验证,以下时几个prop例子:
        <br>
        <!-- <input type="text" v-model.number="parentInput" placeholder="请输入..."> -->
        <my-component :prop-a="parentInput" :prop-d="parentInput" :prop-f="parentInput"></my-component>
    </div>    
<script>
    Vue.component('my-component',{
        props:{
            //必须是数字类型
            propA:Number,
            //必须是字符串或数字类型
            propB:[String,Number],
            //布尔值,如果没有定义,默认是true
            propC:{
                type:Boolean,
                default:true
            },
            //数字,而且是必传
            propD:{
                type:Number,
                required:true
            },
            //如果是数组或对象,默认值必须是一个函数来返回
            propE:{
                type:Array,
                default:function(){
                    return [];
                }
            },
            // 自定义一个验证函数
            propF:{
                validator:function(value){
                    return value>10;
                }
            }
        },
        template:'<div>{{propA}},{{propD}},{{propF}}</div>'
    });

    var app=new Vue({
        el:'#app',
        data:{
            parentInput:16
        }
    })
</script> 
</body> 
</html>

部分摘自:https://www.cnblogs.com/exhuasted/p/7250452.html

原文地址:https://www.cnblogs.com/planetwithpig/p/11653732.html