React和Vue的props验证示例详解
为什么要使用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>
到此这篇关于React和Vue的props验证的文章就介绍到这了,更多相关Vue props验证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
解决React报错React.Children.only expected to rece
这篇文章主要为大家介绍了React报错React.Children.only expected to receive single React element child分析解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-01-01基于Cloud Studio构建React完成点餐H5页面(腾讯云 Cloud Studio 实战训练营)
最近也是有机会参与到了腾讯云举办的腾讯云Cloud Studio实战训练营,借此了解了腾讯云Cloud Studio产品,下面就来使用腾讯云Cloud Studio做一个实战案例来深入了解该产品的优越性吧,感兴趣的朋友跟随小编一起看看吧2023-08-08React高级指引之Refs and the DOM使用时机详解
在典型的React数据流中,props是父组件与子组件交互的唯一方式。要修改一个子组件,你需要使用新的props来重新渲染它。但是,在某些情况下,你需要在典型数据流之外强制修改子组件2023-02-02基于CSS实现MaterialUI按钮点击动画并封装成 React 组件
笔者先后开发过基于vue,react,angular等框架的项目,碧如vue生态的elementUI, ant-design-vue, iView等成熟的UI框架, react生态的ant-design, materialUI等,这些第三方UI框架极大的降低了我们开发一个项目的成本和复杂度,使开发者更专注于实现业务逻辑和服务化2021-11-11
最新评论