最近跟着技術胖學習了vue3 和 typescript 記錄一下自己的學習過程
現在寫一個簡單的菜單選擇功能
1 <template> 2 <div class="hello"> 3 <div> 4 <h2>歡迎光臨呱呱的小店</h2> 5 <div>請選擇你喜歡的服務員</div> 6 </div> 7 <div> 8 <button 9 v-for="(item, index) in girls" 10 :key="index" 11 @click="girlsnumFun(index)" 12 > 13 {{ item }} 14 </button> 15 </div> 16 <div>當前選擇的是 【{{ girlsnum }}】</div> 17 </div> 18 </template>
1 <script lang="ts"> 2 import { defineComponent, ref } from "vue"; 3 export default defineComponent({ 4 name: "hello", 5 setup() { 6 const girls = ref(["服務員1", "服務員2", "服務員3"]); 7 const girlsnum = ref(''); 8 const girlsnumFun = (item: number) => { 9 girlsnum.value = girls.value[item]; 10 }; 11 return { 12 girls, 13 girlsnum, 14 girlsnumFun, 15 }; 16 }, 17 }); 18 </script>
setup()
- setup 是一個新的組件選項 ,作為在組件內使用 composition api 的入口
- 調用時機: 創建組件實例 ,初始化props,緊接着調用setup函數。從生命周期鈎子的視角來看,它會在
beforeCreate
鈎子之前被調用 - 返回一個對象,則對象的屬性將會被合並到組件模板的渲染上下文
- 返回一個函數,函數中也能使用當前
setup
函數作用域中的響應式數據
1 import { h, ref, reactive } from 'vue' 2 3 export default { 4 setup() { 5 const count = ref(0) 6 const object = reactive({ foo: 'bar' }) 7 8 return () => h('div', [count.value, object.foo]) 9 }, 10 }
- 參數
該函數接收 props
作為其第一個參數 然而不要解構 props
對象,那樣會使其失去響應性
1 export default { 2 props: { 3 name: String, 4 }, 5 setup(props) { 6 console.log(props.name) 7 }, 8 }
注意 props
對象是響應式的,watchEffect
或 watch
會觀察和響應 props
的更新:
1 export default { 2 props: { 3 name: String, 4 }, 5 setup(props) { 6 watchEffect(() => { 7 console.log(`name is: ` + props.name) 8 }) 9 }, 10 }
- 類型定義
1 interface Data { 2 [key: string]: unknown 3 } 4 5 interface SetupContext { 6 attrs: Data 7 slots: Slots 8 emit: (event: string, ...args: unknown[]) => void 9 } 10 11 function setup(props: Data, context: SetupContext): Data
ref()
- ref() 在獲取變量的過程中需要加上.value 注意:
setup
返回的 ref 在模板中會自動解開,不需要寫.value
- ref的實現 ref的底層是reactive ref的對象具有對應的getter和setter。getter總是經過cover 轉化后的響應式對象raw ,觸發Vue的依賴收集。 ref的對象賦值會調用setter 調用會通知deps,通知依賴這一狀態的對象更新,並重新更新raw ,raw被保存為新的響應式包裝對象。
- 注意如果將一個新的 ref 分配給現有的 ref, 將替換舊的 ref
- 注意當嵌套在 reactive
Object
中時,ref 才會解套。從Array
或者Map
等原生集合類中訪問 ref 時,不會自動解套:
const arr = reactive([ref(0)]) // 這里需要 .value console.log(arr[0].value) const map = reactive(new Map([['foo', ref(0)]])) // 這里需要 .value console.log(map.get('foo').value)
- 類型定義
1 interface Ref<T> { 2 value: T 3 } 4 5 function ref<T>(value: T): Ref<T>
const foo = ref<string | number>('foo') // foo 的類型: Ref<string | number> foo.value = 123 // 能夠通過!