背景
vue3更新很久啦,在编码方式上有一个很大的改变,解放我们的双手的亮点不少!下面记录一下其中亮点之一语法糖🍬setup的用法。
语法
<script setup lang="ts">
</script>
优点
-
更少的样板内容,更简洁的代码。
无需注册组件
setup中引入组件<script setup lang="ts"> import Footer from '@/components/Footer.vue'; </script>模版中使用<template> <div class="home"> <Footer /> </div> </template>顶层的绑定会被暴露给模板
变量、方法、import 导入的内容无需return出去,直接暴露给模版,开箱即用模版<template> <div> {{ msg }}</div> <button @click="handClick">ok</button> <button @click="showInfo">ok</button> </template>setup<script setup lang="ts"> import { showInfo } from '@/utils/index.js'; const msg = 'hello world!'; const handClick = () => { console.log('btn'); }; </script>defineProps、defineEmits
无需引入,更好的支持typescript
defineEmits两种写法<script setup lang="ts"> const emit = defineEmits(['changeName']); </script><script setup lang="ts"> const emit = defineEmits<{ (e: 'changeName'): void; }>(); </script>defineProps<script setup lang="ts"> const props = defineProps({ name: String }); </script>
useAttrs、useSlots
- useAttrs:用来获取父组件传递过来的所有的参数属性信息
- useSlots: 获取插槽信息
- 模板中通过
$attrs、$slots来访问
setup
<script setup lang="ts">
import { useAttrs } from 'vue';
const { attrs = { name } } = useAttrs();
console.log(attrs);
console.log(name);
</script>
模版
<div> {{ $attrs.name }}</div>
支持顶层await
<script setup lang="ts">
const getInfos = () => {
setTimeout(() => {
console.log(1);
}, 1000);
};
const res = await getInfos();
</script>
注意,这里返回了一个promise,使用该组件的时候需要使用异步组件进行包裹 <Suspense>
自定义指令
通过固定指令的名称格式(vNameOfDirective)自动注册自定义指令
<script setup lang="ts">
// 自动注册一个指令 指令名称v-MyDirective,模版自动识别格式进行注册
const vMyDirective = {
beforeMount: () => {},
mounted(el: HTMLElement) {
console.log(el.focus());
}
};
</script>
<template>
<input v-MyDirective />
</template>
别处导入,重命名
<script setup>
import { myDirective as vMyDirective } from './MyDirective.js'
</script>
动态组件
<component :is="flat ? User : ''" :name="name" @changeName="changeName" />
其他
除了vue3默认帮我们帮引入的一些api(defineEmits、defineProps、defineExpose),有一些(比如ref、useAttrs、useSlots)还需要手动导入也是挺麻烦的,我们可以使用unplugin-auto-import把使用频率高的api进行自动导入,这样可以少些很多代码。
安装
npm i -D unplugin-auto-import
安装完成后会自动生成两个文件 auto-imports.d.ts、.eslintrc-auto-import.json
Vite配置
// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [
AutoImport({
// resolvers: [ElementPlusResolver()],
imports: [
'vue',
'pinia',
'vue-router',
],
eslintrc: {
enabled: true, // Default `false`
filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
},
dts: true //auto generation auto-imports.d.ts file
}),
]
})
ts配置
如果不配置,ts语法校验会失败
// tsconfig.json
{
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue","auto-imports.d.ts"],
}
使用
无需引入api,默认引入的可以在eslintrc-auto-import.json中查看,这样看代码少了太多了!
// User.vue
<script setup lang="ts">
const emit = defineEmits(['changeName']);
const attrs = useAttrs();
let { name } = attrs;
</script>
<template>
<div> {{ name }}</div>
<div> {{ $attrs.name }}</div>
<div @click="emit('changeName')"> changeName</div>
</template>