Vue: Day_1

这样那样如此如此發表於2024-11-12

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狀態。當要解除安裝元件時會執行beforeUnmountedunmounted

  • 給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
  • 在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

    • refreactive可以使用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-ifv-show區別

    • 相同點:都是透過布林值來顯示DOM
    • 不同點:
      1. 無論布林值是真或者假,v-show都會初始建立DOM,而v-if如果初始值為false,則初始不渲染該DOM
      2. v-show不能運用在template上和自定義元件上,而v-if都可以
      3. v-show適用於頻繁切換的DOM,初始化成本比較高。v-if使用於不經常切換的DOM,初始化成本比較低
      4. v-show的隱藏類似於CSS的display: none;,而v-if則是將整個DOM銷燬,所以頻繁切換時使用v-if開銷會比較大

相關文章