Menu
×
   ❮   
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 简介 Vue 指令 Vue v-bind Vue v-if Vue v-show Vue v-for Vue 事件 Vue v-on Vue 方法 Vue 事件修饰符 Vue 表单 Vue v-model Vue CSS 绑定 Vue 计算属性 Vue 侦听器 Vue 模板

扩展 应用

Vue 为什么、如何以及如何设置 Vue 第一个 SFC 页面 Vue 组件 Vue 属性 Vue v-for 组件 Vue $emit() Vue 透传属性 Vue 作用域样式 Vue 局部组件 Vue 插槽 Vue v-slot Vue 作用域插槽 Vue 动态组件 Vue 传送门 Vue HTTP 请求 Vue 模板引用 Vue 生命周期钩子 Vue 提供/注入 Vue 路由 Vue 表单输入 Vue 动画 Vue 与 v-for 的动画 Vue 构建 Vue 组合式 API

Vue 参考

Vue 内置属性 Vue 内置组件 Vue 内置元素 Vue 组件实例 Vue 指令 Vue 实例选项 Vue 生命周期钩子

Vue 示例

Vue 示例 Vue 练习 Vue 问答 Vue 服务器 Vue 证书

Vue 属性

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

使用 props,我们可以通过组件标签的自定义属性将数据传递给组件。

将数据传递给组件

还记得上一页的例子吗?所有三个组件都显示了“Apple”?现在使用 props,我们可以将数据传递给组件,让它们拥有不同的内容,并呈现不同的外观。

让我们创建一个简单的页面来显示“苹果”、“披萨”和“米饭”。

在主应用程序文件 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>

接收组件内的 data

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

FoodItem.vue:

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

Props 属性在 <template> 标签中使用连字符 - 来分隔单词(短横线命名法),但短横线命名法在 JavaScript 中是非法的。因此,我们需要在 JavaScript 中使用驼峰命名法来编写属性名称,Vue 会自动理解!

最后,我们使用 <div> 元素创建的“苹果”、“披萨”和“米饭”示例如下:

示例

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> 标签。

要传递与 String 不同的数据类型的 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>

开始练习



×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
[email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
[email protected]

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2024 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.