尤大都说Vue3 + script setup + TS + Volar真香,你说香不香?(上)

简介: 相信你已经开始使用或者迫不及待地想尝试Vue3.2了,其实我群里的小伙伴早已经开始使用,而且踩了很多坑了,今天给大家分享一下他的实践投稿文章,希望大家多多支持!

正文如下


目前setup sugar已经进行了定稿,而vue3 + setup sugar + TS的写法看起来很香,所以我大胆尝试了下,期间发现一些小问题,分享下我的经验,如有问题,欢迎斧正。


前期准备


  1. 使用vue-cli创建一个 vue3 + TS 的项目


  1. vscode禁用 Vetur,下载Volar


什么是 setup sugar


在单文件组件(SFC)中引入一个新的 <script> 类型 setup。它向模板公开了所有的顶层绑定。


未使用setup sugar


<template>
  <Foo :count="count" @click="inc" />
</template>
<script>
import Foo from './Foo.vue'
import { ref } from 'vue'
export default {
  setup() {
    const count = ref(1)
    const inc = () => { count.value++ }
    return {
      Foo,
      count,
      inc
    }
  }
}
</script>


使用了setup sugar


<template>
  <Foo :count="count" @click="inc" />
</template>
<script setup>
// 导入的组件也可直接可用于模板(指令同理,同样会被自动注册)
import Foo from './Foo.vue'
import { ref } from 'vue'
// 书写组合式 api 就像在正常的 setup 中一般,但是不需要进行手动地进行 return
const count = ref(0)
const inc = () => { count.value++ }
</script>


你可以在 github.com/vuejs/rfcs/…[4] 以及github.com/vuejs/rfcs/…[5] 看到有关 setup sugarref sugar有关更多的讨论。个人不喜欢ref sugar,个人认为.value的写法比较好理解,结合Volar的帮助提示,已经没有多少的心智负担。


vue3 组合式写法是否会产生更多问题


目前网络上很多人反应使用组合式 api 反而显得代码更加乱了。那么从vue2options apivue3composition api写法,究竟会获得什么好处呢?


  1. 逻辑耦合度更高:在options api中如何一个功能我们需要用到 data+method+watch...等更多 api,一段代码无法合并在一起,我们在阅读一段逻辑需要进行反复上下移动进行观看。而composition api就解决了这个问题。


  1. 功能抽离:得益于函数式编程,一个功能逻辑我们可以封装到一个 hook 中,我们直接导入hook,运行方法,即可。


缺点:从options api切换到composition api最大的问题无异于最大的问题就是没有强制的代码分区,如果书写的人没有很好的代码习惯,那么后续的人将会看的十分难受。目前我是这么解决的:


  • 自我代码分区并且尽量抽离方法(写好注释),分区如下:


  1. 相关引入


  1. 响应式数据、props、emit 定义


  1. 生命周期以及 watch 书写


  1. 方法定义


  1. 方法、属性暴露


  • 组件抽离:将页面拆成两个文件夹,一个为 views,一个为 components。views 和 components 文件夹下有各自的文件。views 文件夹中为页面入口,掌管数据,而 components 则为页面中一些组件抽离。如果是公共组件,再抽离到 components 文件夹下其他位置。


  • hook 抽离:尽可能将逻辑抽离,并不一定要进行复用。


setup 衍生出的新的 api


define 编译器宏(compiler macros )


define开头的 api 都为编译器宏(compiler macros )api,只能在 <script setup> 中使用。它们不需要被导入,并且在处理 <script setup> 时被编译掉。


注意:define类 api 必须直接在 setup 中外层进行使用,你无法将其放在方法中。


注意:define类 api 虽然不用导入,但是这一点和 TS 兼容不太好,如果不引入会提示 undefined,如果进行了引入,会有 warning 提示。


注意:define类 api虽然目前都可以使用 TS 类型声明,但是你无法导入一个 interface 或者 type 进行类型声明(直接在文件中声明是可以的),因为这样会报错。猜测这一点是和 define编译器宏有关,可能后期会被修复。


  1. defineProps:这个 api 很好理解,就是定义 props 相关信息。


   基础用法:


defineProps({
  name: {
    type: String,
    required: false,
    default: 'Petter',
  },
  userInfo: Object,
  tags: Array,
})

使用 TS 类型声明:


const props = defineProps<{ 
    foo: string 
    bar?: number
}>()


注:两个写法不可以一起进行使用,也就是一个 defineProps 不能既使用 TS 类型声明,也使用基础用法。


  1. withDefaults:这个方法并非属于编译器宏(compiler macros )api,但是这个 api 由defineProps衍生而出。在 TS 类型声明下无法进行设置默认值,这个 api 主要是为了解决这个场景。


withDefaults(defineProps<{
 size?: number
 labels?: string[]
}>(), {
 size: 3,
 labels: () => ['default label']
})


  1. defineEmits:这个 api 也很好理解,就是定义 emits 相关信息。不过使用和以前有点不一样。


     基础使用:


// 声明
const emits = defineEmits(['change', 'delete'])
// 使用
emits('change')


TS声明类型:


// 声明
const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', value: string): void }>()
// 使用
emits('change',1)


  1. defineExpose:在传统的 Vue 组件中,所有暴露在模板上的东西都隐含地暴露在组件实例上,也就是父组件可以通过ref 或者子链可以全量获取到子组件所有的属性、方法。大多数时候,这种全量暴露是过度的,而 vue3 setup 中必须进行手动暴露。


const a = 1
const b = ref(2)
defineExpose({ a, b, })


注意:目前发现defineExpose暴露出去的属性以及方法都是 unknown 类型,如果有修正类型的方法,欢迎评论区补充。


hook api


注:useContext API 被弃用,取而代之的是更加细分的 api。


  1. useAttrs:见名知意,这是用来获取 attrs 数据,但是这和 vue2 不同,里面包含了 class属性方法


  1. 在 vue2 中封装组件透传属性、方法你可能这么写:


<component v-bind='$attrs',v-on='$listeners'></component>


vue3 里删除了 $listeners,新写法:


<template>
 <component v-bind='attrs'></component>
</template>
<srcipt setup lang='ts'>
   const attrs = useAttrs();
<script>


  1. useCSSModule:CSS Modules 是一种 CSS 的模块化和组合系统。vue-loader 集成 CSS Modules,可以作为模拟 scoped CSS。允许在单个文件组件的setup中访问CSS模块。此 api 本人用的比较少,不过多做介绍。


  1. useSlots: 顾名思义,获取插槽数据。


  1. useCssVars: 此 api 暂时资料比较少。介绍v-bind in styles时提到过。


  1. useTransitionState: 此 api 暂时资料比较少。


  1. useSSRContext: 此 api 暂时资料比较少。


相关文章
|
13天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
116 64
|
13天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
|
1月前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
63 7
|
1月前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
52 1
|
1月前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
56 1
|
19天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
34 1
vue学习第四章
|
19天前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
28 1
vue学习第九章(v-model)
|
19天前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
33 1
vue学习第十章(组件开发)
|
25天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
25天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。