Appearance
元件溝通
Props
在父元件綁定屬性給子元件後,子元件內還需要宣告 Props,才能取用綁定的屬性。
defineProps
使用 defineProps()
宣告 Props,定義 props 的名稱、型別,撰寫型別是讓程式易懂,也可以讓組件使用者知道傳遞的型別是否正確。
html
<script setup>
const props = defineProps({
title: String,
greetingMessage: String,
likes: Number,
abc: {
type: String,
required: true,
default: 'success', // 可以是表達式
// 可以自訂驗證
validator:(value) => ['success', 'warning', 'danger'].includes(value)
}
})
</script>
<script setup>
const props = defineProps({
title: String,
greetingMessage: String,
likes: Number,
abc: {
type: String,
required: true,
default: 'success', // 可以是表達式
// 可以自訂驗證
validator:(value) => ['success', 'warning', 'danger'].includes(value)
}
})
</script>
html
<script setup lang="ts">
const props = defineProps<{
title?: string
greetingMessage?: String,
likes?: number,
abc: {
type: String,
required: true,
default: 'success', // 可以是表達式
// 可以自訂驗證
validator:(value) => ['success', 'warning', 'danger'].includes(value)
}
}>()
</script>
<script setup lang="ts">
const props = defineProps<{
title?: string
greetingMessage?: String,
likes?: number,
abc: {
type: String,
required: true,
default: 'success', // 可以是表達式
// 可以自訂驗證
validator:(value) => ['success', 'warning', 'danger'].includes(value)
}
}>()
</script>
Emits
html
<template>
<button @click="buttonClick('payload')">onclick</button>
<button @click="$emit('submit', 'payload')">onclick</button>
</template>
<script setup>
const emit = defineEmits(['submit'])
const buttonClick = (e) => {
const payload = e
emit('submit', payload)
}
</script>
<template>
<button @click="buttonClick('payload')">onclick</button>
<button @click="$emit('submit', 'payload')">onclick</button>
</template>
<script setup>
const emit = defineEmits(['submit'])
const buttonClick = (e) => {
const payload = e
emit('submit', payload)
}
</script>
事件修飾符
vue
<template>
<!-- 點擊事件的傳播將被停止 -->
<a @click.stop="doit"></a>
<!-- 提交事件將不再重新加載頁面 -->
<form @submit.prevent="doit"></form>
<!-- 可以鏈接修飾符 -->
<a @click.stop.prevent="doit"></a>
<!-- 只有修飾符 -->
<form @submit.prevent></form>
<!-- 只有當 event.target 是元素本身時才觸發處理程序 -->
<!-- 也就是說不理會來自子元素冒泡的事件 -->
<div @click.self="doit"></div>
</template>
<template>
<!-- 點擊事件的傳播將被停止 -->
<a @click.stop="doit"></a>
<!-- 提交事件將不再重新加載頁面 -->
<form @submit.prevent="doit"></form>
<!-- 可以鏈接修飾符 -->
<a @click.stop.prevent="doit"></a>
<!-- 只有修飾符 -->
<form @submit.prevent></form>
<!-- 只有當 event.target 是元素本身時才觸發處理程序 -->
<!-- 也就是說不理會來自子元素冒泡的事件 -->
<div @click.self="doit"></div>
</template>
按鍵修飾符
任何來自KeyboardEvent.key的 key name 都可以作為修飾符,但要轉換為 kebab-case 的形式。
vue
<template>
<!-- 只有當 key 是 Enter 時才調用 submit -->
<input @keyup.enter="submit" />
<!-- Alt + Enter 組合 -->
<input @keyup.alt.enter="clear" />
<!-- PageDown 轉為 kebab-case 可作為修飾符 -->
<input @keyup.page-down="onPageDown" />
</template>
<template>
<!-- 只有當 key 是 Enter 時才調用 submit -->
<input @keyup.enter="submit" />
<!-- Alt + Enter 組合 -->
<input @keyup.alt.enter="clear" />
<!-- PageDown 轉為 kebab-case 可作為修飾符 -->
<input @keyup.page-down="onPageDown" />
</template>
provide
如果只用 props 需要傳遞好幾次: 使用 provide/inject:
使用方法
- 上層元件使用 provide 提供;內層元件使用 inject 接。
- reactive state 可以被 provide。 provide:
vue
<script setup>
import { ref, provide } from 'vue';
const count = ref(0);
// 可以 provide 任何種類,字串、數字、物件... etc
provide(/* key */ 'message', /* value */ 'hello!');
// 可以 provide reactive state
provide('key', count);
// 可以宣告為 readonly
provide('read-only-count', readonly(count));
</script>
<script setup>
import { ref, provide } from 'vue';
const count = ref(0);
// 可以 provide 任何種類,字串、數字、物件... etc
provide(/* key */ 'message', /* value */ 'hello!');
// 可以 provide reactive state
provide('key', count);
// 可以宣告為 readonly
provide('read-only-count', readonly(count));
</script>
inject:
vue
<script setup>
import { inject } from 'vue';
// 直接注入
const value = inject('message');
// 可以有預設值
const withDefaultValue = inject('message', 'default value');
// 可以從 function 計算出預設值
const withFactorFunction = inject('key', () => new ExpensiveClass(), true);
</script>
<script setup>
import { inject } from 'vue';
// 直接注入
const value = inject('message');
// 可以有預設值
const withDefaultValue = inject('message', 'default value');
// 可以從 function 計算出預設值
const withFactorFunction = inject('key', () => new ExpensiveClass(), true);
</script>
Working with Reactivity
- 使用 provided state 和 mutations function 保持 reactivity。
- 應盡量把 provided state 和 mutations function 集中在同一個處,易於維護(高內聚性),範例:
vue
<!-- provider component -->
<script setup>
import { provide, ref } from 'vue';
const location = ref('North Pole');
function updateLocation() {
location.value = 'South Pole';
}
provide('location', {
location,
updateLocation,
});
</script>
<!-- provider component -->
<script setup>
import { provide, ref } from 'vue';
const location = ref('North Pole');
function updateLocation() {
location.value = 'South Pole';
}
provide('location', {
location,
updateLocation,
});
</script>
vue
<!-- injector component -->
<template>
<button @click="updateLocation">{{ location }}</button>
</template>
<script setup>
import { inject } from 'vue';
const { location, updateLocation } = inject('location');
</script>
<!-- injector component -->
<template>
<button @click="updateLocation">{{ location }}</button>
</template>
<script setup>
import { inject } from 'vue';
const { location, updateLocation } = inject('location');
</script>
Expose
defineExpose()
暴露元件屬性,上層元件可透過元件參考取得。
vue
<template>
<v-dialog v-model="model">
</v-dialog>
</template>
<script setup>
import { ref } from 'vue'
const model = false
const showDialog = () => model = true
defineExpose({ showDialog });
</script>
<template>
<v-dialog v-model="model">
</v-dialog>
</template>
<script setup>
import { ref } from 'vue'
const model = false
const showDialog = () => model = true
defineExpose({ showDialog });
</script>
Summary
- 元件定義 Props:使用
const props = defineProps()
定義元件 Props,以取用父元件綁定的屬性。<script setup>
當中以props.someprops
取得 props。template
當中直接以取得 props。
- 元件事件定義:使用
const emits = defineEmits(['submit'])
定義元件事件。template
當中以$emit('submit', 'payload')
觸發事件。<script setup>
當中以emits('submit', 'payload')
觸發事件。
- 元件定義 Expose:使用
defineExpose
定義元件暴露的屬性,上層元件透過元件參考取得。 - 父元件事件控制
- 父元件常用
.prevent
、.stop
等等事件修飾符
控制事件傳遞。 - 父元件常用
按鍵修飾符
接收特定按鍵事件。
- 父元件常用