关于此分类
关于初识 vue3分类主要是记录一些通过 vue3 进行的实践与学习记录。
此文主要记录关于 vue3 script setup 的尝试。
本文会随着作者日常使用进行补充及内容修正
本文参考于:
默认自动暴露
<script setup>
是在单文件组件 (SFC) 中使用组合式 API的编译时语法糖。相比于普通的<script>
语法,它具有更多优势:
- 更少的样板内容,更简洁的代码。
- 能够使用纯 Typescript 声明 props 和抛出事件。
- 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
- 更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)。
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <div>当前msg的值:{{ msg }}</div> <div>当前msg的值(ref的值会被自动解包):{{ msgRef }}</div> </template>
<script setup lang="ts"> import { ref } from 'vue'
const msg = '这是一条msg' const msgRef = ref('msg') </script>
|
同样的导入组件也可以直接使用
1 2 3 4 5 6 7
| <template> <MyComponent /> </template>
<script setup> import MyComponent from './MyComponent.vue' </script>
|
动态组件
1 2 3 4 5 6 7 8 9
| <script setup> import Foo from './Foo.vue' import Bar from './Bar.vue' </script>
<template> <component :is="Foo" /> <component :is="someCondition ? Foo : Bar" /> </template>
|
自定义指令
但这里有一个需要注意的限制:必须以 vNameOfDirective
的形式来命名本地自定义指令,以使得它们可以直接在模板中使用。
1 2 3 4 5 6 7 8 9
| const vMyDirective = { beforeMount: (el: HTMLElement) => { console.log(el) }, mounted(el, value: Ref<number>) { console.log(value.value) } }
|
1
| <div v-my-directive="123">123</div>
|
defineProps、defineEmits、defineExpose
defineProps
和defineEmits
分别用于定义当前组件需要接收的参数和需要触发的 emit。
1 2 3 4 5
| const props = defineProps({ foo: String })
const emit = defineEmits(['change', 'delete'])
|
在 JavaScript 中上述定义即可,但在 typescript 中可以为其增加类型。
1 2 3 4 5 6 7 8 9
| const props = defineProps<{ foo: string bar?: number }>()
const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', value: string): void }>()
|
类型声明时的默认值
1 2 3 4 5 6 7 8 9
| const props = defineProps<{ foo: string bar?: number }>()
const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', value: string): void }>()
|
defineExpose 用于定义暴露出去的属性,此模式下默认是全暴露
1 2 3 4 5 6 7 8 9 10 11
| <script setup> import { ref } from 'vue'
const a = 1 const b = ref(2)
defineExpose({ a, b }) </script>
|
使用 <script setup>
的组件是默认关闭的,也即通过模板 ref 或者 $parent
链获取到的组件的公开实例,不会暴露任何在 <script setup>
中声明的绑定。
为了在 <script setup>
组件中明确要暴露出去的属性,使用 defineExpose
编译器宏
1 2 3 4 5 6 7 8 9 10
| <template> <div>test</div> </template>
<script setup> const a = 1 defineExpose({ a: 1 }) </script>
|
在父组件中使用
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <testAVue ref="testRef" /> </template>
<script setup lang="ts"> import testAVue from './test-a.vue' import { onMounted, ref } from 'vue' const testRef = ref(null) onMounted(() => { console.log(testRef.value) // Proxy {a: 1, __v_skip: true} }) </script>
|
与普通的<script>
使用
<script setup>
可以和普通的 <script>
一起使用。普通的 <script>
在有这些需要的情况下或许会被使用到:
- 无法在
<script setup>
声明的选项,例如 inheritAttrs
或通过插件启用的自定义的选项。 - 声明命名导出。
- 运行副作用或者创建只需要执行一次的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script> // 普通 <script>, 在模块范围下执行(只执行一次) runSideEffectOnce()
// 声明额外的选项 export default { inheritAttrs: false, customOptions: {} } </script>
<script setup> // 在 setup() 作用域中执行 (对每个实例皆如此) </script>
|