[TOC] #### 1. props 选项概述 --- props 选项的值可以是数组或对象,用于接收来自父组件的数据 当 props 的值为一个对象时,可以配置高级选项,如:类型检测、自定义验证、设置默认值 当 props 的值为一个简单的数组时,键值是接收的属性名,如果父组件没有传递该属性,属性值为 undefined #### 2. props 用法详解 --- props 基于对象的语法可以使用以下选项: | 选项 | 描述 | 取值 | | ------------ | ------------ | ------------ | | type | 类型检测 | 原生构造函数,如:String,Array,Object 等 | | default | 默认值 | Any,父组件没有传入 prop 时的默认值,对象或数组必须用一个工厂函数返回 | | required | 是否必传 | Boolean。和 default 选项二选一使用即可 | | validator | 自定义验证函数 | Function,函数的参数是 prop 的值 | prop 会在组件实例创建之前进行验证,所以实例的选项 data、computed 等在 default 和 validator 函数中是不可用的 ```javascript export default { props: { // 只检测类型 name: String, // 多个可能的类型 likes: [String, Array], // 检测类型 + 默认值 age: { type: Number, default: 18, }, // 检测类型 + 必传项 gender: { type: String, required: true, }, // 检测类型 + 自定义验证函数 phone: { type: String, validator(val) { return /^1[3456789]\d{9}$/.test(val); }, }, } } ``` #### 3. props 书写规范 --- html 属性名对大小写是不敏感的,浏览器会把所有大写字符解释为小写字符 如果 props 中的属性名为多个单词,使用小驼峰命名法,父组件传入 prop 时使用其对应短横线命名法的属性名 ```javascript export default { props: { userInfo: { type: Object, default() { return {}; }, }, }, } ``` ```html <test :user-info="{ id: 1, name: 'liang' }"></test> ``` #### 4. props 传值语法 --- **传递静态或动态 prop** 传入一个静态的值 ```html <liang title="Hello Vue !"></liang> ``` 使用 v-bind 指令进行动态传值 ```html <!-- 动态赋予一个变量的值 --> <liang :title="form.title"></liang> <!-- 动态赋予一个复杂表达式的值 --> <liang :title="form.title + ' by ' + article.name"></liang> ``` **传入一个数字** 即使 20 是静态的,仍然需要使用 v-bind 来告诉 Vue 这是一个 JS 表达式,而不是一个字符串 ```html <!-- 子组件 props 接收到的 age 是 String 类型 --> <liang age="20"></liang> <!-- 子组件 props 接收到的 age 是 Number 类型 --> <liang v-bind:age="20"></liang> ``` **传入一个布尔值** ```html <!-- 父组件传入 prop 没有值时需要分两种情况 --> <!-- 子组件 props 中 disabled 的 type 定义的是 Boolean 类型,接收到的就是 true --> <!-- 子组件 props 中 disabled 的 type 定义的不是 Boolean 类型,接收到的就是空字符串 --> <liang disabled></liang> <!-- 父组件传入布尔值时也必须使用 v-bind 语法,否则子组件接收到的是字符串 --> <liang :disabled="false"></liang> ``` **传入一个数组或对象** ```html <liang :ids="[1, 2, 3]"></liang> <liang :user-info="{ id: 1, name: 'liang' }"></liang> ``` #### 5. 单向数据流 --- 父子组件的 prop 之间形成了一个 **单行下行绑定**。父级 prop 的更新会向下流动到子组件中,但反过来则不行。这样会 **防止从子组件意外变更父组件的状态**,从而导致应用的数据流向难以理解 父组件中的 prop 数据发生变更时,子组件中所有的 prop 都将跟着刷新为最新的值。意味着 **不应该在子组件内部改变 prop**,如果这样做了,Vue 将会在控制台发出警告 下面是在子组件中试图变更 prop 的情形: **一、将 prop 作为初始值传递到 data 选项中** 在子组件中不能直接修改 prop 的值,但是可以将 prop 作为初始值传递到 data 选项中,修改 data 选项的值 ```javascript export default { props: { num: Number, }, data() { return { count: this.num, }; }, methods: { btnClick() { this.count++; }, } } ``` **二、需要将 prop 进行转换处理,最好使用这个 prop 值定义一个计算属性** ```javascript export default { props: { num: Number, }, computed: { countAdd() { return this.num + 2; }, }, } ```