vue3中<script setup> 和 setup函数的区别
Posted 奥特曼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3中<script setup> 和 setup函数的区别相关的知识,希望对你有一定的参考价值。
目录
官网:<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。相比于普通的 <script> 语法,具有以下特点:
- 更少的样板内容,更简洁的代码。
- 能够使用纯 TypeScript 声明 props 和自定义事件。
- 更好的运行时性能 (其模板会被编译成同一作用域内的渲染函数,避免了渲染上下文代理对象)。
- 更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)。
简单来说<script setup> 就是 setup函数的一个语法糖,我们来看这个糖甜不甜~
一、基本语法
要启用该语法,需要在 <script>
代码块上添加 setup
属性即可
<script setup>
console.log('hello script setup')
</script>
里面的代码会被编译成组件 setup()
函数的内容。这意味着与普通的 <script>
只在组件被首次引入的时候执行一次不同,<script setup>
中的代码会在每次组件实例被创建的时候执行。
二、定义变量
使用setup函数
<script>
import ref from 'vue'
export default
name: 'Home',
setup ()
const num = ref(1)
return num
</script>
使用<script setup>
<script setup>
import ref from 'vue'
const num = ref(1)
</script>
so ~ 你是喜欢两行定义一个变量还是写成好多好多行,注意 当使用 <script setup>
的时候,任何在 <script setup>
声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用
三、使用外部文件方法
使用setup函数
<template>
<div class="home">
<h1>使用了setup函数</h1>
<h2> lowercase1(name)</h2>
</div>
</template>
<script>
import ref from 'vue'
import lowercase from '@/utils/lowercase.js'
export default
setup ()
const name = ref('MYNAME')
const lowercase1 = lowercase
return name, lowercase1
</script>
使用<script setup>
<template>
<div class="about">
<h1>使用了script setup</h1>
<h2>1.使用变量 lowercase(name)</h2>
</div>
</template>
<script setup>
import lowercase from '@/utils/lowercase.js'
import ref from 'vue'
const name = ref('MYNAME')
</script>
不需要在定义成一个方法啦 直接使用
四、注册组件
使用setup函数
<script>
import Hello from '@/components/HelloWorld'
export default
components:
Hello
</script>
使用<script setup>
<script setup>
import Hello from '@/components/HelloWorld'
</script>
不需要在component 在注册了
五、使用自定义指令
不使用<script setup>
<template>
<h1 v-onceClick>使用了setup函数</h1>
</template>
<script>
export default
directives:
onceClick:
mounted (el, binding, vnode)
console.log(el)
,
</script>
使用<script setup>
<template>
<h1 v-my-Directive>使用了script setup</h1>
</template>
<script setup>
const vMyDirective =
beforeMount: (el) =>
console.log(el)
// 在元素上做些操作
</script>
全局注册的自定义指令将正常工作。本地的自定义指令在 <script setup>
中不需要显式注册,但他们必须遵循 vNameOfDirective
这样的命名规范
六、父传子
<Com :num="100"></Com>
使用setup函数
<script>
export default
props:
num:
type: Number,
default: 1
,
setup (props)
console.log(props)
</script>
使用<script setup>
<script setup>
import defineProps from 'vue'
// eslint-disable-next-line no-unused-vars
const props = defineProps(
num:
type: Number,
default: 1
)
</script>
七、子传父
使用setup函数
<script>
export default
setup (props, context)
const sendNum = () =>
context.emit('sendNum', 1200)
return sendNum
</script>
使用<script setup>
<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 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。
八、defineExpose
使用 <script setup>
的组件是默认关闭的——即通过模板引用或者 $parent
链获取到的组件的公开实例,不会暴露任何在 <script setup>
中声明的绑定。
可以通过 defineExpose
编译器宏来显式指定在 <script setup>
组件中要暴露出去的属性,若不使用defineExpose 则获取不到当前引用的组件实例变量、方法
<script setup>
import ref,defineExpose from 'vue'
const a = 1
const b = ref(2)
defineExpose(
a,
b
)
</script>
下面通过父组件获取子组件实例时 加definedExpose和不加 definedExpose的区别
九、useSlots()
和 useAttrs()
useSlots 顾名思义 使用插槽的意思 那必然和插槽脱离不了关系
子组件 定义出一个插槽
<template>
<div>
<slot name="header"> </slot>
</div>
</template>
<script setup>
import onMounted, useSlots from 'vue'
onMounted(() =>
const slot = useSlots()
const slotHeader = slot.header()
console.log(slot, slotHeader)
)
</script>
父组件
<ComSlot>
<template v-slot:header>我是父组件使用了header</template>
</ComSlot>
来看打印出来的slot和slotHeader
useSlots是一个函数可以打印出组件中所有的插槽 而打印出来的插槽同样是函数 调用后可以看到插槽的基础信息
useAttrs
父组件
<ComSlot class="box">
<template v-slot:header><p>我是父组件使用了header</p></template>
</ComSlot>
子组件
<script setup>
import useAttrs from 'vue'
onMounted(() =>
const artts = useAttrs()
console.log(artts)
)
</script>
useAttrs 可以拿到父组件传递过来的所有属性
十、与普通的<script>
一起使用
<script setup>
可以和普通的 <script>
一起使用。普通的 <script>
在有这些需要的情况下或许会被使用到:
- 声明无法在
<script setup>
中声明的选项,例如inheritAttrs
或插件的自定义选项。 - 声明模块的具名导出 (named exports)。
- 运行只需要在模块作用域执行一次的副作用,或是创建单例对象。
<script>
// 普通 <script>, 在模块作用域下执行 (仅一次)
runSideEffectOnce()
// 声明额外的选项
export default
name:'header',
inheritAttrs: false,
customOptions:
</script>
<script setup>
// 在 setup() 作用域中执行 (对每个实例皆如此)
</script>
十一、顶层 await
<script setup>
中可以使用顶层 await
。结果代码会被编译成 async setup()
:
<script setup>
const post = await fetch('https://api.uomg.com/api/rand.qinghua').then((r) => r.json())
</script>
另外,await 的表达式会自动编译成在 await
之后保留当前组件实例上下文的格式。
注意:async setup()
必须与 Suspense 内置组件组合使用,Suspense
目前还是处于实验阶段的特性,会在将来的版本中稳定。
使用await demo
父组件
<template>
<div>
<Suspense>
<template v-slot:default> <ComAwait></ComAwait> </template>
<template v-slot:fallback> <div>加载中</div> </template>
</Suspense>
</div>
</template>
<script setup>
import defineAsyncComponent from 'vue' // 使用defineAsyncComponent异步引入组件
const ComAwait = defineAsyncComponent(() =>
import('@/components/ComAwait.vue')
)
</script>
子组件
<template>
<div>post.content</div>
</template>
<script setup>
const post = await fetch('https://api.uomg.com/api/rand.qinghua').then((r) => r.json())
</script>
十二、限制<script setup> 使用src属性
由于模块执行语义的差异,<script setup>
中的代码依赖单文件组件的上下文。当将其移动到外部的 .js
或者 .ts
文件中的时候,对于开发者和工具来说都会感到混乱。因此,<script setup>
不能和 src
attribute 一起使用。
以上是关于vue3中<script setup> 和 setup函数的区别的主要内容,如果未能解决你的问题,请参考以下文章
vue3中<script setup> 和 setup函数的区别
Vue3 项目中使用setup()函数报错,script setup cannot contain ES module exports