🏃♀️ 背景(👉为什么突然间要写起 defineProps)
有一次有个例子要做teleport,具体代码如下,看到同事在template模板中用props.show这种,后面我说:“在模板中,不需要通过props.show这种形式,直接用show直接用也可以”,遂有了此文做记录📝。
大概代码如下:
<!--
可定制插槽和 CSS 过渡效果的模态框组件。
-->
<script setup>
import Modal from './Modal.vue'
import { ref } from 'vue'
const showModal = ref(false)
</script>
<template>
<button id="show-modal" @click="showModal = true">Show Modal</button>
<Teleport to="body">
<!-- 使用这个 modal 组件,传入 prop -->
<modal :show="showModal" @close="showModal = false">
<template #header>
<h3>Custom Header</h3>
</template>
</modal>
</Teleport>
</template>
// model.vue
<script setup>
const props = defineProps({
show: Boolean
})
</script>
<template>
<Transition name="modal">
<!-- 这里直接用show -->
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<slot name="header">default header</slot>
</div>
<div class="modal-body">
<slot name="body">default body</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button
class="modal-default-button"
@click="$emit('close')"
>OK</button>
</slot>
</div>
</div>
</div>
</Transition>
</template>
大概上面👆teleport的效果是这样的:
🏃♀️ 正文(解释)
模板中自动解构
setup 语法糖:
在 <script setup> 中,Vue 会自动将通过 defineProps 和 defineEmits 声明的 props 和 emits 注入到模板的作用域中。也就是说,Vue 会在内部做一些处理,使得这些 props 和 emits 可以像在 <script setup> 中定义的局部变量一样在模板中直接使用。
<template>
<!-- 可以直接使用 show,而不需要 props.show -->
<div v-if="show" class="modal-mask">
这是一个模态框
</div>
</template>
<script setup>
import { defineProps } from 'vue';
// 定义 props
const props = defineProps({
show: Boolean
});
// 在 <script setup> 中仍然可以通过 props 对象访问
console.log(props.show);
</script>
在上述代码中,defineProps 定义了一个名为 show 的布尔类型的 prop。在模板中,我们可以直接使用 show 来判断是否显示模态框,而不需要写成 props.show。
如果不用setup这种组合式,用选项式来写的话,大致代码如下:
<template>
<!-- 需要使用 this.$props.show -->
<div v-if="this.$props.show" class="modal-mask">
这是一个模态框
</div>
</template>
<script>
export default {
props: {
show: Boolean
},
mounted() {
console.log(this.$props.show);
}
};
</script>
<script setup> 语法通过自动注入 props 到模板作用域,简化了模板中对 props 的使用,使代码更加简洁和直观。
基本用法
在 <script setup> 中使用 defineProps 定义 props 非常简单,只需调用该函数并传入一个对象,对象的键为 prop 的名称,值为 prop 的类型或类型定义。
<template>
<div>
<!-- 直接使用 prop -->
<p>{{ message }}</p>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
// 定义 props
const props = defineProps({
message: String
});
</script>
在上述代码中,定义了一个名为 message 的 prop,其类型为 String。在模板中可以直接使用 message 来显示从父组件传递过来的数据。
复杂类型定义 并 设默认值
<template>
<div>
<p>{{ user.name }}</p>
<p>{{ user.age }}</p>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
user: {
type: Object,
default: () => ({
name: 'Guest',
age: 18
})
}
});
</script>
这里定义了一个 user prop,其类型为 Object,并设置了默认值。如果父组件没有传递 user prop,子组件将使用默认值。
类型检查和必填项设置
可以通过 required 选项来指定某个 prop 是否为必填项。
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
id: {
type: Number,
required: true
},
title: {
type: String,
default: 'Default Title'
}
});
</script>
在这个例子中,id 是必填的 Number 类型 prop,而 title 是可选的 String 类型 prop,有默认值。
🏃♀️ 小结(复盘)
<script setup> 语法为开发者提供了更简洁的语法糖,使得通过 defineProps 定义的 props 可以直接在模板中使用,减少了代码的冗余,提高了开发效率。但在 <script setup> 内部,仍然可以通过 props 对象来访问这些 props。
- 语法简洁:在
<script setup>中使用defineProps避免了传统选项式 API 中复杂的props选项定义,使代码更加简洁易读。 - 自动注入:通过
defineProps定义的 props 会自动注入到模板的作用域中,在模板中可以直接使用 prop 名称,而不需要通过props.xxx的形式访问。 - 静态分析支持:Vue 3 的编译器可以对
defineProps进行静态分析,提供更好的类型检查和 IDE 支持,有助于在开发过程中尽早发现错误。
☎️ 希望对大家有所帮助,如有错误,望不吝赐教,欢迎评论区留言互相学习。