Vue3 引入了 Composition API,其中 setup
函數是 Composition API 的核心部分。setup
函數在組件實例創建之前執行,它接收兩個參數:props
和 context
。context
是一個包含 attrs
、slots
和 emit
的對象。本文將深入分析 setup
函數中的 attrs
、slots
和 emit
,并通過實例演示它們的使用。
setup
函數概述在 Vue3 中,setup
函數是 Composition API 的入口點。它接收兩個參數:
props
:組件的 props 對象。context
:一個包含 attrs
、slots
和 emit
的對象。setup
函數返回一個對象,該對象的屬性將被暴露給模板使用。
export default {
setup(props, context) {
// 在這里可以使用 props 和 context
return {
// 暴露給模板的屬性
};
},
};
attrs
的使用attrs
是一個包含所有非 prop 的 attribute 的對象。這些 attribute 包括 class
、style
以及任何未在 props
中聲明的 attribute。
假設我們有一個組件 MyComponent
,它接收一個 title
prop,并且我們還傳遞了一些其他的 attribute:
<MyComponent title="Hello" class="my-class" data-id="123" />
在 setup
函數中,我們可以通過 context.attrs
訪問這些非 prop 的 attribute:
export default {
setup(props, { attrs }) {
console.log(attrs.class); // 輸出: "my-class"
console.log(attrs['data-id']); // 輸出: "123"
return {
// 暴露給模板的屬性
};
},
};
attrs
我們可以將 attrs
傳遞給子組件,或者在模板中直接使用它們:
export default {
setup(props, { attrs }) {
return {
attrs,
};
},
};
在模板中:
<template>
<div v-bind="attrs">
<!-- 這里可以使用 attrs 中的所有 attribute -->
</div>
</template>
attrs
是響應式的,因此當父組件更新 attribute 時,attrs
會自動更新。attrs
不包含在 props
中聲明的屬性。slots
的使用slots
是一個包含所有插槽內容的對象。通過 slots
,我們可以在 setup
函數中訪問和操作插槽內容。
假設我們有一個組件 MyComponent
,它包含一個默認插槽和一個具名插槽:
<MyComponent>
<template v-slot:default>
<p>Default Slot Content</p>
</template>
<template v-slot:footer>
<p>Footer Slot Content</p>
</template>
</MyComponent>
在 setup
函數中,我們可以通過 context.slots
訪問這些插槽:
export default {
setup(props, { slots }) {
console.log(slots.default()); // 輸出: [VNode]
console.log(slots.footer()); // 輸出: [VNode]
return {
// 暴露給模板的屬性
};
},
};
slots
我們可以將 slots
傳遞給子組件,或者在模板中直接使用它們:
export default {
setup(props, { slots }) {
return {
slots,
};
},
};
在模板中:
<template>
<div>
<slot name="default"></slot>
<slot name="footer"></slot>
</div>
</template>
我們還可以動態地渲染插槽內容:
export default {
setup(props, { slots }) {
const slotName = ref('default');
return {
slotName,
slots,
};
},
};
在模板中:
<template>
<div>
<component :is="slots[slotName]" />
</div>
</template>
slots
是響應式的,因此當父組件更新插槽內容時,slots
會自動更新。slots
中的每個插槽都是一個函數,調用該函數會返回一個 VNode 數組。emit
的使用emit
是一個用于觸發自定義事件的函數。通過 emit
,我們可以在子組件中觸發事件,并在父組件中監聽這些事件。
假設我們有一個組件 MyComponent
,它包含一個按鈕,點擊按鈕時觸發一個自定義事件 click
:
<MyComponent @click="handleClick" />
在 setup
函數中,我們可以通過 context.emit
觸發這個事件:
export default {
setup(props, { emit }) {
const handleClick = () => {
emit('click', 'Hello from MyComponent');
};
return {
handleClick,
};
},
};
在父組件中,我們可以監聽這個事件:
export default {
methods: {
handleClick(message) {
console.log(message); // 輸出: "Hello from MyComponent"
},
},
};
emit
我們可以在模板中直接使用 emit
:
export default {
setup(props, { emit }) {
return {
emit,
};
},
};
在模板中:
<template>
<button @click="emit('click', 'Hello from MyComponent')">Click Me</button>
</template>
emit
是響應式的,因此當父組件更新事件處理函數時,emit
會自動更新。emit
的第一個參數是事件名稱,后續參數是傳遞給事件處理函數的參數。下面是一個綜合使用 attrs
、slots
和 emit
的實例:
export default {
setup(props, { attrs, slots, emit }) {
const handleClick = () => {
emit('click', 'Hello from MyComponent');
};
return {
attrs,
slots,
handleClick,
};
},
};
在模板中:
<template>
<div v-bind="attrs">
<slot name="default"></slot>
<button @click="handleClick">Click Me</button>
<slot name="footer"></slot>
</div>
</template>
在父組件中使用:
<MyComponent class="my-class" @click="handleClick">
<template v-slot:default>
<p>Default Slot Content</p>
</template>
<template v-slot:footer>
<p>Footer Slot Content</p>
</template>
</MyComponent>
在 Vue3 的 setup
函數中,attrs
、slots
和 emit
是非常有用的工具。通過它們,我們可以訪問非 prop 的 attribute、操作插槽內容以及觸發自定義事件。掌握這些工具的使用,可以幫助我們更好地構建靈活且可復用的組件。
希望本文對你理解 Vue3 中的 setup
參數有所幫助。如果你有任何問題或建議,歡迎在評論區留言討論。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。