vue2之props

5,109 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情

props

props是用来给组件接收外部数据的, 一般是父组件给子组件传值。可以是对象或者数组。

1. 语法

1.1 数组

props属性值如果是数组的话,那么主要就是用来接收数据的。

props: ['name', 'msg']

1.2 对象

对象允许配置高级选项,如类型检测、自定义验证和设置默认值。主要配置项如下:

  • type: 数据类型,StringNumberBooleanArrayObjectDateFunctionSymbol、任何自定义构造函数、或上述内容组成的数组。会检查一个 prop 是否是给定的类型,否则抛出警告。
  • default:默认值,可以为任意类型的值。为该 prop 指定一个默认值。如果该 prop 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回。
  • required: 表示该prop是否是必须传入的。布尔类型。在非生产环境中,如果这个值为 truthy 且该 prop 没有被传入的,则一个控制台警告将会被抛出。
  • validator:自定义验证函数。Function类型。自定义验证函数会将该 prop 的值作为唯一的参数代入。在非生产环境下,如果该函数返回一个 falsy 的值 (也就是验证失败),一个控制台警告将会被抛出。

2. 使用

prop在使用的时候会根据应用场景有不同的写法,主要有下面几种形式。

2.1 只接收数据

子组件

<template>
  <div class="hi-wrapper">
    <h3>你好呀, {{name}}</h3>
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  name: 'hiFriend',
  props: ['name', 'msg']
}
</script>

接收两个变量值: name和msg

父组件

<template>
  <div class="hello">
    <hiFriend ref="msg" name="儿子" msg="我是你爸爸"></hiFriend>
  </div>
</template>

<script>
import hiFriend from './hiFriend.vue';
export default {
  name: 'HelloWorld',
  components: {hiFriend},
  props: {
    msg: String
  },
  data() {
    return {
    }
  }
}
</script>

效果如下:

image.png

上面这种写法是简写形式,适用于只传数据,没有其他的限制条件, 也可以写成下面这种复杂形式

<template>
  <div class="hi-wrapper">
    <h3>你好呀, {{name}}</h3>
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  name: 'hiFriend',
  props: {
    name:{},
    msg:{}
  }
}
</script>

2.2 限制类型

上面那个复杂形式也是配置其他属性的基础,比如如果需要限制类型,那么就可以添加type属性

2.2.1 语法
props: {
    name: {
        type: String | Array
    }
}
2.2.2 唯一类型

唯一类型的type的值为字符串

子组件

<template>
  <div class="hi-wrapper">
    <h3>你好呀, {{name}}</h3>
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  name: 'hiFriend',
  props: {
    name:{
      type: String
    },
    msg:{
      type: [String, Number]
    }
  }
}
</script>

定义name为string类型

父组件

<template>
  <div class="hello">
    <hiFriend ref="msg" name="儿子" msg="我是你爸爸"></hiFriend>
  </div>
</template>

<script>
import hiFriend from './hiFriend.vue';
export default {
  name: 'HelloWorld',
  components: {hiFriend},
  props: {
    msg: String
  },
  data() {
    return {
    }
  }
}
</script>

传的name是string类型,效果如下:

image.png

<template>
  <div class="hello">
    <hiFriend ref="msg" :name="23" msg="我是你爸爸"></hiFriend>
  </div>
</template>

传的是number类型,效果如下:

image.png

2.2.3 多种类型

多种类型的type的值为数组

子组件

<template>
  <div class="hi-wrapper">
    <h3>你好呀, {{name}}</h3>
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  name: 'hiFriend',
  props: {
    name:{
      type: String
    },
    msg:{
      type: [String, Number]
    }
  }
}
</script>

子组件的msg定义的是string和number类型。

父组件

<template>
  <div class="hello">
    <hiFriend ref="msg" name="儿子" msg="我是你爸爸"></hiFriend>
  </div>
</template>

<script>
import hiFriend from './hiFriend.vue';
export default {
  name: 'HelloWorld',
  components: {hiFriend},
  props: {
    msg: String
  },
  data() {
    return {
    }
  }
}
</script>

如果父组件传的是string, 效果如下:

image.png

<template>
  <div class="hello">
    <hiFriend ref="msg" name="儿子" :msg="666666"></hiFriend>
  </div>
</template>

如果父组件传的是number, 效果如下:

image.png

<template>
  <div class="hello">
    <hiFriend ref="msg" name="儿子" :msg="true"></hiFriend>
  </div>
</template>

如果父组件传入的是boolean, 效果如下:

image.png

小结

  1. type类型如果是唯一类型,属性值就是数据类型的名,如果是多类型,属性值需要用数据包裹。
  2. 如果传入的类型与props定义的类型不符,那么就会报错。

2.3 指定默认值

指定默认值的方式是在对象种定义default属性。

2.3.1 语法
props: {
    name:{
      type: String,
      default: ''
    }
}
2.3.2 用法

子组件

<template>
  <div class="hi-wrapper">
    <h3>你好呀, {{name}}</h3>
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  name: 'hiFriend',
  props: {
    name:{
      type: String,
      default: '张三'
    },
    msg:{
      type: [String, Number]
    }
  }
}
</script>

子组件定义name的默认值是张三

父组件

<template>
  <div class="hello">
    <hiFriend ref="msg" msg="我是你爸爸"></hiFriend>
  </div>
</template>

<script>
import hiFriend from './hiFriend.vue';
export default {
  name: 'HelloWorld',
  components: {hiFriend},
  props: {
    msg: String
  },
  data() {
    return {
    }
  }
}
</script>

父组件没有传name,效果如下:

image.png

小结

  1. 如果定义了默认值,那么如果没有传值,那么就使用默认值
  2. 基本类型的默认值,直接写对应的类型的默认数据,引用类型的默认值是先写一个函数,然后在函数内返回对应的数据
data: {
  type: Object,
  default: () => {
    return {}
  }
}

data: {
  type: Array,
  default: () => {
    return []
  }
}

2.4 限制必要性

限制必要性是使用required来配置的,属性值就两个值,true or false。 子组件

<template>
  <div class="hi-wrapper">
    <h3>你好呀, {{name}}</h3>
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  name: 'hiFriend',
  props: {
    name:{
      type: String,
      default: '张三',
      required: true
    },
    msg:{
      type: [String, Number]
    }
  }
}
</script>

子组件定义了name为必传

父组件

<template>
  <div class="hello">
    <hiFriend ref="msg" msg="我是你爸爸"></hiFriend>
  </div>
</template>

<script>
import hiFriend from './hiFriend.vue';
export default {
  name: 'HelloWorld',
  components: {hiFriend},
  props: {
    msg: String
  },
  data() {
    return {
    }
  }
}
</script>

父组件没有传name,效果如下:

image.png

<template>
  <div class="hello">
    <hiFriend ref="msg" name="儿子" msg="我是你爸爸"></hiFriend>
  </div>
</template>

父组件传了name, 效果如下:

image.png

2.5 自定义验证函数

自定义函数是除了上面几种限制之外,如果还需要别的限制条件,那么就可以通过validator来配置

2.5.1 语法

validator其实就是一个函数,接受传进来的值作为参数

  props: {
    name:{
      validator: (value) => {
      }
    }
  }
2.5.2 用法

子组件

<template>
  <div class="hi-wrapper">
    <h3>你好呀, {{name}}</h3>
    <p>{{msg}}</p>
  </div>
</template>
<script>
export default {
  name: 'hiFriend',
  props: {
    name:{
      type: String,
      default: '张三',
      required: true,
      validator: (value) => {
        return value !== ''
      }
    },
    msg:{
      type: [String, Number]
    }
  }
}
</script>

父组件

<template>
  <div class="hello">
    <hiFriend ref="msg" name="儿子的妹妹" msg="我是你爸爸"></hiFriend>
  </div>
</template>

<script>
import hiFriend from './hiFriend.vue';
export default {
  name: 'HelloWorld',
  components: {hiFriend},
  props: {
    msg: String
  },
  data() {
    return {
    }
  }
}
</script>

父组件传入的值满足自定义验证函数,效果如下:

image.png

<template>
  <div class="hello">
    <hiFriend ref="msg" name="" msg="我是你爸爸"></hiFriend>
  </div>
</template>

父组件传入的值不满足自定义验证函数,效果如下:

image.png

小结

  1. validator自定义验证函数只会返回true或者false,不能用作其他的返回值。
  2. 通过验证就将传入的值渲染出来,并且不报错,否则就会报错。