Vue3深入组件-Props

Prop 类型

  1. 字符串数组形式

    1
    props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
  2. 对象形式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
    type: String,
    required: true
    },
    // 带有默认值的数字
    propD: {
    type: Number,
    default: 100
    },
    // 带有默认值的对象
    propE: {
    type: Object,
    // 对象或数组默认值必须从一个工厂函数获取
    default: function() {
    return { message: 'hello' }
    }
    },
    // 自定义验证函数
    propF: {
    validator: function(value) {
    // 这个值必须匹配下列字符串中的一个
    return ['success', 'warning', 'danger'].indexOf(value) !== -1
    }
    },
    // 具有默认值的函数
    propG: {
    type: Function,
    // 与对象或数组默认值不同,这不是一个工厂函数 —— 这是一个用作默认值的函数
    default: function() {
    return 'Default function'
    }
    },
    author: Person // 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。用于验证 author prop 的值是否是通过 new Person 创建的
    }
    function Person(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
    }

    注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 datacomputed 等) 在 defaultvalidator 函数中是不可用的。

传递静态或动态的 Prop

  1. 传一个字符串

    1
    2
    3
    4
    5
    <blog-post title="My journey with Vue"></blog-post>
    <!-- 动态赋予一个变量的值 -->
    <blog-post :title="post.title"></blog-post>
    <!-- 动态赋予一个复杂表达式的值 -->
    <blog-post :title="post.title + ' by ' + post.author.name"></blog-post>
  2. 传一个数字

    1
    2
    3
    4
    5
    <!-- 这是一个 JavaScript 表达式而不是一个字符串。             -->
    <blog-post :likes="42"></blog-post>

    <!-- 用一个变量进行动态赋值。-->
    <blog-post :likes="post.likes"></blog-post>
  3. 传一个布尔值

    1
    2
    3
    4
    5
    6
    7
    8
    <!-- 包含该 prop 没有值的情况在内,都意味着 `true`。          -->
    <blog-post is-published></blog-post>

    <!-- 这是一个 JavaScript 表达式而不是一个字符串。 -->
    <blog-post :is-published="false"></blog-post>

    <!-- 用一个变量进行动态赋值。 -->
    <blog-post :is-published="post.isPublished"></blog-post>
  4. 传一个数组

    1
    2
    3
    4
    5
    <!-- 这是一个 JavaScript 表达式而不是一个字符串。             -->
    <blog-post :comment-ids="[234, 266, 273]"></blog-post>

    <!-- 用一个变量进行动态赋值。 -->
    <blog-post :comment-ids="post.commentIds"></blog-post>
  5. 传一个对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!-- 这是一个 JavaScript 表达式而不是一个字符串。             -->
    <blog-post
    :author="{
    name: 'Veronica',
    company: 'Veridian Dynamics'
    }"
    ></blog-post>

    <!-- 用一个变量进行动态赋值。 -->
    <blog-post :author="post.author"></blog-post>
  6. 传一个对象的所有 property

    1
    2
    3
    4
    5
    6
    post: {
    id: 1,
    title: 'My Journey with Vue'
    }
    <blog-post v-bind="post"></blog-post> ===》
    <blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>

单向数据流

这里有两种常见的试图变更一个 prop 的情形:

  1. 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data property 并将这个 prop 作为其初始值:

    1
    2
    3
    4
    5
    6
    props: ['initialCounter'],
    data() {
    return {
    counter: this.initialCounter
    }
    }
  2. 这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

    1
    2
    3
    4
    5
    6
    props: ['size'],
    computed: {
    normalizedSize: function () {
    return this.size.trim().toLowerCase()
    }
    }

    注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。