目录
React中的props校验
react中单一类型校验器
设定属性类型和默认值
?设置必需属性
react中组合类型校验器
PropTypes.oneOfType
?PropTypes.arrayOf
PropTypes.objectOf
?编辑PropTypes.shape
PropTypes.node
Vue中的props验证
vue数据验证:通过变量名:具体类型的方法
vue数据验证:带有默认值的方式验证
通过required设置必须属性
多种类型中的一种
?对象数组验证,并且数组元素是特定属性的对象
自定义验证函数
为什么要使用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>
?
?
|