Vue 3--Composition API 和 script setup
说一下 Composition API
和 Options API 的区别?
Composition API 也叫组合式 API,它主要就是为了解决 Vue2 中 Options API 的问题。
一是在 Vue2 中只能固定用 data、computed、methods 等选项组织代码,在组件越来越复杂的时候,一个功能相关的属性和方法就会在文件上中下到处都有,很分散,变越来越难维护
二是 Vue2 中虽然可以用 minxin 来做逻辑的提取复用,但是 minxin 里的属性和方法名会和组件内部的命名冲突,还有当引入多个 minxin 的时候,我们使用的属性或方法是来于哪个 minxin 也不清楚
而 Composition API 刚才就解决了这两个问题,可以让我们自由的组织代码,同一功能相关的全部放在一起,代码有更好的可读性更便于维护,单独提取出来也不会造成命名冲突,所以也有更好的可扩展性
Option的弊端
Option的缺陷–反复横跳
相信大部分同学都维护过超过200行的.vue组件,新增或者修改一个需求,就需要分别在data,methods,computed里修改 ,滚动条反复上下移动,我称之为『反复横跳』 比如我们简单的加个拍脑门的需求 加个累加器 ,这种写代码上下反复横条的感觉, 相信大家都懂的
Option的缺陷:mixin和this
反复横跳的本质,在于功能的分块组织,以及代码量太大了,如果我们能把代码控制在一屏,自然就解决了,vue2里的解决方案,是使用mixin来混合, 我们抽离一个counter.js
1 |
|
在App.vue中
1 |
|
这样确实拆分了代码,但是有一个贼严重的问题,就是不打开counter.js,App.vue里的this上,count,add这些属性,是完全不知道从哪来的,你不知道是mixin,还是全局install,还是Vue.prototype.count设置的,数据来源完全模糊,调试爽死你,这也是option的一个大问题,this是个黑盒,template里写的count和double,完全不知道从哪来的
mixin命名冲突
如果有两个mixin,就更有意思了,比如我们又有一个需求,实时显示鼠标的坐标位置x,并且有一个乘以2的计算属性凑巧也叫double,再整一个mixin
1 |
|
这是是一个独立维护的mixin,可能在N个地方用到,他根本不知道会不会有人和他冲突,然后用一下
1 |
|
两个mixin里都有double这个数,尴尬,看效果 ,lsp的count被覆盖了 很尴尬,而且在App.vue这里,你完全不知道这个double到底是哪个,调试很痛苦
Composition API 和 <script setup>
上手
Composition API 拆分代码
之前的累加器和清单,虽然功能都很简单,但也属于两个功能模块。如果在一个页面里有这两个功能,那就需要在 data 和 methods 里分别进行配置。但这样的话,数据和方法相关的代码会写在一起,在组件代码行数多了以后就不好维护。所以,我们需要使用 Composition API 的逻辑来拆分代码,把一个功能相关的数据和方法都维护在一起。
但是,所有功能代码都写在一起的话,也会带来一些问题:随着功能越来越复杂,script 内部的代码也会越来越多。因此,我们可以进一步对代码进行拆分,把功能独立的模块封装成一个独立的函数,真正做到按需拆分。
在下面,我们新建了一个函数 useTodos:
1 |
|
这个函数就是把那些和清单相关的所有数据和方法,都放在函数内部定义并且返回,这样这个函数就可以放在任意的地方来维护。
而我们的组件入口,也就是<script setup>
中的代码,就可以变得非常简单和清爽了。在下面的代码中,我们只需要调用 useTodos,并且获取所需要的变量即可,具体的实现逻辑可以去 useTodos 内部维护,代码可维护性大大增强。
使用
1 |
|
我们在使用 Composition API 拆分功能时,也就是执行 useTodos 的时候,ref、computed 等功能都是从 Vue 中单独引入,而不是依赖 this 上下文。其实你可以把组件内部的任何一段代码,从组件文件里抽离出一个独立的文件进行维护。
获取鼠标位置函数封装
现在,我们引入追踪鼠标位置的需求进行讲解,比如我们项目中可能有很多地方需要显示鼠标的坐标位置,那我们就可以在项目的 src/utils 文件夹下面新建一个 mouse.js。我们先从 Vue 中引入所需要的 ref 函数,然后暴露一个函数,函数内部和上面封装的 useTodos 类似,不过这次独立成了文件,放在 utils 文件下独立维护,提供给项目的所有组件使用。
想获取鼠标的位置,我们就需要监听 mousemove 事件。这需要在组件加载完毕后执行,在 Composition API 中,我们可以直接引入 onMounted 和 onUnmounted 来实现生命周期的功能。
看下面的代码,组件加载的时候,会触发 onMounted 生命周期,我们执行监听 mousemove 事件,从而去更新鼠标位置的 x 和 y 的值;组件卸载的时候,会触发 onUnmounted 生命周期,解除 mousemove 事件。
1 |
|
完成了上面的鼠标事件封装这一步之后,我们在组件的入口就可以和普通函数一样使用 useMouse 函数。在下面的代码中,上面的代码返回的 x 和 y 的值可以在模板任意地方使用,也会随着鼠标的移动而改变数值。
1 |
|
简单来看,因为 ref 和 computed 等功能都可以从 Vue 中全局引入,所以我们就可以把组件进行任意颗粒度的拆分和组合,这样就大大提高了代码的可维护性和复用性。
<script setup>
好用的功能
如果没有 <script setup>
,那么我们需要写出下面这样的代码来实现累加器。
1 |
|
在上面的代码中,我们要在<script>
中导出一个对象。我们在 setup 配置函数中写代码时,和 Options 的写法比,也多了两层嵌套。并且,我们还要在 setup 函数中,返回所有需要在模板中使用的变量和方法。上面的代码中,setup 函数就返回了 count 和 add。
使用
<script setup>
可以让代码变得更加精简,这也是现在开发 Vue 3 项目必备的写法。除了我们上面介绍的功能,<script setup>
还有其它一些很好用的功能,比如能够使用顶层的 await 去请求后端的数据等等,我们会在后面的项目中看到这种使用方法。
style 样式的特性
比如,在 style 标签上,当我们加上 scoped 这个属性的时候,我们定义的 CSS 就只会应用到当前组件的元素上,这样就很好地避免了一些样式冲突的问题。
如果在 scoped 内部,你还想写全局的样式,那么你可以用:global 来标记,这样能确保你可以很灵活地组合你的样式代码(后面项目中用到的话,我还会结合实战进行讲解)。而且我们甚至可以通过 v-bind 函数,直接在 CSS 中使用 JavaScript 中的变量。
在下面这段代码中, 我在 script 里定义了一个响应式的 color 变量,并且在累加的时候,将变量随机修改为红或者蓝。在 style 内部,我们使用 v-bind 函数绑定 color 的值,就可以动态地通过 JavaScript 的变量实现 CSS 的样式修改,点击累加器的时候文本颜色会随机切换为红或者蓝。
参考文章
新的代码组织方式:Composition API + script setup 到底好在哪里?
那个忙了一夜的Vue3动画很好,就是太短了
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!