首先,关于组合式API现已有众多大佬发布了相关介绍及相关教程,但是个人在学习过程中还是花了比较多的时间去理解 “ 组合式API ” 这个概念。
因为目前搜索引擎排的比较前面的文章其实约等于是摘抄了一下官方文档,我并没有找到能够快速让新手形成一定认识并直接上手的文章,所以我总结一下自己目前的认识(用于记录方便以后查看,希望能对其他同学有所帮助),本人菜鸟若描述不当,请轻喷!!!!!!
组合式API 的目的是分离项目逻辑让程序可以做到专码做专事,按照官网的描述是将处理相同问题的代码放到相同的位置,让代码一块一块的,但这实际上让长时间使用选项式API编码的我有点摸不着头脑,一直思考如何把代码分成一块一块的,官网的图也让让我似懂非懂。所以我认为把逻辑分离到独立文件中可以快速的对组合式API有些初步的认识。
- 首先 组合式API 本质上是一个普通函数(一个独立的方法)
- “逻辑关注点分离” 这个词过于高级,其实就是抽取函数(封装方法),把处理某种东西的代码封装成一个函数(方法),像我们平时经常会把一些像时间格式化、字符串格式化、二次封装的请求,他们就是一种逻辑分离,只不过分离的比较细
- 组合式API的逻辑关注点分离目标是将页面的业务逻辑逐一分离,达到专码做专事,看事知码的程度
语音描述始终会有些难以看懂,我们不如直接上手来上那么个小案例。就来个最最最最最最最最最最最最常见的登录功能吧!(Vue3 + Typescript)理论上与js项目只有类型声明的差别
项目建议使用Vuecli创建,通常不会有其他莫名其妙的问题
写上template(2202年了我们就用 script setup 了)
<template>
<div class="home">
<input type="text" placeholder="账号"><br>
<input type="text" placeholder="密码"><br>
<input type="button" value="登录">
</div>
</template>
<script lang="ts" setup>
</script>
这里home这一层div可有可无,默认生成我就不改了
不多说,直接把整个登录逻辑分离出来
新建 CompositionApi.ts 文件在views目录下
/**CompositionApi.ts**/
import { onMounted , watch , reactive , toRefs } from "vue";
// 登录案例
function initLogin(){
// 定义变量,并使其响应式化
let state = reactive({
name:"",
password:""
})
const user = toRefs(state)
//初始化工作
onMounted(()=>{
console.log("页面onMounted");
})
// 监听改变(这种情况其实可以采用computed)
watch(user.name,(newVal,oldVal)=>{
console.log("nameChange:new="+newVal+"/old="+oldVal);
})
watch(user.password,(newVal,oldVal)=>{
console.log("passwordChange:new="+newVal+"/old="+oldVal);
})
// 定义事件方法
const userSumbit = ()=>{
console.log("提交:"+user.name.value+"/"+user.password.value);
}
return {
user,
userSumbit,
}
}
export {
initLogin,
}
观察分离出来的代码我们能发现以下几点:
- 登录功能的逻辑部分都在这里了,包括data的建立,生命周期钩子内内做的工作,及其他功能选项都被放到了 initLogin 函数内
- 选项式API的钩子及方法变成了主动引入式的API,且能多次使用
- 函数最终利用 return 将所需的 data 及 方法导出
其中主动引入式的生命周期钩子及选项方法是组合式API最为实用的内容,也是区别选项式API与普通函数抽离主要的点,能在抽离的函数中自由的注册这些内容让我们可以更加自由的将逻辑关注点分离。
使用分离的逻辑
<template>
<div class="home">
<input type="text" placeholder="账号" v-model="user.name.value"><br>
<input type="text" placeholder="密码" v-model="user.password.value"><br>
<input type="button" value="登录" @click="userSumbit">
</div>
</template>
<script lang="ts" setup>
import { initLogin } from './CompositionApi';
//调用分离逻辑API
const { user , userSumbit} = initLogin()
</script>
由于script setup 的特性我们利用解构方式导出的 对象/方法 可以直接在模板中引用,灰常的方便。
这样就算完成的逻辑关注点的分离,如果其他页面需要复用登录逻辑就不用把现有的登录逻辑复制到其他页面或者跳回登录页,只要书写新的dom样式就能在不同的页面直接引用已经实现的逻辑(单指功能一致样式不同的情况),同时维护登录逻辑也不用怕某个含登录功能的页面忘记修改了!
当然你如果想保持单文件的优势,可以把 function 定义在当前script标签中
<template>
<div class="home">
<input type="text" placeholder="账号" v-model="user.name.value"><br>
<input type="text" placeholder="密码" v-model="user.password.value"><br>
<input type="button" value="登录" @click="userSumbit">
</div>
</template>
<script lang="ts" setup>
import { inject , ref , reactive , toRefs ,watch,onMounted} from 'vue';
/**
* 登录案例
*/
const { user , userSumbit} = initLogin()
// 登录案例
function initLogin(){
// 定义变量,并使其响应式化
let state = reactive({
name:"",
password:""
})
const user = toRefs(state)
//初始化工作
onMounted(()=>{
console.log("页面onMounted");
})
// 监听改变(这种情况其实可以采用computed)
watch(user.name,(newVal,oldVal)=>{
console.log("nameChange:new="+newVal+"/old="+oldVal);
})
watch(user.password,(newVal,oldVal)=>{
console.log("passwordChange:new="+newVal+"/old="+oldVal);
})
// 定义事件方法
const userSumbit = ()=>{
console.log("提交:"+user.name.value+"/"+user.password.value);
}
return {
user,
userSumbit,
}
}
</script>
组合式API让代码的书写变的更加的自由,这方面就像又从框架式开发回到了原生开发时的自由,但自由的书写方式也让代码组织能力变得更加重要,一旦组织混乱,组合式API的优势也就没有了。
好了,希望大家阅读完这篇文章能获得一点点灵感,学习新东西一时间不能理解和转换思维是很正常的,可以尝试暂时换一个学习方向(我开始学Vue时是卡住了,思维无法从原生转过来,后面去学习了一点点小程序就打通了我对MVVM框架的思维)
任重道远