Vue基礎
Chapter 1
-
透過響應式定義的變數
reactive(obj)
和ref
一樣擁有深層響應式,所以當改變reactive(obj).obj
裡面的物件也會發生改變。但是reactive
只能包裝引用型別的變數,而ref
可以包裝任何型別但是在沒自動解包的情況下需要.value
來訪問ref
值 -
reactive
的變數如果解構的話,變數不具有響應式。(const { num } = reactive({ num: 0 })
),即使num
發生變化,也無效 -
將
ref
賦值在reactive
中,如果reactive
是物件型別,那麼ref
將自動解包,而無需.value
,並且reactive
改變改值時,對應的ref
也會自動更新。-
<script setup> import { ref, reactive } from 'vue'; const num = ref(0) const obj = reactive({ num }) </script> <template> <button v-on:click="obj.num += 1"> <!-- 對應的 ref: num 也會加一 --> {{num}} </button> </template>
-
-
將
ref
賦值給reactve
中,但是reactive
是陣列型別,那麼ref
將不會自動解包,需要透過.value
來獲取,並且修改reactive
的值也不會再將ref
值更新-
<script setup> import { ref, reactive } from 'vue'' const num = ref(0) const obj = reactive([num.value]) </script> <template> <button v-on:click="obj[0] += 1"> <!-- num 將不會更新 --> {{num}} <!-- obj.num 將不會更新 --> {{obj[0]}} </button> </template>
-
-
生命週期:vue會首先執行setup進行初始化,然後初始化API,之後進行初次渲染建立DOM和插入
onMounted
。渲染完成後再次期間如果狀態發生變化則進入onUpdate
狀態,更新後會進入updated
狀態。當要解除安裝元件時會執行beforeUnmounted
和unmounted
-
給DOM新增
ref
屬性時,vue初次執行時,獲取的的ref
會是null
,因為setup中的變數初始化是在DOM渲染插入之前的。如果想明確獲取指定DOM,需要使用onMounted(() => console.log(ref.value))
在掛載後在執行獲取該ref
- 也可以直接在DOM上來操作
ref
屬性的函式,<div :ref="(e) => ref.value = e.target"></div>
,當DOM移除時ref
也將變為null
- 使用
watch
來獲取到DOM,但是watch
會在DOM更新之前執行。使用需要使用watch(() => ref.value.focus(), { flush: 'post' })
來指定在DOM更新之後在執行,也可以使用watchPostEffect
- 也可以直接在DOM上來操作
-
在Vue3.5之前不同的是:
props
解構,3.5前解構的變數不具有響應式,而3.5後解構的變數都具有響應式 -
對於變數以及屬性都是相同命名時,可以像JS那樣省略書寫,
<div :item></div>
-
透過想要過一個按鈕來實現元件的切換可以使用Vue自帶元件
component
來實現,但是切換後,之前的元件都將被解除安裝,也就是再次切換回來之前的ref
狀態會被重新初始化,可以透過Vue內建元件<KeepAlive>
來實現儲存不銷燬-
<script setup> import { ref } from 'vue' import Hello from './Hello.vue' import World from './World.vue' const key = ref('Hello') const tabs = { Hello, World } </script> <template> <button @click="key = 'Hello'">Hello</button> <button @click="key = 'World'">World</button> <KeepAlive :max="2"> <component :is="tabs[key]" /> </KeepAlive> </template>
-
-
在Vue中也可以給自定義元件新增
v-model
屬性,在該元件下使用defineModel
來獲取-
// 父元件 <script setup> import Child from './Child.vue' const text = ref('') </script> <template> <Child v-model:main.capitalize="text" /> </template> // 子元件 Child.vue <script setup> import { defineModel } from 'vue' const [model, modifiers] = defineModel('main', { get(value) { if (modifiers.capitalize) { return value.charAt(0).toUpperCase() + value.slice(1) } return value; }, set(value) {} }) </script> <template> <input v-model="model" /> </template>
-
-
為Vue注入TS
-
ref
和reactive
可以使用ref<number>(0)
/const obj: { num: number } = reactive({ num: 0 })
-
defineProps(['num'])
defineProps<{ num?: number }>()
defineProps({ num: { type: Number, required: false } })
-
defineEmits(['change'])
defineEmits<{ (e: 'change', id: number): void }>()
defineEmits({ change: (id: number) => {} })
-
provide('name', 'su')
和inject<string>('name')
-
computed<number>(() => 1)
-
<script setup> import Child from './Child.vue' // InstanceType 為內部自帶無需引入 type ChildType = InstanceType<typeof Child> </script>
-
useTemplateRef<HTMLDivElement>('div')
-
-
v-if
和v-show
區別- 相同點:都是透過布林值來顯示DOM
- 不同點:
- 無論布林值是真或者假,
v-show
都會初始建立DOM,而v-if
如果初始值為false
,則初始不渲染該DOM v-show
不能運用在template
上和自定義元件上,而v-if
都可以v-show
適用於頻繁切換的DOM,初始化成本比較高。v-if
使用於不經常切換的DOM,初始化成本比較低v-show
的隱藏類似於CSS的display: none;
,而v-if
則是將整個DOM銷燬,所以頻繁切換時使用v-if
開銷會比較大
- 無論布林值是真或者假,