Vue3 的語法糖

組合式 API:setup()

Vue 3 的 Composition API 系列裏,推出了一個全新的 setup 函數,它是一個組件選項,在創建組件之前執行,一旦 props 被解析,並作爲組合式 API 的入口點。

setup 是一個接收propscontext的函數,最後 setup 需要return所有內容暴露給模板。

<script>
// 這是一個基於 TypeScript 的 Vue 組件
import { defineComponent } from 'vue'

export default defineComponent({
  setup(props, context) {
    // 在這裏聲明數據,或者編寫函數並在這裏執行它
    console.log(context)
    return {
      // 需要給 `<template />` 用的數據或函數,在這裏 `return` 出去
    }
  },
})
</script>

新的 setup 選項是在組件創建之前, props 被解析之後執行,是組合式 API 的入口。

  • 注意:在setup中不能使用this,因爲他找不到實例。但是在 vue2 語法和 vue3 語法混用的時候,vue2 語法中可以使用this訪問到setup裏暴露出的變量。

組件的生命週期

生命週期

可以看到 Vue 2 生命週期裏的 beforeCreatecreated ,在 Vue 3 裏已被 setup 替代。

setup 語法糖

<script setup>

</script>
  1. 它只是簡化了以往的組合API(compositionApi)的必須返回(return)的寫法,並且有更好的運行時性能。2. 在setup函數中所有 ES 模塊導出都被認爲是暴露給上下文的值,幷包含在 setup() 返回對象中。相對於之前的寫法,使用後,語法也變得更簡單。

ref

ref是最常用的一個響應式 API,它可以用來定義所有類型的數據,包括 Node 節點和組件。返回一個響應式對象,所有的值都通過.value屬性獲取。

<template>
  <div>{{num}}</div>
</template>
<script setup >
import { ref } from 'vue'

const num = ref(0)

</script>

reactive

返回一個對象的響應式代理。

<template>
  <div>{{state.searchInfo.name}}</div>
</template>
<script setup >
import { reactive } from 'vue'

const state = reactive({
  searchInfo: {
    name: 'Jack',
  },
})
</script>

組件自動註冊

setup中不再需要用過components進行註冊,直接引入即可食用。

<template>
 <Child />
</template>

<script setup>
import Child from '@/components/Child.vue'
</script>

defineProps

接收父組件傳過來的內容, 可以定義類型和默認值

const props = defineProps({
  modelValue: {
    type: Array,
    default: (() ={[]}),
  },
})

defineEmit

子組件向父組件傳遞內容事件

const text = ref(1)
const emit = defineEmits(['update:modelValue'])
emit('update:modelValue', text.value)

defineExpose

向外暴露組件內方法和屬性

傳統的寫法,我們可以在父組件中,通過 ref 實例的方式去訪問子組件的內容,但在 script setup 中,該方法就不能用了,setup 相當於是一個閉包,除了內部的 template 模板,誰都不能訪問內部的數據和方法。

<script setup> 的組件默認不會對外部暴露任何內部聲明的屬性。如果有部分屬性要暴露出去,可以使用 defineExpose

// 子組件
const table = ref(null)
defineExpose({
  table,
})
// 父組件
<template>
 <Child ref="child" />
</template>

<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'

let child = ref(null);

onMounted(() ={
 console.log(child.value.table); // Child Components
})
</script>

watch

watch(
  source, // 必傳,要偵聽的數據源
  callback // 必傳,偵聽到變化後要執行的回調函數
  // options // 可選,一些偵聽選項
)

watchEffect

<template>
  <div>{{num}}</div>
</template>
<script setup >
import { watchEffect, watch, ref } from 'vue'

const num = ref(1)

var id = setInterval(() ={
  num.value = num.value + 1
  if (num.value === 20) {
    clearInterval(id)
    id = null
  }
}, 1000)

watchEffect(() ={
  console.log(1111)
})

watch(() => num.value, () ={
  console.log(222, num.value)
})
</script>

watchwatchEffect區別:

1、watch 是惰性執行,也就是隻有監聽的值發生變化的時候纔會執行,但是 watchEffect 不同,每次代碼加載 watchEffect 都會執行(忽略 watch 第三個參數的配置,如果修改配置項也可以實現立即執行)

2、watch 需要傳遞監聽的對象,watchEffect 不需要

3、watch 只能監聽響應式數據:ref 定義的屬性和 reactive 定義的對象,如果直接監聽 reactive 定義對象中的屬性是不允許的,除非使用函數轉換一下

4、watchEffect 如果監聽 reactive 定義的對象是不起作用的,只能監聽對象中的屬性。

seSlots() 和 useAttrs()

獲取插槽數據和獲取 attrs 數據,裏面包含了 class、屬性、方法。

// 舊
<script setup>
  import { useContext } from 'vue'

  const { slots, attrs } = useContext()
</script>

// 新
<script setup>
  import { useAttrs, useSlots } from 'vue'

  const attrs = useAttrs()
  const slots = useSlots()
</script>

其他 Hook Api

  1. useCSSModule:CSS Modules 是一種 CSS 的模塊化和組合系統。vue-loader 集成 CSS Modules,可以作爲模擬 scoped CSS。允許在單個文件組件的 setup 中訪問 CSS 模塊。此 api 本人用的比較少,不過多做介紹。

  2. useCssVars: 此 api 暫時資料比較少。介紹 v-bind in styles 時提到過。

  3. useTransitionState: 此 api 暫時資料比較少。

  4. useSSRContext: 此 api 暫時資料比較少。

參考:Vue 官網、小調不喫辣(掘金)

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/b7Zqwqbe0FRlntvSSTFCBg