淺析setup sugar:使用與不使用 script setup 的繁雜性對比、具體如何使用 script setup、setup存在的限制(配置項缺失的處理)


一、使用與不使用 script setup 的對比

1、不使用 script setup 的繁雜性

  我們之前的組件可能是這樣的:

<template>
  <div>
    <Card>{{msg}}</Card>
  </div>
</template>
<script lang="ts"> import { ref, defineComponent } from "vue"; import Card from "./components/Card.vue"; export default defineComponent({ components: { Card, }, setup() { const msg = ref("setup script"); return { msg }; } }); </script>

  這里做了兩件事,一個是導入並注冊組件,一個是導出一個字符串給template使用。

  如果模板上要使用的這些變量,必須要在 setup 返回的對象中定義。暴露變量必須 return 出來,如果我們內容很多的話,那么這個 setup 就會返回很多值,動輒十幾二十行,也是挺繁瑣的。有沒有更簡單的辦法,於是 script setup 語法出現。使用這個語法只需要在 script 標簽上加上 setup 屬性。

2、script setup 使用:啟用setup script之后是這樣的

  vue3.2 將這個之前的實驗功能變為正式功能,在單文件組件中引入了一種新的腳本類型:< script setup >

<script lang="ts" setup> import { ref } from "vue"; import Card from "./components/Card.vue"; const msg = ref("setup script"); </script>

  這里省去了組件的注冊步驟,也沒有顯式的導出變量的動作。你只需要在script上配置setup即可。

<script setup> import { ref } from 'vue'
  // 像在平常的setup中code,但是不需要返回任何變量
  const count = ref(0)//在此處定義的count可以直接在模板html中引用
  const inc = () => {//函數也可以直接引用,而不用返回
    count.value++ } </script>
<template>
  <Foo :count="count" @click="inc" />
</template>

  當 <script> 標簽具有 setup 屬性時,組件在編譯的過程中代碼運行的上下是 setup() 函數中。所有ES模塊導出都被認為是暴露給上下文的值,並包含在 setup() 返回對象中。

  其實 script setup 就相當於在編譯運行是把代碼放到了 setup 函數中運行,然后把導出的變量定義到上下文中,並包含在返回的對象中。

二、如何使用 script setup 語法

1、導出變量和方法:在setup script里面定義的所有變量都會自動導出,非常方便。

2、使用組件:所有的組件導入即可自動注冊。

  需要注意一點的是:如何定義組件名 => name?

  在 script setup 中,引入的組件可以直接使用,無需再通過components進行注冊,並且無法指定當前組件的名字,它會自動以文件名為主

  如果需要定義類似 name 的屬性,可以再加個平級的 script 標簽,在里面實現即可。

3、使用 props - defineProps:使用 props 需要用到defineProps來定義,具體用法跟之前的 props 寫法類似。

  通過 defineProps 指定當前 props 類型的同時,獲得上下文的props對象

  在 script中 需要 props[key] 引用,而 template 中可直接調用 key。

<script lang="ts" setup> import { defineProps } from "vue"; const props = defineProps(['title', 'content']); </script>

// 給props定義類型:
const props = defineProps({ title: String, content: { type: Stirng, required: true } }); // 使用TS的注解的方式:
defineProps<{ title?: string content: string }>();

4、使用 emits - defineEmit:使用defineEmit定義當前組件含有的事件,並通過返回的上下文去執行 emit

  使用 defineEmit 對組件里面使用到的事件進行驗證和定義,具體用法跟之前一樣。

const emit = defineEmit(['onHeaderClick']) emit('onHeaderClick', 'params') // 還可以對事件進行驗證
const emit = defineEmit({ onHeaderClick: ({title}) => { if(!title) { console.warn('Invalid title') return false } return true } })

5、使用 context - useContext:使用 useContext 獲取上下文。

  可以通過useContext從上下文中獲取 slots 和 attrs。不過提案在正式通過后,廢除了這個語法,被拆分成了useAttrsuseSlots

import { useContext } from 'vue'
const { slots, attrs } = useContext() // 獲取到的slots attrs跟之前的setup里面的是一樣的。

6、使用Slots和Attrs:需要useSlots, useAttrs

<script setup> import { useSlots, useAttrs } from 'vue'
const slots = useSlots() const attrs = useAttrs() </script>

7、指令:指令跟組件一樣,導入自定注冊。

<script setup> import {color as superColor} from './v-color'
</script>

<template>
  <div v-super-color />
</template>
// 導入的 color 重命名為 superColor,並自動映射為指令v-super-color

8、defineExpose API

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

  如果需要對外暴露 setup 中的數據和方法,需要使用 defineExpose API。示例:

<script setup> import { defineExpose } from 'vue'
const a = 1
const b = 2 defineExpose({ a }) // 將 a 暴露出去
</script>

三、setup 目前存在的限制

1、配置項的缺失:修改選項配置需要單開一個 script

  有時候我們需要更改組件選項,在 setup 中我們目前是無法做到的。我們需要在上方再引入一個 script,在上方寫入對應的 export 即可。

<script> export default { name: 'YourName', inheritAttrs: false, customOptions: {}, } </script>
<script setup>
  // your code
</script>

  注意:Vue 3 SFC 一般會自動從組件的文件名推斷出組件的 name。在大多數情況下,不需要明確的 name 聲明。唯一需要的情況是當你需要 <keep-alive> 包含或排除或直接檢查組件的選項時,你需要這個名字。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM