当前位置 : 主页 > 网络编程 > JavaScript >

React和Vue的props验证示例详解

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 React中的props校验 react中单一类型校验器 设定属性类型和默认值 设置必需属性 react中组合类型校验器 PropTypes.oneOfType PropTypes.arrayOf PropTypes.objectOf PropTypes.shape PropTypes.node vue数据验证
目录
  • React中的props校验
    • react中单一类型校验器
      • 设定属性类型和默认值
      • 设置必需属性
    • react中组合类型校验器
      • PropTypes.oneOfType
      • PropTypes.arrayOf
      • PropTypes.objectOf
      • PropTypes.shape
      • PropTypes.node
      • vue数据验证:通过变量名:具体类型的方法
      • vue数据验证:带有默认值的方式验证
      • 通过required设置必须属性
      • 多种类型中的一种
      • 对象数组验证,并且数组元素是特定属性的对象
      • 自定义验证函数
  • 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验证内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!

    上一篇:Node交互式的SFTP上传实现过程剖析
    下一篇:没有了
    网友评论