前言#
很早之前就看见尤大在说 <script setup> + TS + Volar = 真香
,但一直都没有去主动尝试过
前段时间恰好在网上看见了相关的项目,好奇心又被调动了,想着也没什么事,也便在这个暑假跟着视频去尝试做了一下,在使用<script setup>
语法糖和 ts 的时候,遇见了不少的问题,也在这个项目完成的过程中感受到了<script setup> +ts
的酸爽感,不得不说,确实很舒服哈哈哈🤣
话不多说了,直接来说开发项目时感受到的优点和自己在开发过程中遇见的一些问题
优点:#
更简洁的代码#
在 vue3.2 中,正式支持了<script setup>
语法糖,减少了大量的重复模板代码,引入的组件无需再注册后才能使用,只要引入后即可在 sfc 中使用,直接用代码来展示可能效果更好:
<template>
<Header />
</template>
<script setup>
//引入后可直接使用,无需注册
import Header from './header.vue'
</script>
不仅仅是组件的引入无需单独注册,包括函数与变量的声明也大大减少了代码量。使用<script setup>
无需再return
变量的值,对于函数,也无需再通过methods
选项来将其暴露,可直接在 setup 中写出函数,官方文档的代码实例如下:
<script setup>
// 变量
const msg = 'Hello!'
// 函数
function log() {
console.log(msg)
}
</script>
<template>
<button @click="log">{{ msg }}</button>
</template>
项目接口更加详细#
在该项目中,我所使用的是 mock.js 来写接口,通过import '@/mock/index'
让接口跑起来。在实际项目中,我需要调用接口时,需要先用 typescript 进行接口定义
, 虽然这会在一定程度上增加代码量,但对于中大型项目来说会更便于维护,在调用接口的时候也会有代码提示,这也是 ts 的优势了。
代码示例如下:
<script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'
// ts定义接口
interface Iswiper {
imgSrc: string
link: string
}
const list = ref<Iswiper[]>([])
axios({
url: '/swiperList',
method: 'get'
}).then((res) => {
console.log(res.data.result)
list.value = res.data.result
})
</script>
当我们将鼠标放上去时,便会出现提示:,这极大的方便了我们对接口的调用和后期的维护,对 ts 中的详细教程可以看这篇文章,可以更深入的了解interface
项目开发过程遇见的问题#
路由无法跳转#
这里犯的错误其实还是因为自己对<script setup>
掌握的不够好。当我想要点击搜索按钮进行跳转的时候,出现了报错 ———— 无论怎么点击都没有反应。本想在<script setup>
中直接使用this.$router.push
来进行跳转,但此刻 setup 还未执行,并没有 vue 实例,更别提this
了
翻看vue-router
官方文档,其实可以很清楚的看见官方对此的解释:
由于 setup 执行时机在 beforeCreate 之前,故在 setup 中是不能使用 data 和 methods (因为还没初始化好)。由于不能再 setup 函数中使用 data 和 methods, 所以 Vue 为了避免我们错误的使用,它直接将 setup 函数中的 this 修改成 undefined.
但由于本项目中的搜索图标
是标签,所以也就没必要使用useRouter
函数了,直接在<a>
标签上进行添加即可:
注意,由于我们是默认路由hash
, 故此处不可以直接添加为/search
,否则不会进行页面的跳转,应在前面再添加一个#
无法修改组件样式#
无法修改组件样式的情况在之前的项目中也遇见过,element plus
组件默认的样式无法修改,在vant3
中也遇见了同样的问题,我们自己写的样式被覆盖
,这里就直接进行样式穿透
即可,使用方法: ::deep 想要修改类名 { 修改样式 }
:
CSS module#
在我对登录界面进行样式修改的时候出现了问题,我无法将整体的页面背景修改成灰色,我通过对body
的样式修改,发现不起作用,如果直接删除vue单文件组件
的<style scoped>
中的scoped便可以样式生效了,但这样带来的副作用就是无法再对样式私有化,会污染全局
这时候便有两个解决方法:
单独再开一个 style#
通过再开一个<style>
的方式,单独对 body 进行一个渲染
使用全局作用域#
CSS Modules 允许使用:global(.className)
的语法,声明一个全局规则
关于 CSS Moudles 的详细情况可以参考阮一峰老师的这篇文章:CSS Modules 用法教程
defineExpose#
在使用vant3
组件的时候,由于他的文档实例并未像element plus
一样直接用的
结果我登录界面的输入框全都不见了.... 一想便知道,估计又是setup语法糖
没把握好的锅,连忙去翻看 vue 官方文档,不出意外的找到了问题的原因:事实上,获取到组件的公开实例的,需要用到definExpose
使用
<script setup>
的组件是默认关闭的 —— 即通过模板 ref 或者$parent
链获取到的组件的公开实例,不会暴露任何在<script setup>
中声明的绑定。通过
defineExpose
编译器宏来显式指定在<script setup>
组件中要暴露出去的 property
注意,definExpose
是需要手动导入的
总结#
<script setup> + TS + Volar
是真的太爽了,虽然我对<script setup>语法糖
的掌握还是不够,导致开发过程中出现了一系列的问题,不过还是能感受到语法糖的魅力的,最后浅浅的附上项目及源码地址