六、单文件组件(SFC)
1、 <script setup>
script-setup语法糖如下代码块:
<script setup>
console.log('hello script setup')
</script>
以上代码会被编译成组件setup()函数的内容。与普通的<script>只在组件被首次引入的时候执行一次不同,<script setup>中的代码会在每次组件实例被创建的时候执行。
- 顶层的绑定会被暴露给模板
任何在
<script setup>中声明的顶层的绑定(包括变量、函数声明、以及import引入的内容)都能在模板中直接使用,<script setup>等效于setup() <script setup>中可以使用响应式状态、普通组件、动态组件、递归组件、命名空间组件<script setup>内部API的使用:defineProps、defineEmits、defineExpose、useSlots、useAttrsdefineProps:用来声明props
<script setup> const props = defineProps({ foo: String }) </script>defineEmits:用来声明emits
<script setup> const emit = defineEmits(['change', 'delete']) </script>defineExpose使用defineExpose可以将<script setup>组件中的属性暴露出去
父组件通过模板ref的方式获取到当前子组件的实例// 子组件 `ChildComponent.vue` <script setup> import { ref, defineExpose } from 'vue' const a = ref([{ b:1, c:{ d:2 } }]) defineExpose({ a }) </script>// 父组件 <template> <ChildComponent ref="childComponentRef" /> </template> <script setup> import { ref, onMounted } from 'vue' import ChildComponent from './ChildComponent.vue' const childComponentRef = ref() onMounted(() => { const valueA = childComponentRef.value.a; console.log(valueA) console.log(valueA[0].b) console.log(JSON.stringify(valueA)) }) </script>useSlots和useAttrs
<script setup> import { useSlots, useAttrs } from 'vue' const slots = useSlots() const attrs = useAttrs() </script>
2、<style module>
与<style scoped>效果相同,対生成的类做hash计算以避免冲突,作用于当前组件内部
<template>
<p :class="$style.red">
This should be red
</p>
</template>
<style module>
.red {
color: red;
}
</style>
以上一个叫做$style的计算属性会被自动注入组件中,它的键是类名,我们还可以自定义注入名称
<template>
<p :class="classes.red">red</p>
</template>
<style module="classes">
.red {
color: red;
}
</style>
以上我们给module一个值classes,实际上classes.red等价于$style.red
七、全局API
在 Vue 3 中,全局和内部 API 都经过了重构,并考虑到了 tree-shaking 的支持,将全局 API 进行分块。因此,对于 ES 模块构建版本来说,全局 API 现在通过具名导出进行访问。Vue3源码引入tree shaking特性,
Vue 2.x 中的这些全局 API 受此更改的影响:
Vue.nextTickVue.observableVue.versionVue.compileVue.setVue.delete
八、异步组件
- 新的
defineAsyncComponent助手方法,用于显式地定义异步组件 component选项被重命名为loader- Loader 函数本身不再接收
resolve和reject参数,且必须返回一个 Promise
import { defineAsyncComponent } from 'vue'
const asyncModalWithOptions = defineAsyncComponent({
loader: () => import('./Modal.vue'),
delay: 200,
timeout: 3000,
errorComponent: ErrorComponent,
loadingComponent: LoadingComponent
})