菜单
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

Vue 教程

Vue 首页 Vue Intro Vue Directives Vue v-bind Vue v-if Vue v-show Vue v-for Vue Events Vue v-on Vue Methods Vue Event Modifiers Vue Forms Vue v-model Vue CSS Binding Vue Computed Properties Vue Watchers Vue Templates

Scaling Up

Vue 为什么、如何以及设置 Vue 第一个 SFC 页面 Vue 组件 Vue Props Vue v-for 组件 Vue $emit() Vue Fallthrough Attributes Vue Scoped Styling Vue 本地组件 Vue Slots Vue v-slot Vue Scoped Slots Vue 动态组件 Vue Teleport Vue HTTP 请求 Vue 模板引用 Vue 生命周期钩子 Vue Provide/Inject Vue 路由 Vue 表单输入 Vue 动画 Vue v-for 动画 Vue Build Vue Composition API

Vue Reference

Vue Built-in Attributes Vue Built-in Components Vue Built-in Elements Vue Component Instance Vue Directives Vue Instance Options Vue Lifecycle Hooks

Vue 示例

Vue Examples Vue Exercises Vue Quiz Vue Server Vue Certificate

Vue Props

Props 是 Vue 中的一个配置选项。

通过 props,我们可以通过自定义属性将数据传递给组件,这些属性添加到组件的标签上。

将数据传递给组件

还记得上一页中所有三个组件都显示“Apple”的例子吗?通过 props,我们现在可以将数据传递给我们的组件,为它们提供不同的内容并使它们看起来不同。

让我们创建一个简单的页面来显示“Apples”、“Pizza”和“Rice”。

在主应用程序文件 App.vue 中,我们创建自己的属性“food-name”来通过 <food-item/> 组件标签传递 prop。

App.vue:

<template>
  <h1>Food</h1>
  <food-item food-name="Apples"/>
  <food-item food-name="Pizza"/>
  <food-item food-name="Rice"/>
</template>

<script></script>

<style>
  #app > div {
    border: dashed black 1px;
    display: inline-block;
    width: 120px;
    margin: 10px;
    padding: 10px;
    background-color: lightgreen;
  }
</style>

在组件内部接收数据

要接收从 App.vue 通过“food-item”属性发送的数据,我们使用这个新的“props”配置选项。我们列出接收到的属性,以便我们的组件 *.vue 文件了解它们,现在我们可以在组件内部的任何地方以与使用数据属性相同的方式使用 props。

FoodItem.vue:

<script>
  export default {
    props: [
      'foodName'
    ]
  }
</script>

Props 属性在 <template> 标签中用连字符 - 分隔单词(kebab-case),但在 JavaScript 中 kebab-case 是非法的。所以我们改用 camel Case 在 JavaScript 中写属性名,Vue 会自动识别!

最后,我们用 <div> 元素来显示“Apples”、“Pizza”和“Rice”的例子看起来是这样的

示例

App.vue:

<template>
  <h1>Food</h1>
  <food-item food-name="Apples"/>
  <food-item food-name="Pizza"/>
  <food-item food-name="Rice"/>
</template>

FoodItem.vue:

<template>
  <div>
    <h2>{{ foodName }}</h2>
  </div>
</template>

<script>
  export default {
    props: [
      'foodName'
    ]
  }
</script>

<style></style>
运行示例 »

很快我们将看到如何将不同类型的数据作为 props 属性传递给组件,但在那之前,让我们通过描述每种食物来扩展我们的代码,并将食物 <div> 元素放在 Flexbox 容器内。

示例

App.vue:

<template>
  <h1>Food</h1>
  <div id="wrapper">
    <food-item
      food-name="Apples"
      food-desc="Apples are a type of fruit that grow on trees."/>
    <food-item
      food-name="Pizza"
      food-desc="Pizza has a bread base with tomato sauce, cheese, and toppings on top."/>
    <food-item
      food-name="Rice"
      food-desc="Rice is a type of grain that people like to eat."/>
  </div>
</template>

<script></script>

<style>
  #wrapper {
    display: flex;
    flex-wrap: wrap;
  }
  #wrapper > div {
    border: dashed black 1px;
    margin: 10px;
    padding: 10px;
    background-color: lightgreen;
  }
</style>

FoodItem.vue:

<template>
  <div>
    <h2>{{ foodName }}</h2>
    <p>{{ foodDesc }}</p>
  </div>
</template>

<script>
  export default {
    props: [
      'foodName',
      'foodDesc'
    ]
  }
</script>

<style></style>
运行示例 »

布尔 Props

通过传递不同数据类型的 props,我们可以实现不同的功能,并且我们能够定义当组件从 App.vue 创建时如何给出属性的规则。

让我们添加一个新 prop“isFavorite”。它应该是一个布尔 prop,值为 truefalse,这样我们就可以直接使用 v-show 来显示一个喜欢的印章 <img> 标签,如果该食物被认为是喜欢的。

要传递字符串以外的数据类型的 props,我们必须在要传递的属性前加上 v-bind:

这就是我们从 App.vue 将布尔值“isFavorite” prop 作为“is-favorite”属性传递的方式

App.vue:

<template>
  <h1>Food</h1>
  <p>My favorite food has a diploma image attached to it.</p>
  <div id="wrapper">
    <food-item
      food-name="Apples"
      food-desc="Apples are a type of fruit that grow on trees."
      v-bind:is-favorite="true"/>
    <food-item
      food-name="Pizza"
      food-desc="Pizza has a bread base with tomato sauce, cheese, and toppings on top."
      v-bind:is-favorite="false"/>
    <food-item
      food-name="Rice"
      food-desc="Rice is a type of grain that people like to eat."
      v-bind:is-favorite="false"/>
  </div>
</template>

我们在 FoodItem.vue 中接收布尔值“isFavorite” prop,如果食物被认为是喜欢的,则显示一个喜欢的印章

示例

FoodItem.vue:

<template>
  <div>
    <h2>
      {{ foodName }}
      <img src="/img_quality.svg" v-show="isFavorite">
    </h2>
    <p>{{ foodDesc }}</p>
  </div>
</template>

<script>
  export default {
      props: ['foodName','foodDesc','isFavorite']
  }
</script>

<style>
  img {
    height: 1.5em;
    float: right;
  }
</style>
运行示例 »

图片:要使上面示例中的图片在您计算机上的本地项目中正常工作,请打开上面的示例,右键单击图片,选择“另存为图像...”并将其保存在项目中的“public”文件夹中。


Props 接口

在上面的示例中,根据 FoodItem.vue 中的代码,我们无法确切知道我们收到了“isFavorite” prop,也无法确切知道它是否是布尔值。为了帮助我们,我们可以定义接收的 props 的数据类型,我们可以设置 props 为必需的,我们甚至可以创建验证函数来验证我们接收到的 props。

定义我们接收的 props 可以作为文档供团队中的其他人参考,如果我们定义的规则被打破,它会在控制台中为我们提供警告。


Props 作为对象

FoodItem.vue 中,我们注释掉了如何将 props 定义为数组以便作为参考,而是将 props 定义在一个对象中。我们还可以定义每个 prop 的数据类型,除了 prop 名称,如下所示

FoodItem.vue:

<script>
  export default {
    // props: ['foodName','foodDesc','isFavorite']
    props: {
      foodName: String,
      foodDesc: String,
      isFavorite: Boolean
    }
  }
</script>

通过这样定义 props,其他人可以查看 FoodItem.vue 并轻松了解组件的预期。

如果一个组件是从父元素(在我们的例子中是 App.vue)创建的,并且给定了一个错误数据类型的 prop,您会在控制台中看到一个警告,如下所示

Screenshot of wrong data type prop warning

这样的警告很有用,可以让我们自己和他人知道一个组件没有按预期使用,并告知是什么出了问题,以便我们可以纠正错误。


必需的 Props

要告诉 Vue prop 是必需的,我们需要将 prop 定义为一个对象。让我们将“foodName” prop 定义为必需的,如下所示

FoodItem.vue:

<script>
  export default {
    // props: ['foodName','foodDesc','isFavorite']
    props: {
      foodName: {
        type: String,
        required: true
      },
      foodDesc: String,
      isFavorite: Boolean
    }
  }
</script>

如果一个组件是从父元素(在我们的例子中是 App.vue)创建的,并且没有定义必需的 prop,您会在控制台中看到一个警告,如下所示

Screenshot of required prop warning

这样的警告很有用,可以让我们自己和他人知道一个组件没有按预期使用,并告知是什么出了问题,以便我们可以纠正错误。


默认值

我们可以为 prop 设置默认值。

让我们为“FoodItem”组件中的“foodDesc” prop 创建一个默认值,然后为米饭创建一个这样的项,而不定义“foodDesc” prop

示例

App.vue:

<template>
  <h1>Food</h1>
  <p>My favorite food has a diploma image attached to it.</p>
  <div id="wrapper">
    <food-item
      food-name="Apples"
      food-desc="Apples are a type of fruit that grow on trees."
      v-bind:is-favorite="true"/>
    <food-item
      food-name="Pizza"
      food-desc="Pizza has a bread base with tomato sauce, cheese, and toppings on top."
      v-bind:is-favorite="false"/>
    <food-item
      food-name="Rice"
      food-desc="Rice is a type of grain that people like to eat." 
      v-bind:is-favorite="false"/>
  </div>
</template>

FoodItem.vue:

<script>
  export default {
    props: {
      foodName: {
        type: String,
        required: true
      },
      foodDesc: {
        type: String,
        required: false,
        default: 'This is the default description.'
      }
      isFavorite: {
        type: Boolean,
        required: false,
        default: false
      }
    }
  }
</script>
运行示例 »

Props 验证器函数

我们还可以定义一个验证器函数来决定 prop 值是否有效。

这些验证器函数必须返回 true 或 false。当验证器返回 false 时,表示 prop 值无效。无效的 prop 值在以开发者模式运行页面时会在浏览器控制台中生成警告,该警告是有用的提示,可以确保组件按预期使用。

假设我们希望食物描述具有一定的长度,在 20 到 50 个字符之间。我们可以添加一个验证器函数来确保提供的食物描述具有有效长度。

FoodItem.vue:

<script>
  export default {
    props: {
      foodName: {
        type: String,
        required: true
      },
      foodDesc: {
        type: String,
        required: false,
        default: 'This is the default description.',
        validator: function(value) {
          if( 20<value.length && value.length<50 ) {
            return true;
          }
          else {
            return false;
          }
        }
      }
      isFavorite: {
        type: Boolean,
        required: false,
        default: false
      }
    }
  }
</script>

注意:如果您将上面的验证器代码添加到您的本地项目中,您将在开发模式下收到一个警告,因为披萨的食物描述是 65 个字符,比验证器函数允许的字符长 15 个。


修改 Props

当一个组件在父元素中创建时,我们不允许在子元素中更改接收到的 prop 的值。所以,在 FoodItem.vue 内部,我们不能更改从 App.vue 接收到的“isFavorite” prop 的值。prop 从父级是只读的,在我们的例子中,父级是 App.vue

但是,假设我们希望用户能够通过单击按钮来更改哪些食物被视为喜欢的。现在需要更改“isFavorite” prop,但我们不能这样做,因为它被标记为只读。

我们不允许更改“isFavorite”。这将生成一个错误。

methods: {
  toggleFavorite() { 
    this.isFavorite = !this.isFavorite;
  }
}

为了解决这个问题,我们可以使用 prop 来初始化 FoodItem.vue 内部的一个新数据值“foodIsFavorite”,如下所示

data() {
  return { 
    foodIsFavorite: this.isFavorite
  }
}

现在我们可以添加一个方法,以便用户可以切换这个新的数据值

methods: {
  toggleFavorite() { 
    this.foodIsFavorite = !this.foodIsFavorite;
  }
}

我们还必须为每个食物项添加切换按钮,并将 <img> 标签中的 v-show 设置为依赖于新的数据属性“foodIsFavorite”。为了使我们的示例更简单,我们还将 props 声明简化为仅数组。

示例

FoodItem.vue:

<template>
  <div>
    <h2>
      {{ foodName }}
      <img src="/img_quality.svg" v-show="foodIsFavorite">
    </h2>
    <p>{{ foodDesc }}</p>
    <button v-on:click="toggleFavorite">Favorite</button>
  </div>
</template>

<script>
  export default {
  props: ['foodName','foodDesc','isFavorite'],
  data() {
    return {
      foodIsFavorite: this.isFavorite
    }
  },
  methods: {
    toggleFavorite() {
      this.foodIsFavorite = !this.foodIsFavorite;
    }
  }
}
</script>

<style>
  img {
    height: 1.5em;
    float: right;
  }
</style>
运行示例 »

Vue 练习

通过练习来测试自己

练习

为了让一个组件接收从 App.vue 通过 'fish-name' 属性发送的数据作为 prop,我们必须在组件中写什么?

<script>
  export default {
    : [
      ''
    ]
  }
</script>

开始练习



×

联系销售

如果您想将 W3Schools 服务用于教育机构、团队或企业,请发送电子邮件给我们
sales@w3schools.com

报告错误

如果您想报告错误,或想提出建议,请发送电子邮件给我们
help@w3schools.com

W3Schools 经过优化,旨在方便学习和培训。示例可能经过简化,以提高阅读和学习体验。教程、参考资料和示例会不断审查,以避免错误,但我们无法保证所有内容的完全正确性。使用 W3Schools 即表示您已阅读并接受我们的使用条款Cookie 和隐私政策

版权所有 1999-2024 Refsnes Data。保留所有权利。W3Schools 由 W3.CSS 提供支持