<script setup></script>
是在單一檔案元件 (SFC) 中使用組合式 API 的編譯時語法醣。當同時使用 SFC 與組合式 API 時該語法為預設推薦。相較於普通的 <script></script>
文法,它有更多優點:
更少的樣板內容,更簡潔的程式碼。
能夠使用純 TypeScript 宣告 props 和自訂事件。
更好的運行時效能 (其模板會被編譯成同一作用域內的渲染函數,避免了渲染上下文代理物件)。
更好的 IDE 類型推導效能 (減少了語言伺服器從程式碼中擷取類型的工作)。
以上是vue3官網對<script setup>的說明,其實<script setup> 就是 setup函數的一個語法糖。
<script> import { ref } from 'vue' export default { setup () { const num = ref(1); return { num } } } </script>
setup函數的寫法中定義的變數和函數都需要return出來,不然無法正常使用。
<script setup> import { ref } from 'vue' const num = ref(1) </script>
在<script setup>語法糖中的定義的變數和函數無需return。裡面的程式碼會被編譯成元件 setup()
函數的內容。這意味著與普通的 <script>
只在元件首次引入的時候執行一次不同,<script setup>
中的程式碼會在每次元件實例被創建的時候執行。
<template> <div> <h3> {{test(name)}}</h3> </div> </template> <script> import { ref } from 'vue' import { test } from '@/utils/test.js' export default { setup () { const name = ref('huang') const testName = test return { name, testName } } } </script>
setup函數使用外部檔案時需要在setup函數中定義成一個方法才能正常使用。
<template> <div> <h3>{{ test(name) }}</h3> </div> </template> <script setup> import { test } from '@/utils/test.js' import { ref } from 'vue' const name = ref('huang') </script>
在<script setup>語法糖中無需再定義成一個方法,可以直接使用 。
<script> import Hello from '@/components/HelloWorld' export default { components: { Hello } } </script>
<script setup> import Hello from '@/components/HelloWorld' </script>
不需要在component 中註冊了,可以直接使用。
<template> <h2 v-onceClick>使用了setup函数</h2> </template> <script> export default { directives: { onceClick: { mounted (el, binding, vnode) { console.log(el) } } }, } </script>
<template> <h2 v-my-Directive>使用了script setup</h2> </template> <script setup> const vMyDirective = { beforeMount: (el) => { console.log(el) } } </script>
全域註冊的自訂指令將正常運作。本地的自訂指令在 <script setup>
中不需要明確註冊,但他們必須遵循 vNameOfDirective
這樣的命名規範
<Com :num="100"></Com>
<script> export default { props: { num: { type: Number, default: 1 } }, setup (props) { console.log(props) } } </script>
<script setup> import { defineProps } from 'vue' const props = defineProps({ num: { type: Number, default: 1 } }) </script>
<script> export default { setup (props, context) { const sendNum = () => { context.emit('sendNum', 200) } return { sendNum } } } </script>
<script setup> import { defineProps, defineEmits } from 'vue' const emit = defineEmits(['submit']) const sendNum = () => { emit('submit', 1000) } </script>
defineProps 和defineEmits 都是只能在<script setup> 中使用的編譯器巨集。他們不需要被導入,因為它們將會隨著 <script setup> 處理過程被編譯。
defineProps 接收與 props 選項相同的值,defineEmits 接收與 emits 選項相同的值。
defineProps 和 defineEmits 在選項傳入後,會提供適當的類型推導。
傳入到 defineProps 和 defineEmits 的選項會從 setup 提升到模組的作用域。因此,在 setup 作用域中宣告的局部變數不能被傳入的選項引用。這樣做會造成編譯錯誤。但是,它可以引用導入的綁定,因為它們也在模組作用域內。
使用setup函數定義的元件的expose是預設開啟的,會將函數內定義的實例變數、方法全部暴露出去。而使用<script setup>的元件是預設關閉的——即透過範本引用或 $parent
鏈取得到的元件的公開實例,不會暴露任何在 <script setup>
中宣告的綁定。
可以透過 defineExpose
編譯器巨集來明確指定在 <script setup>
元件中要揭露出去的屬性,若不使用 defineExpose 則取得不到目前引用的元件實例變數、方法。
使用了defineExpose
<script setup> import { ref } from "vue"; const type = ref("<script setup>语法糖"); const msg = ref("使用了defineExpose"); defineExpose({ type, msg, }); </script>
# 不使用defineExpose
<script setup> import { ref } from "vue"; const type = ref("<script setup>语法糖"); const msg = ref("使用了defineExpose"); </script>
可以同時使用常規的<script> 標籤和<script setup> 標籤。在特定需求的情況下,常規的<script>可能會被使用
#聲明無法在<script setup> 中聲明的選項,例如inheritAttrs 或外掛程式的自訂選項。
宣告模組的具名匯出 (named exports)。
运行只需要在模块作用域执行一次的副作用,或是创建单例对象
<script> // 普通 <script>, 在模块作用域下执行 (仅一次) runSideEffectOnce() // 声明额外的选项 export default { name:'header', inheritAttrs: false, customOptions: {} } </script> <script setup> // 在 setup() 作用域中执行 (对每个实例皆如此) </script>
<script setup>
中可以使用顶层 await
。结果代码会被编译成 async setup()
<script setup> const post = await fetch('https://api.com').then((r) => r.json()) </script>
另外,await 的表达式会自动编译成在 await
之后保留当前组件实例上下文的格式。
由于模块执行语义的差异,<script setup></script>
中的代码依赖单文件组件的上下文。当将其移动到外部的 .js
或者 .ts
文件中的时候,对于开发者和工具来说都会感到混乱。因此,<script setup></script>
不能和 src
attribute 一起使用。
以上是vue3中<script setup>和setup函數的差別是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!