在 Vue 3 中使用 <script setup> 语法可以让我们更简洁地定义组件内容和逻辑,尤其是在定义 props 时会更方便。以下是使用 <script setup> 语法的所有示例,涵盖 props 的基本用法、类型校验、默认值、只读特性、对象和函数类型的 props、以及解构 props


1. 基本用法

父组件将标题和描述传递给子组件,子组件通过 props 接收并展示这些数据。

<!-- ParentComponent.vue -->
<template>
  <div>
    <ChildComponent title="欢迎" description="这是子组件的描述内容" />
  </div>
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';
</script>
<!-- ChildComponent.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
  </div>
</template>

<script setup>
const props = defineProps({
  title: String,
  description: String
});
</script>

2. 类型校验和默认值

在这个示例中,我们为 props 设置了类型和默认值:

<!-- ChildComponent.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
    <p>Views: {{ views }}</p>
  </div>
</template>

<script setup>
const props = defineProps({
  title: {
    type: String,
    required: true
  },
  description: {
    type: String,
    default: '这是默认的描述内容'
  },
  views: {
    type: Number,
    default: 0
  }
});
</script>

在此示例中:

  • title 为必填项,类型为 String
  • description 有默认值 '这是默认的描述内容'
  • views 的类型为 Number,默认值为 0

3. 基于 props 的计算属性(只读特性)

props 在子组件中是只读的,不能直接修改。以下示例展示了如何基于 props 的值创建计算属性,而不直接修改 props 本身:

<!-- ChildComponent.vue -->
<template>
  <div>
    <h1>{{ fullTitle }}</h1>
  </div>
</template>

<script setup>
import { computed } from 'vue';

const props = defineProps({
  title: String
});

const fullTitle = computed(() => `${props.title} - 子组件`);
</script>

这里使用 computed 创建了一个基于 props.title 的计算属性 fullTitle,不会直接修改 props


4. 传递对象和函数类型的 props

在 Vue 3 中,props 可以传递对象和函数类型的数据,例如用户信息和事件处理函数:

<!-- ParentComponent.vue -->
<template>
  <ChildComponent :user="{ name: '张三' }" :onAction="handleAction" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';

function handleAction() {
  alert('子组件调用的父组件方法');
}
</script>
<!-- ChildComponent.vue -->
<template>
  <div>
    <h2>{{ user.name }}</h2>
    <button @click="onAction">点击处理</button>
  </div>
</template>

<script setup>
const props = defineProps({
  user: {
    type: Object,
    required: true
  },
  onAction: {
    type: Function,
    required: true
  }
});
</script>

在这个例子中,父组件将 user 对象和 onAction 函数作为 props 传递给子组件,子组件可以直接使用这些数据和方法。


5. 使用解构 props

<script setup> 语法中,可以使用解构来简化访问 props。不过需要注意,解构 props 后无法响应更新,因此适用于无需响应更新的情况:

<!-- ChildComponent.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
  </div>
</template>

<script setup>
const { title, description } = defineProps({
  title: String,
  description: String
});
</script>

在这个例子中,titledescription 通过解构 props 直接使用,代码更加简洁,但不具备响应式。


6. 监听 props 变化

可以使用 watch 监听 props 的变化,从而响应父组件传递的数据更新:

<!-- ChildComponent.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
  </div>
</template>

<script setup>
import { watch } from 'vue';

const props = defineProps({
  title: String
});

watch(
  () => props.title,
  (newVal, oldVal) => {
    console.log(`title changed from ${oldVal} to ${newVal}`);
  }
);
</script>

props.title 发生变化时,watch 函数会记录并输出新旧值。