vue3 结合Composition API拆分代码(学习笔记)
Composition API(vue3) 和Options API(vue2)区别options API由于所有数据都挂载在 this 之上,因而 Options API 的写法对 TypeScript 的类型推导很不友好,并且这样也不好做 Tree-shaking 清理代码。增功能基本都得修改 data、method 等配置,并且代码上 300 行之后,会经常上下反复横跳,开发很痛苦。代码不好
Composition API(vue3) 和Options API(vue2)区别
options API
- 由于所有数据都挂载在 this 之上,因而 Options API 的写法对 TypeScript 的类型推导很不友好,并且这样也不好做 Tree-shaking 清理代码。
- 增功能基本都得修改 data、method 等配置,并且代码上 300 行之后,会经常上下反复横跳,开发很痛苦。
- 代码不好复用,Vue 2 的组件很难抽离通用逻辑,只能使用 mixin,还会带来命名冲突的问题。
Composition API
- 所有 API 都是 import 引入的,没用到功能,打包的时候会被清理掉 ,减小包的大小。
- 不再上下反复横跳,我们可以把一个功能模块的 methods、data 都放在一起书写,维护更轻松。
- 可以更好的组织代码结构、利用业务逻辑代码复用,更好的维护
- computed ref 声明周期靠单独引入,而不是依赖上下文(onMouted、onUnmounted)生命周期
- Composition API 对我们开发 Vue 项目起到了巨大的帮助。下面这个示例图很好地说明了问题:每一个功能模块的代码颜色一样,左边是 Options API,一个功能的代码零散的分布在 data,methods 等配置内,维护起来很麻烦,而右边的 Compositon API 就不一样了,每个功能模块都在一起维护。
script setup 是为了提高使用compostion API而存在的
Composition API 拆分代码
为什么要拆分代码? 如果在一个页面里有这两个功能,那就需要在 data 和 methods 里分别进行配置。但这样的话,数据和方法相关的代码会写在一起,在组件代码行数多了以后就不好维护。所以,我们需要使用 Composition API 的逻辑来拆分代码,把一个功能相关的数据和方法都维护在一起。
但是,所有功能代码都写在一起的话,也会带来一些问题:随着功能越来越复杂,script 内部的代码也会越来越多。因此,我们可以进一步对代码进行拆分,把功能独立的模块封装成一个独立的函数,真正做到按需拆分。
在下面我们在uitils中新建一个todoList.js
import { ref, computed } from "vue";
function useTodos() {
let title = ref("");
let todos = ref([{ title: "学习Vue3", done: false }]);
function addTodo() {
todos.value.push({
title: title.value,
done: false,
});
title.value = "";
}
function clear() {
//把done为true的过滤掉
todos.value = todos.value.filter((v) => !v.done);
}
let active = computed(() => {
return todos.value.filter((v) => !v.done).length;
});
let all = computed(() => todos.value.length);
let allDone = computed({
get: function () {
return active.value === 0;
},
set: function (value) {
todos.value.forEach((todo) => {
todo.done = value;
});
},
});
function delTodo(idx){
todos.value.splice(idx,1)
}
return { title, todos, addTodo, clear,delTodo, active, all, allDone };
}
export {
useTodos
}
这个函数就是把那些和清单相关的所有数据和方法,都放在函数内部定义并且返回,这样这个函数就可以放在任意的地方来维护。
而我们的组件入口,也就是 script setup 中的代码,就可以变得非常简单和清爽了。在下面的代码中,我们只需要调用 useTodos,并且获取所需要的变量即可,直接在模板中使用即可,具体的实现逻辑可以去 useTodos 内部维护,代码可维护性大大增强。
<script setup>
import {useTodos} from '../utils/todoList'
import {useAdd} from '../utils/tiredAdd'
let { title, todos:todoList, addTodo, clear,delTodo, active, all, allDone } = useTodos();
</script>
响应式style 样式的特性
在 style 标签上,当我们加上 scoped 这个属性的时候,我们定义的 CSS 就只会应用到当前组件的元素上,这样就很好地避免了一些样式冲突的问题。
<style scoped>
h1 {
color: red;
}
</style>>
这样,组件就会解析成下面代码的样子。标签和样式的属性上,新增了 data- 的前缀,确保只在当前组件生效。
<h1 data-v-3de47834="">1</h1>
<style scoped>
h1[data-v-3de47834] {
color: red;
}
</style>
style 标签的特殊属性,通过标记 scoped 可以让样式只在当前的组件内部生效,还可以通过 v-bind 函数来使用 JavaScript 中的变量去渲染样式,如果这个变量是响应式数据,就可以很方便地实现样式的切换。
<template>
<div>
<h1 @click="add">{{ count }}</h1>
</div>
</template>
<script setup>
import { ref } from "vue";
let count = ref(1)
let color = ref('red')
function add() {
count.value++
color.value = Math.random()>0.5? "blue":"red"
}
</script>
<style scoped>
h1 {
color:v-bind(color);
}
</style>>
更多推荐
所有评论(0)