有時我們只希望外部對 Component 提供初始值,並不需要與外部 State 連動,此時可使用 defineProps()
+ ref()
組合完成。
Version
Vue 3.4
ref()
- Prop 只提供 component 的初始值,之後外部 state 變動不會影響 component 內部 state
App.vue
<template>
<div>
<button @click="onClick">Outer +</button>
<span>External State: {{ count }}</span>
</div>
<MyCounter :initialCount="count" />
</template>
<script setup>
import { ref } from 'vue'
import MyCounter from '@/components/MyCounter.vue'
let count = ref(10)
let onClick = () => count.value++
</script>
Line 2
<div>
<button @click="onClick">Outer +</button>
<span>External State: {{ count }}</span>
</div>
- 外部 state 可不斷遞增
Line 6
<MyCounter :initialCount="count" />
外部 state 透過
initialCount
prop 傳進MyCounter
component<MyCounter />
:若沒有要傳入 HTML,則以 self closing 結尾:initialCount
:傳入 prop,:
為v-bind:
的縮寫
,在 3.4 若傳入的 state 與 prop名稱相同
,只要寫 prop 名稱即可
Component Naming Convention
Component
:Component 名稱與 File 名稱以CamelCase
組合兩個單字
(單一單字
留給 HTML 跟 Vue 以作區別),假如真的找不到兩個單字,前面加The
Prop
:以camelCase
組和兩個單字
MyCounter
MyCounter.vue
<template>
<div class="box">Internal State: {{ count }}</div>
</template>
<script setup>
import { ref } from 'vue'
let props = defineProps({ initialCount: Number })
let count = ref(props.initialCount * 10)
</script>
<style scoped>
.box {
border-style: solid;
border-width: 2px;
border-color: red;
width: fit-content;
}
</style>
Line 8
let props = defineProps({ initialCount: Number })
let count = ref(props.initialCount * 10)
defineProps()
:定義initialCount
propref()
:在ref()
內讀取 prop 並加工,因為使用了ref()
,所以count
state 切斷了與initialCount
prop 的連動性
Options API
App.vue
<template>
<div>
<button @click="onClick">Outer +</button>
<span>External State: {{ count }}</span>
</div>
<MyCounter :initialCount="count" />
</template>
<script>
import MyCounter from '@/components/MyCounter.vue'
export default {
components: {
MyCounter
},
data: () => ({
count: 10
}),
methods: {
onClick() {
this.count++
}
}
}
</script>
- 最後附上相同功能的 Options API 供參考
- Component 除了要
import
外,還要在components
下宣告
MyCounter.vue
<template>
<div class="box">Internal State: {{ count }}</div>
</template>
<script>
export default {
props: {
initialCount: Number
},
data: function () {
return {
count: this.initialCount * 10
}
}
}
</script>
<style scoped>
.box {
border-style: solid;
border-width: 2px;
border-color: red;
width: fit-content;
}
</style>
- Prop 在
props
key 下以 Object 宣告 - 以
this
直接讀取 prop,data
必須改用function
,而不能使用 arrow function
Conclusion
- 若 component 只需外部 state 提供初始值,之後就與外部 state 無關,則適合使用
defineProps()
+ref()
組合