Vue3 的 script setup语法糖
defineProps
在 <script setup>
块中也是没有组件配置项 props 的,需要使用 defineEmits
编译器宏声明 props 相关信息
需求:变量类型,是否必传
<script lang="ts" setup>
// Prop
interface ListItem {
name: string
age: number
}
const props = defineProps<{
callType: number //必传
generation?: number // 可传可不穿
list: ListItem[]
}>()
</script>
需求:变量类型,是否必传,默认的props值
<script lang="ts" setup>
import {withDefaults} from "vue";
// Prop
interface Props {
modelValue: string;
defaultImgUrl: string; // 没有 ?: 的,就是必须传的
editState?: boolean;
fileSize?: number;
fileType?: string[];
}
const props = withDefaults(defineProps<Props>(), {
fileSize: 5,
editState: false,
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: () => ["png", "jpg", "jpeg"]
})
</script>
defineEmits
在<script setup>
块中也是没有组件配置项 emits 的,需要使用 defineEmits
编译器宏声明 emits 相关信息
<script lang="ts" setup>
// @Emit
const emit = defineEmits<{
(e: "update:modelValue", value: string | undefined): void
}>()
</script>
defineExpose
通过 defineExpose 编译器宏来显式指定在
// 父组件
<!-- 弹框 -->
<family-dialog ref="familyDialogRef"></family-dialog>
<script lang="ts" setup>
// @Components
import FamilyDialog from "./FamilyDialog.vue"
// @refs
const familyDialogRef = ref({} as any)
const openFamilyDialog = ():void => {
familyDialogRef.value.familyDialogOpen = true; // 可以通过 子组件实例使用 暴露处理的 属性或者方法
}
</script>
// 子组件
<script lang="ts" setup>
import {defineExpose} from "vue";
const familyDialogOpen = ref(false);// 弹窗是否显示
defineExpose({
familyDialogOpen
})
</script>
toRefs
将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref
<script lang="ts" setup>
import {reactive, toRefs} from "vue";
const model = reactive({
familyInfoDialogOpen: false,// 弹窗显示
formData: { // 表单数据
...
}
}
)
const {formData, familyInfoDialogOpen} = toRefs(model)
</script>
useAttrs
在模板中使用 $attrs
来访问 attrs 数据,与 Vue2 相比,Vue3 的 $attrs 还包含了 class
和 style
属性。
在 <script setup>
中使用 useAttrs 函数获取 attrs 数据。
// 父组件
<!--/**
* @author: liuk
* @date: 2023/1/6
* @describe: useAttrs hooks api学习
在模板中使用 $attrs 来访问 attrs 数据,与 Vue2 相比,Vue3 的 $attrs 还包含了 class 和 style 属性。
在 <script setup> 中使用 useAttrs 函数获取 attrs 数据。
*/-->
<template>
<div>
<h2>使用 useAttrs</h2>
<HelloWorld class="hello-word" title="我是标题" style="margin-top: 10px"/>
</div>
</template>
<script setup lang="ts">
import HelloWorld from './son.vue'
</script>
// 子组件
<template>
<!-- 在模板中使用 $attrs 访问属性 -->
<div>{{ $attrs.title }}</div>
<div>{{ $attrs.class }}</div>
<div>{{ $attrs.style }}</div>
</template>
<script setup lang="ts">
import { useAttrs } from 'vue'
const attrs = useAttrs()
// js中使用.
console.log(attrs)
console.log(attrs.class) // hello-word
console.log(attrs.title) // 我是标题
</script>
useCssModule
在 Vue3 中,也是支持 CSS Modules 的,在 <style>
上增加 module 属性,即<style module>
。
<style module>
代码块会被编译为 CSS Modules 并且将生成的 CSS 类作为 $style 对象的键暴露给组件,
可以直接在模板中使用 $style。而对于如 <style module="content">
具名 CSS Modules,编译后生成的 CSS 类作为 content 对象的键暴露给组件,即module 属性值什么,就暴露什么对象。
<!--/**
* @author: liuk
* @date: 2023/1/6
* @describe: useCssModule hooks api学习
在 Vue3 中,也是支持 CSS Modules 的,在 <style> 上增加 module 属性,即<style module> 。
<style module> 代码块会被编译为 CSS Modules 并且将生成的 CSS 类作为 $style 对象的键暴露给组件,可以直接在模板中使用 $style。而对于如 <style module="content"> 具名 CSS Modules,编译后生成的 CSS 类作为 content 对象的键暴露给组件,即module 属性值什么,就暴露什么对象。
*/-->
<template>
<div>
<h2>使用 useCssModule</h2>
<div class="success">普通style red</div>
<!-- 系统自带 -->
<div :class="$style.success">默认CssModule pink</div>
<!-- script中定义 -->
<div :class="style.success">默认CssModule pink</div>
<!-- 系统自带 -->
<div :class="content.success">具名CssModule blue</div>
<!-- script中定义 -->
<div :class="contentStyle.success">具名CssModule blue</div>
</div>
</template>
<script setup lang="ts">
import {useCssModule} from 'vue'
// 不传递参数,获取<style module>代码块编译后的css类对象
const style = useCssModule()
console.log(style.success) // 获取到的是success类名经过 hash 计算后的类名
// 传递参数content,获取<style module="content">代码块编译后的css类对象
const contentStyle = useCssModule('content')
console.log(contentStyle.success)
</script>
<!-- 普通style -->
<style>
.success {
color: red;
}
</style>
<!-- 无值的css module -->
<style module lang="scss">
.success {
color: pink;
}
</style>
<!-- 具名的css module -->
<style module="content" lang="scss">
.success {
color: blue;
}
</style>
inheritAttrs
inheritAttrs 表示是否禁用属性继承,默认值是 true
// 父组件
<!--/**
* @author: liuk
* @date: 2023/1/6
* @describe: inheritAttrs 属性学习
*/-->
<template>
<div>
<h2>设置 inheritAttrs</h2>
<son title="我是title" aaa="111"/>
</div>
</template>
<script lang="ts" setup>
import Son from "./son.vue"
</script>
// 子组件
<template>
<div>
<span :title="attrs.title">attrs - hover一下看title</span>
<br/>
<span :title="$attrs.title">$attrs - hover一下看title</span>
</div>
</template>
<script lang="ts">
export default {
name: 'HelloWorld',
inheritAttrs: true, // 默认inheritAttrs 为 true
}
</script>
<script setup lang="ts">
import {useAttrs} from 'vue'
const attrs = useAttrs();
// console.log(attrs, '==> attrs')
</script>
<!--可看出 $attrs值与inheritAttrs无关-->
<!--element渲染的结果,当inheritAttrs为true时,dom标签会出现传递的属性,而为false时,则不会 -->