news 2026/6/10 9:40:42

Vue 3中:setup 函数接收两个重要参数:props 和 context

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue 3中:setup 函数接收两个重要参数:props 和 context

props是响应式的只读对象,需通过defineProps声明,可使用toRefs保持解构后的响应性。


context包含三个非响应式属性:attrs(未声明的属性)、slots(插槽内容)和emit(触发事件)。


在<script setup>中推荐使用useAttrs()、useSlots()和defineEmits()。


注意事项包括setup执行时机、响应式丢失风险及TypeScript支持。


最佳实践建议优先使用<script setup>语法糖,配合类型声明和emit事件通信,充分利用Vue3响应式系统。


在 Vue3 的 Composition API 中,setup函数接收两个重要参数:propscontext


1.props 参数

props是响应式的对象,包含组件接收的所有 prop。


特性:

  • 响应式:当父组件传递的 prop 变化时,props会自动更新

  • 只读:不能在子组件中直接修改(会触发警告)

  • 需要显式声明:必须通过definePropsprops选项声明


基本使用:

vue

<script setup> import { toRefs, watch } from 'vue' // 声明 props const props = defineProps({ title: String, count: { type: Number, default: 0 } }) // 直接使用 console.log(props.title) // 监听 props 变化 watch(() => props.count, (newVal) => { console.log('count changed:', newVal) }) // 解构 props(会失去响应性) const { title } = props // ❌ 非响应式 // 保持响应性的解构 const { title, count } = toRefs(props) // ✅ 响应式 </script>

2.context 参数

context是一个普通对象(非响应式),包含三个组件属性。

context 包含三个属性:


a)attrs

vue

<script setup> import { useAttrs } from 'vue' // 方式一:通过 setup 参数 setup(props, context) { console.log(context.attrs) // 所有未在 props 中声明的 attribute } // 方式二:在 <script setup> 中使用 useAttrs() const attrs = useAttrs() console.log(attrs.class) // 获取 class 属性 console.log(attrs.onClick) // 获取事件监听器 </script>

  • 包含所有未在 props 中声明的 attribute

  • 包括classstyle、事件监听器等

  • 非响应式,但会自动更新


b)slots

vue

<script setup> import { useSlots } from 'vue' // 方式一:通过 setup 参数 setup(props, context) { // 检查插槽是否存在 if (context.slots.default) { // 渲染插槽内容 return () => context.slots.default() } } // 方式二:在 <script setup> 中使用 useSlots() const slots = useSlots() console.log(slots.default) // 默认插槽 console.log(slots.header) // 具名插槽 </script>

  • 包含所有插槽内容的函数

  • 用于渲染插槽内容或检查插槽是否存在


c)emit

vue

<script setup> import { defineEmits } from 'vue' // 方式一:通过 setup 参数 setup(props, context) { const handleClick = () => { context.emit('update', newValue) } } // 方式二:在 <script setup> 中使用 defineEmits() const emit = defineEmits(['update', 'delete']) const handleClick = () => { emit('update', { id: 1, value: 'new' }) emit('delete', 1) } </script>

  • 用于触发自定义事件

  • 推荐使用defineEmits进行声明


3.完整示例

选项式 API 写法:

vue

<script> import { toRefs, watch } from 'vue' export default { props: ['title', 'count'], emits: ['update-count'], setup(props, context) { // 使用 props const { title, count } = toRefs(props) // 使用 attrs console.log('所有 attributes:', context.attrs) // 使用 slots const hasHeaderSlot = !!context.slots.header // 使用 emit const increment = () => { context.emit('update-count', count.value + 1) } // 监听 props 变化 watch(count, (newVal) => { console.log('Count updated:', newVal) }) return { title, count, increment, hasHeaderSlot } } } </script>

<script setup>语法糖写法:

vue

<script setup> import { toRefs, watch, useAttrs, useSlots } from 'vue' // 声明 props const props = defineProps({ title: String, count: Number }) // 声明 emits const emit = defineEmits(['update-count']) // 使用 attrs 和 slots const attrs = useAttrs() const slots = useSlots() // 响应式解构 props const { title, count } = toRefs(props) // 检查插槽 const hasHeaderSlot = !!slots.header // 方法 const increment = () => { emit('update-count', count.value + 1) } // 监听器 watch(count, (newVal) => { console.log('Count updated:', newVal) }) </script> <template> <div :class="attrs.class"> <slot name="header" v-if="hasHeaderSlot" /> <h2>{{ title }}</h2> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <slot /> </div> </template>

4.注意事项

  1. setup 执行时机:在beforeCreate之前执行,此时无法访问this

  2. 响应式丢失:直接解构 props 会丢失响应性,使用toRefstoRef

  3. attrs 非响应式:但会自动更新,无需担心

  4. TypeScript 支持


vue

<script setup lang="ts"> interface Props { title: string count?: number } const props = defineProps<Props>() const emit = defineEmits<{ (e: 'update', value: number): void }>() </script>

5.最佳实践

  1. 优先使用<script setup>语法糖

  2. 使用definePropsdefineEmits进行声明

  3. 需要响应式解构时使用toRefs

  4. 避免直接修改 props,使用 emit 触发事件

  5. 使用 TypeScript 增强类型安全


通过合理使用这两个参数,可以更好地组织组件逻辑,并充分利用 Vue3 的响应式系统。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 14:38:08

LangChain应用增强:为Agent添加语音反馈能力,提升交互体验

LangChain应用增强&#xff1a;为Agent添加语音反馈能力&#xff0c;提升交互体验 在构建智能对话系统时&#xff0c;文本交互虽然高效&#xff0c;但缺乏情感温度和自然性。随着多模态AI技术的发展&#xff0c;语音反馈正成为提升用户沉浸感与交互体验的关键一环。本文将介绍如…

作者头像 李华
网站建设 2026/6/10 0:10:22

收藏!后端转大模型应用开发:避开坑,用工程化能力快速破局

很多后端同学问我&#xff1a;“现在转大模型应用开发晚不晚&#xff1f;”我的答案是&#xff1a;不晚&#xff0c;而且正是好时候&#xff01;大模型赛道不缺能调参跑Demo的人&#xff0c;缺的是咱们这种懂系统架构、能扛高并发、会做生产级落地的后端工程师。大模型应用开发…

作者头像 李华
网站建设 2026/6/10 12:58:15

dify应用增强:为AI对话添加自然语音输出功能

dify应用增强&#xff1a;为AI对话添加自然语音输出功能 在构建智能对话系统时&#xff0c;文本交互虽已成熟&#xff0c;但自然、富有情感的语音输出能极大提升用户体验。尤其是在教育、客服、陪伴机器人等场景中&#xff0c;让AI“开口说话”已成为刚需。本文将介绍如何基于 …

作者头像 李华
网站建设 2026/6/10 12:50:27

用Sambert-HifiGan为电子导览系统添加多语言语音

用Sambert-HifiGan为电子导览系统添加多语言语音 &#x1f4cc; 背景与需求&#xff1a;电子导览中的语音合成挑战 在现代智慧文旅、博物馆导览、智能客服等场景中&#xff0c;高质量的语音播报能力已成为提升用户体验的关键环节。传统的预录音频方案存在维护成本高、扩展性差的…

作者头像 李华
网站建设 2026/6/10 6:36:13

电商促销语音自动合成:基于Sambert-Hifigan镜像的落地实践分享

电商促销语音自动合成&#xff1a;基于Sambert-Hifigan镜像的落地实践分享 在电商运营场景中&#xff0c;个性化、高效率的营销内容生成正成为提升转化率的关键手段。其中&#xff0c;促销语音作为直播带货、APP推送、智能外呼等渠道的重要载体&#xff0c;其制作效率和情感表现…

作者头像 李华
网站建设 2026/6/9 23:31:49

Sambert-HifiGan语音情感分析:如何准确表达情绪

Sambert-HifiGan语音情感分析&#xff1a;如何准确表达情绪 引言&#xff1a;中文多情感语音合成的技术演进与挑战 随着人机交互场景的不断深化&#xff0c;传统“机械化”的语音合成已无法满足用户对自然、富有情感表达的需求。尤其在智能客服、有声阅读、虚拟主播等应用中&am…

作者头像 李华