认识vue中的Props

2023-10-14 09:02:35 浏览数 (1)

什么是props

Props 是 Vue 组件之间通信的一种方式,通过 Props,父组件可以向子组件传递数据,即:父组件可以通过组件标签上的属性值把数据传递到子组件中。子组件可以根据自己的属性和方法去渲染展示数据或执行某些操作。由于 props 是单向数据流的,它是只能从父组件传递到子组件的,而子组件是无法更改 props 的值的,只能由父组件来修改。这样就保证了组件的数据传递不会出现混乱和错乱的情况。

如何定义props

在 Vue 组件中,需要通过配置 props 属性来定义组件的 props。在组件中添加 props 属性之后,就可以使用 props 选项接收从父组件传递的数据。

使用字符串数组方式定义props

Props可以是数组形式进行滴定仪,在这里Props定义了一个数组,其中每个元素都是一个字符串类型的Prop名,表示父组件可以向子组件传递的数据项。

没有使用 <script setup> 的组件中定义prop

使用字符串数组来声明 props非常简单,只需要在组件中进行如下定义即可:

代码语言:javascript复制
 //在没有使用 `<script setup>` 的组件中定义prop 
 export default {
  props: ['propA', 'propB', 'propC'],
  setup(props) {
    // setup() 接收 props 作为第一个参数
    console.log(props.foo)
  }
}
使用

在使用

代码语言:javascript复制
<script setup>
import { defineProps } from 'vue'
const props = defineProps(['propA', 'propB', 'propC'])
console.log(props.foo)
</script>

使用对象的形式定义props

定义props,也可以通过对象形式声明,对于以对象形式声明中的每个属性,key 是 prop 的名称,而值则是该 prop 预期类型的构造函数。

没有使用 <script setup> 的组件中定义prop
代码语言:javascript复制
// 非 <script setup>
export default {
 props: {
    // 确定props类型
    propA: Number,
    // 确定多个类型,其中可以设置默认值
    propB: [String, Number],
    // 自定义校验规则
    propC: {
      type: String,
      required: true,
      validator: function (value) {
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
}
使用
代码语言:javascript复制
// 使用 <script setup>
defineProps({
   // 确定props类型
    propA: Number,
    // 确定多个类型,其中可以设置默认值
    propB: [String, Number],
    // 自定义校验规则
    propC: {
      type: String,
      required: true,
      validator: function (value) {
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
})

定义成对象形式的Props更加灵活,可以设置数据类型、验证规则、默认值等属性。

如何使用props

在Vue3中,使用props需要进行以下几个步骤:

  1. 在组件选项中声明props:
代码语言:javascript复制
props: {
  propA: String,
  propB: {
    type: Number,
    required: true
  },
  propC: {
    type: [String, Number],
    default: 'default value'
  }
}
  1. 在组件的模板中使用props:
代码语言:javascript复制
<template>
  <div>
    <p>Prop A: {{ propA }}</p>
    <p>Prop B: {{ propB }}</p>
    <p>Prop C: {{ propC }}</p>
  </div>
</template>
  1. 在父组件中通过绑定属性的方式传入props:
代码语言:javascript复制
<template>
  <my-component prop-a="valueA" :prop-b="valueB"></my-component>
</template>

在以上代码中,“propA”、“propB”和“propC”是props的名称,“String”和“Number”是props的类型,“default value”是props的默认值,“valueA”和“valueB”是传入props的实际值。

props的使用场景

当我们需要在父组件和子组件之间进行数据传递时,就可以使用 Props。比如,在一个商品列表页面中,可以定义一个 ProductList 的父组件,子组件 ProductItem 可以通过 Props 接收父组件传递过来的产品信息,用于渲染商品列表。代码示例如下

  1. 在父组件 ProductList 中,定义一个产品列表,然后使用 v-for 指令遍历产品列表,将每个产品作为一个子组件 ProductItemproduct props 传递给子组件:
代码语言:javascript复制
<template>
  <div>
    <ProductItem v-for="product in products" :key="product.id" :product="product" />
  </div>
</template>
<script>
import ProductItem from './ProductItem.vue'
export default {
  components: {
    ProductItem
  },
  data() {
    return {
      products: [
        {
          id: 1,
          name: 'Product A',
          price: 100,
          description: 'This is product A'
        },
        {
          id: 2,
          name: 'Product B',
          price: 200,
          description: 'This is product B'
        }
      ]
    }
  }
}
</script>
  1. 在子组件 ProductItem 中,通过 props 对象声明一个名为 product 的 props,然后通过模板插值,将父组件传递过来的产品信息进行渲染:
代码语言:javascript复制
<template>
  <div>
    <h2>{{ product.name }}</h2>
    <p>{{ product.description }}</p>
    <p>Price: {{ product.price }}</p>
  </div>
</template>
<script>
export default {
  props: {
    product: {
      type: Object,
      required: true
    }
  }
}
</script>

在上面的代码中,父组件 ProductList 将产品列表 products 传递给子组件 ProductItemproduct props,子组件 ProductItem 接收并渲染产品信息。这样可以很容易地实现在一个商品列表页面中渲染商品列表。

属性验证

前面提到过,在vue中可以通过定义 props 对象的方式进行Props校验。

为了校验一个属性,可以在 props 对象中添加一个与该属性名称相同的属性,该属性的值为一个对象。这个对象可以包含以下选项:

  • type: 指定属性的类型。可以为 JavaScript 原生构造函数(如 String、Number、Boolean)或自定义构造函数。如果指定多个可选类型,可以使用数组 [String, Number] 的方式表示。
  • required: 指定该属性是否是必需的。如果该属性没有默认值,并且父组件没有传递该属性,则会在控制台中打印警告。
  • default: 指定该属性的默认值。如果父组件没有传递该属性,则使用默认值。如果 default 的值是对象或数组,必须将其设置为函数,并在函数中返回它,以避免值之间的共享。
  • validator: 指定一个自定义验证器函数,用于在接收到 prop 的值时检查其有效性。

例如,下面的组件定义了一个名为 my-component 的组件,其中有一个 prop 名称为 age,类型为 Number,且必需:

代码语言:javascript复制
<template>
  <div>
    <p>My age is: {{ age }}</p>
  </div>
</template>
<script>
export default {
  props: {
    age: {
      type: Number,
      required: true
    }
  }
}
</script>

如果 my-component 在使用时没有传递 age 属性或 age 的值不是一个数字,则会在控制台中打印一个警告。如果正确设置了 prop,则会将其传递给组件,并在模板中进行渲染。

除了上面提到的选项之外,还可以通过 props 对象的 .default.required.type.validator 属性来直接进行校验,例如:

代码语言:javascript复制
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  props: {
    message: {
      default: 'default message',
      required: true,
      type: String,
      validator: (value) => {
        return value.length <= 10
      }
    }
  }
}
</script>

在这个例子中,message 属性的默认值是 default message,必需且类型为 String,并且在传递给子组件时使用 validator 函数进行验证。在这个例子中,验证器函数检查 message 是否超过 10 个字符,如果超过,将返回 false 并打印一个警告。

非 prop 特性

有时候父组件可能会传递一些特定于子组件的非 props 属性,非Prop特性指的是在组件中使用的但未在组件 props 中定义的属性。这些属性可以作为组件模板中的模板占位符或类名和样式绑定。例如传递 CSS 类名或事件监听器。在子组件内可以通过 $attrs 访问这些非 prop 特性。

  • attrs: 包含了父作用域中不被认作 props 的特性绑定 (class 和 style 除外)。当一个组件被创建时,所有的特性 (除了已经在 prop 中定义的特性) 都会被自动添加到 child component 实例的 attrs 对象中。

比如在下面的代码中,定义了一个 MyComponent 组件,其中定义了两个 propmessagecolor)和一个非 prop 特性 title。这个组件使用 props 的值渲染了一个 <div> 元素,并将非 prop 特性绑定到该元素上:

代码语言:javascript复制
<template>
  <div :style="{ color }" :title="title">
    {{ message }}
  </div>
</template>
<script>
export default {
  props: {
    message: {
      type: String
    },
    color: {
      type: String,
      default: 'black'
    }
  },
  setup(props, { attrs }) {
    // 获取非 prop 特性 title 的值
    const title = attrs.title
    return {
      title
    }
  }
}
</script>

在上面的代码中,我们使用了 $attrs 对象来获取非 prop 特性 title 的值,并将其暴露给组件模板。例如,如果我们这样使用 MyComponent 组件:

代码语言:javascript复制
<MyComponent message="Hello world" color="red" title="This is a title" />

则会在页面上渲染一个红色的 <div> 元素,并带有一个 title 特性。由于 title 不是一个 prop,因此我们需要使用 $attrs 对象来获取它的值。

单向数据流特性

在 Vue 组件中,Props 是单向数据流的。这意味着,数据只能从父组件传递到子组件,而不能反向传递。这样的特性可以减少数据传递的混乱和错乱,也使得数据流动更加直观和易于维护。

在子组件中,不能直接更改由父组件传递过来的 Props 的值。如果需要更改 Props 的值,则应该使用事件等方式,比如通过 $emit 方法向父组件传递修改的信息,让父组件更改数据。

props的默认属性

Props 的默认特性就是用来处理默认值的。通常情况下,Props 接收的都是从父组件传递的数据,但是有时候如果父组件没有传递数据,则需要使用默认值。在定义 Props 时,可以使用 default 选项为 Props 指定默认值。 例如:

代码语言:javascript复制
props: {
  message: {
    type: String,
    default: 'Hello, Vue!'
  }
}

在上面的代码中,对 Props message 设置了默认值为 Hello, Vue!,如果在父组件没有传递 message 数据时,props message 的值就会是默认值 Hello, Vue!

此外,父组件也可以通过使用 v-bind 来动态地绑定 Props 的值。例如:

代码语言:javascript复制
<template>
  <example-component v-bind:message="dynamicMessage"></example-component>
</template>
<script>
export default {
  data() {
    return {
      dynamicMessage: '动态绑定的消息'
    }
  }
}
</script>

在上面的代码中,dynamicMessage 是父组件中的数据,用它来动态绑定 Props 的值。在子组件中,可以使用 props.message 来访问父组件传递过来的数据。 好了,关于vue中的Props的详细介绍就到这里了,有疑问的小伙伴评论区留言。

0 人点赞