Vue props验证
Celester_best 人气:0为什么要使用props校验?
使用props校验有两个好处:
1、可以很清晰的知道组件中属性的类型以及哪些属性是必需的
2、传递的数据出现错误时会报错,可以很容易定位问题
本文将会提供React和vue中的数据校验方法和示例。
React中的props校验
react中使用propTypes来对props进行校验。通过defaultProps可以设置默认值,通过propTypes可以规定属性的类型。
基本使用示例:
import React from "react"; // 引入PropTypes import PropTypes from 'prop-types' export default class Child extends React.Component { constructor(props) { super(props) } render() { return ( <div></div> ) } } // 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes={ } // 设置默认值 Child.defaultProps = { }
react中单一类型校验器
可以通过PropTypes对string(字符串)、number(数字或者是可以被解析成数字的值)、bool(布尔)、object(对象)、array(数组)、func(函数)类型进行校验
设定属性类型和默认值
使用示例:
// 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes = { arrValue: PropTypes.array,//数组类型 boolValue: PropTypes.bool,//布尔类型 funcValue: PropTypes.func,//函数类型 numValue: PropTypes.number,//数字类型 objValue: PropTypes.object,//对象类型 strValue: PropTypes.string,//字符串类型 } // 设置默认值 Child.defaultProps = { arrValue: [1, 2], boolValue: false, numValue: 0, objValue: { name: 'lisi' }, strValue: '123' }
不传递参数的情况(会使用设置的默认值):
父类:
import React from "react"; import Child from './Child' export default class PropsDemo extends React.Component { constructor(props) { super(props) this.print = this.print.bind(this) } print() { console.log('打印日志') } render() { return ( <div> <Child></Child> </div > ) } }
子类:
import React from "react"; // 引入PropTypes import PropTypes from 'prop-types' export default class Child extends React.Component { printData() { this.props.funcValue() } render() { const { arrValue, boolValue, numValue, objValue, strValue } = this.props return ( <div> <div>{arrValue.join(',')}</div> <div style={{ color: boolValue ? '#00ffff' : '#ff7f50' }}>布尔类型</div> <div>学生信息:{`${objValue.name}-${objValue.age}`}</div> <div>得分:{numValue}</div> <div>备注:{strValue}</div> <button onClick={this.printData.bind(this)}>打印</button> </div> ) } } // 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes = { arrValue: PropTypes.array,//数组类型 boolValue: PropTypes.bool,//布尔类型 funcValue: PropTypes.func,//函数类型 numValue: PropTypes.number,//数字类型 objValue: PropTypes.object,//对象类型 strValue: PropTypes.string,//字符串类型 } // 设置默认值 Child.defaultProps = { arrValue: [1, 2], boolValue: false, numValue: 60, objValue: { name: 'lisi', age: 20 }, strValue: 'xxx' }
传递参数(使用传递的值)
import React from "react"; import Child from './Child' export default class PropsDemo extends React.Component { constructor(props) { super(props) this.print = this.print.bind(this) } print() { console.log('打印日志') } render() { const arrValue = [3, 4, 5] const boolValue = true const numValue = 88 const objValue = { name: '王五', age: 22 } const strValue = '优秀' return ( <div> <Child arrValue={arrValue} boolValue={boolValue} numValue={numValue} objValue={objValue} funcValue={this.print} strValue={strValue} ></Child> </div > ) } }
设置必需属性
通过isRequired可以设定属性是必需的,如果父组件没有传递,并且也没有默认值时就会有报错提醒。
注释strValue的传递
<Child arrValue={arrValue} boolValue={boolValue} numValue={numValue} objValue={objValue} funcValue={this.print} // strValue={strValue} ></Child>
设置strValue为必需属性,并注释默认值的设置
Child.propTypes = { arrValue: PropTypes.array,//数组类型 boolValue: PropTypes.bool,//布尔类型 funcValue: PropTypes.func,//函数类型 numValue: PropTypes.number,//数字类型 objValue: PropTypes.object,//对象类型 strValue: PropTypes.string.isRequired,//字符串类型 } // 设置默认值 Child.defaultProps = { arrValue: [1, 2], boolValue: false, numValue: 60, objValue: { name: 'lisi', age: 20 }, // strValue: 'xxx' }
运行代码:
放开刚刚注释掉的默认值设置,发现不在报错。
Child.propTypes = { arrValue: PropTypes.array,//数组类型 boolValue: PropTypes.bool,//布尔类型 funcValue: PropTypes.func,//函数类型 numValue: PropTypes.number,//数字类型 objValue: PropTypes.object,//对象类型 strValue: PropTypes.string.isRequired,//字符串类型 } // 设置默认值 Child.defaultProps = { arrValue: [1, 2], boolValue: false, numValue: 60, objValue: { name: 'lisi', age: 20 }, strValue: 'xxx' }
放开刚刚注释掉的传递strValue设置,发现也不会报错
<Child arrValue={arrValue} boolValue={boolValue} numValue={numValue} objValue={objValue} funcValue={this.print} strValue={strValue} ></Child>
react中组合类型校验器
组合类型的校验器有如下几种:
oneOfType:属性必须是指定的一组类型中的一种
arrayOf:属性必须是由指定元素组成的数组
objectOf:属性必须是一个带有指定类型值的属性值的对象,也就是说对象必须要有一个指定类型的属性
shape:属性必须是一个符合特定格式的对象,它需要拥有同一组属性。
node:属性必须是一个可以渲染的值:数字,字符串,元素或数组
element:属性必须是一个React元素
instanceOf:属性必须是指定类的实例
oneOf:确保属性被限制为一组枚举值中的一项
PropTypes.oneOfType
父类:
const dataValue1 = '测试'//字符串 const dataValue2 = 234//数字 const dataValue3 = { name: '王五' }//非字符串和数字 return ( <div> <Child dataValue1={dataValue1} dataValue2={dataValue2} dataValue3={dataValue3} ></Child> </div > )
子类:
import React from "react"; // 引入PropTypes import PropTypes from 'prop-types' export default class Child extends React.Component { componentDidMount() { console.log('dataValue3:', this.props.dataValue3) } render() { return ( <div> <div>dataValue1:{this.props.dataValue1}</div> <div>dataValue1:{this.props.dataValue2}</div> </div> ) } } // 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes = { dataValue1: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), dataValue2: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), dataValue3: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]) }
可以看到dataValue1和dataValue2都是规定类型中的一种,可以正常使用;而dataValue3传递的不是规定的类型,就有提醒。
PropTypes.arrayOf
父类:
render() { const dataValue1 = [1, 2, 3, 4]//元素是number类型 const dataValue2 = ['1', '2', '3', '4']//元素是string类型 return ( <div> <Child dataValue1={dataValue1} dataValue2={dataValue2} ></Child> </div > ) }
子类:
import React from "react"; // 引入PropTypes import PropTypes from 'prop-types' export default class Child extends React.Component { render() { return ( <div> <div>dataValue1:{this.props.dataValue1.join(',')}</div> <div>dataValue1:{this.props.dataValue2.join(',')}</div> </div> ) } } // 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes = { dataValue1: PropTypes.arrayOf(PropTypes.number), dataValue2: PropTypes.arrayOf(PropTypes.number), }
可以看到数组元素是number时就不没有错误提示,但是数组元素不是number时就会有错误提示。
PropTypes.objectOf
父类:
render() { const dataValue1 = { value1: 1, value2: 2, value3: 3 } const dataValue2 = { value1: "1", value2: "2", value3: "3" } return ( <div> <Child dataValue1={dataValue1} dataValue2={dataValue2} ></Child> </div > ) }
子类:
import React from "react"; // 引入PropTypes import PropTypes from 'prop-types' export default class Child extends React.Component { getValueStr(obj) { let str = '' for (const key in obj) { str = `${str}${obj[key]},` } return str } render() { const { dataValue1, dataValue2 } = this.props const dataValue1Str = this.getValueStr(dataValue1) const dataValue2Str = this.getValueStr(dataValue2) return ( <div> <div>dataValue1:{dataValue1Str}</div> <div>dataValue1:{dataValue2Str}</div> </div> ) } } // 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes = { dataValue1: PropTypes.objectOf(PropTypes.number), dataValue2: PropTypes.objectOf(PropTypes.number), }
PropTypes.shape
父类:
render() { const dataValue1 = { name: '张三', age: 20 } const dataValue2 = { name: '张三', age: "20"//age不传递number类型 } const dataValue3 = { name: '张三',//少传递一个属性 } const dataValue4 = { name: '张三', age: 20, num: 88,//多传递一个属性 } return ( <div> <Child dataValue1={dataValue1} dataValue2={dataValue2} dataValue3={dataValue3} dataValue4={dataValue4} ></Child> </div > ) }
子类:
import React from "react"; // 引入PropTypes import PropTypes from 'prop-types' export default class Child extends React.Component { getValueStr(obj) { let str = '' for (const key in obj) { str = `${str}${obj[key]},` } return str } render() { const { dataValue1, dataValue2, dataValue3, dataValue4 } = this.props const dataValue1Str = this.getValueStr(dataValue1) const dataValue2Str = this.getValueStr(dataValue2) const dataValue3Str = this.getValueStr(dataValue3) const dataValue4Str = this.getValueStr(dataValue4) return ( <div> <div>dataValue1:{dataValue1Str}</div> <div>dataValue2:{dataValue2Str}</div> <div>dataValue3:{dataValue3Str}</div> <div>dataValue4:{dataValue4Str}</div> </div> ) } } // 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes = { dataValue1: PropTypes.shape({ name: PropTypes.string, age: PropTypes.number }), dataValue2: PropTypes.shape({ name: PropTypes.string, age: PropTypes.number }), dataValue13: PropTypes.shape({ name: PropTypes.string, age: PropTypes.number }), dataValue14: PropTypes.shape({ name: PropTypes.string, age: PropTypes.number }), }
由此可见,缺少属性或者增加属性都不会有错误提醒,但是如果传递的属性类型跟预定的不一致就会有错误提醒。
PropTypes.node
父组件:
render() { const dataValue1 = 123//数字 const dataValue2 = '张三'//字符串 const dataValue3 = [1, 2, 3] const dataValue4 = {//对象 name: '张三', age: 20, num: 88, } return ( <div> <Child dataValue1={dataValue1} dataValue2={dataValue2} dataValue3={dataValue3} dataValue4={dataValue4} ></Child> </div > ) }
子组件:
import React from "react"; // 引入PropTypes import PropTypes from 'prop-types' export default class Child extends React.Component { getValueStr(obj) { let str = '' for (const key in obj) { str = `${str}${obj[key]},` } return str } render() { const { dataValue1, dataValue2, dataValue3, dataValue4, } = this.props const dataValue4Str = this.getValueStr(dataValue4) return ( <div> <div>dataValue1:{dataValue1}</div> <div>dataValue2:{dataValue2}</div> <div>dataValue3:{dataValue3.join(',')}</div> <div>dataValue4:{dataValue4Str}</div> </div> ) } } // 规定属性的类型-将propTypes设置成一个类构造函数属性 Child.propTypes = { dataValue1: PropTypes.node, dataValue2: PropTypes.node, dataValue3: PropTypes.node, dataValue4: PropTypes.node, }
可以看到当预定属性为PropTypes.node类型时,可以传递数字,字符串,数组,但是传递对象类型时就会有报错提示。注意PropTypes.node类型并不仅仅局限于数字,字符串,数组,还可以是其他任何可渲染的元素。
Vue中的props验证
vue中可以对如下类型进行检查:String、Number、Boolean、Array、Object、Date、Function、Symbol以及自定义类型。
vue数据验证:通过变量名:具体类型的方法
父组件:
<template> <div> <PropsChildDemo :name="name" :age="age" :obj="obj" :obj2="obj2" ></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { name: "张三", age: 20, obj: { name: "李四", age: 21, }, obj2: { func: function () { console.log("打印"); }, }, }; }, }; </script>
子组件:
<template> <div> <div>姓名:{{ name }}</div> <div>年龄:{{ age }}</div> <div>姓名:{{ obj.name }};年龄:{{ obj.age }}</div> <button @click="obj2.func">打印</button> </div> </template> <script> export default { name: "PropsChildDemo", components: {}, props: { name: String,//直接说明name为String类型 age: Number, obj: Object, obj2: { func: Function, }, }, data() { return {}; }, methods: {}, }; </script>
vue数据验证:带有默认值的方式验证
vue中设置默认值是使用default属性,此时设置数据类型时需要使用type属性
<template> <div> <PropsChildDemo :obj2="obj2"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { name: "张三", age: 20, obj: { name: "李四", age: 21, }, obj2: { func: function () { console.log("打印"); }, }, }; }, }; </script>
<template> <div> <div>姓名:{{ name }}</div> <div>年龄:{{ age }}</div> <div>姓名:{{ obj.name }};年龄:{{ obj.age }}</div> <button @click="obj2.func">打印</button> </div> </template> <script> export default { name: "PropsChildDemo", components: {}, props: { name: { // 设置类型 type: String, // 设置默认值 default: "XXX", }, age: { type: Number, default: 0, }, obj: { type: Object, // 注意:对象和数组的默认值必须从一个工厂函数获取 default: function () { return { name: "xxxx", age: -1, }; }, }, obj2: { func: Function, }, }, data() { return {}; }, methods: {}, }; </script>
注意:对象和数组的默认值必须从一个工厂函数获取。
通过required设置必须属性
name: { // 设置类型 type: String, // 设置默认值 default: "XXX", // 通过required设置必须属性 required: true, },
通过required设置name为必需属性之后,如果没有传递name字段,就会有错误提示。
多种类型中的一种
<template> <div>数据验证</div> </template> <script> export default { name: "PropsChildDemo", components: {}, props: { info: [String, Number, Boolean], }, data() { return {}; }, }; </script>
info必须为String,Number,Boolean中的一种,否则就会有提示。
传递了一个对象:
<template> <div> <PropsChildDemo :info="info"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { info: { nam: "张三", age: 20, }, }; }, }; </script>
传递一个字符串:
<template> <div> <PropsChildDemo :info="info"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { info: "张三", }; }, }; </script>
对象数组验证,并且数组元素是特定属性的对象
验证info是一个数组,并且数组元素是由name,age属性组成的对象
<template> <div>数据验证</div> </template> <script> export default { name: "PropsChildDemo", components: {}, props: { info: { // 设置必须 required: true, type: Array, // 验证info是一个数组,并且数组元素是由name,age属性组成的对象 validator(value) { return value.every((item) => { const { name, age } = item; return Boolean(name && age); }); }, }, }, data() { return {}; }, }; </script>
少传一个属性:
<template> <div> <PropsChildDemo :info="info"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { info: [ { name: "zhangsan", age: 20, }, // 其中一个元素少一个属性 { name: "wangwu", }, ], }; }, }; </script>
按要求传递:
<template> <div> <PropsChildDemo :info="info"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { info: [ { name: "zhangsan", age: 20, }, { name: "wangwu", age: 21, }, ], }; }, }; </script>
多传递一个参数:
<template> <div> <PropsChildDemo :info="info"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { info: [ // 多传递一个参数 { name: "zhangsan", age: 20, num: 88, }, ], }; }, }; </script>
所以少传或者错传都会验证失败,多传或者按要求传递能验证通过。
自定义验证函数
<template> <div> <PropsChildDemo :info="info"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { info: "zhaoliu", }; }, }; </script>
<template> <div>{{ info }}</div> </template> <script> export default { name: "PropsChildDemo", components: {}, props: { info: { validator(value) { return ["zhangsan", "lisi", "wangwu"].indexOf(value) !== -1; }, }, }, data() { return {}; }, }; </script>
info必须为zhangsan,lisi,wangwu中的一个,否则就会有错误提示
传递zhangsan,lisi,wangwu中的一个,就不会有错误提示:
<template> <div> <PropsChildDemo :info="info"></PropsChildDemo> </div> </template> <script> import PropsChildDemo from "./PropsChildDemo.vue"; export default { name: "PropsDemo", components: { PropsChildDemo }, data() { return { info: "wangwu", }; }, }; </script>
加载全部内容