如何充分利用Composition API对Vue3项目进行代码抽离(2)

navInfos,

addTabShow,

isShowSaveAlert,

closeSaveConfigAlert,

showSaveConfigAlert,

isShowImportAlert,

showImportConfigAlert,

closeImportConfigAlert,

showSearch,

toID

}

}

}

上述代码是我项目中侧边栏中所有的变量以及方法,虽说变量和方法都同时存在于setup函数中了,但是仍看起来杂乱无章,若是这个组件的业务需求越来越复杂,这个setup内的代码可能更乱了

于是,我便开始构思如何抽离我的代码。后来在掘金的沸点上说了一下我的思路,并且询问了一下其他掘友的建议

其实最后一位老哥的回答对我启发很大,因此我也借鉴了一下它的思路对我的项目代码进行了抽离

准备工作

=============================================================

首先我得思考一个问题:抽离代码时,是按照组件单独抽离?还是按照整体功能抽离?

最后我决定按照整体的功能去抽离代码,具体功能列表如下:

  • 搜索功能

  • 新增/修改标签功能

  • 新增/修改网址功能

  • 导入配置功能

  • 导出配置功能

  • 编辑功能

开始抽出代码

===============================================================

上述的每一个功能都会通过一个JS文件去存储该功能对应的变量以及方法。然后所有的JS文件都是放在src/use下的,如图

就拿 新增/修改标签功能 来举例子,用一个动图给大家看看该功能的全部效果

在这里插入图片描述

很明显,我是做了一个弹窗组件,当点击侧边栏中的 + 号后,弹窗显示;然后我输入了想要新增标签的名称,并且选择了合适的图标,最后点击了确认,于是一个标签就添加好了,弹窗也随之隐藏;

最后我又去编辑模式下点击修改标签,弹窗再次显示,与此同时把对应标签的名称与图标都渲染了出来;待我修改了名字后,点击了确认,于是标签的信息就被我改好了,弹窗又随之隐藏了。

所以总结以下涉及到的功能就有以下几个:

  1. 弹窗的展示

  2. 弹窗的隐藏

  3. 点击确认后新增或修改标签内容

按照传统的写法,实现上述三个功能是这个样子的(我修改并简化了代码,大家理解意思就行):

  • 侧边栏组件内容

<tab-alert :isShow=“isShow” @closeTabAlert=“close”/>

  • 标签弹框组件内容

看完了我上面举例的代码后可以发现,简简单单的一个功能的实现,却涉及到两个组件,而且还需要父子组件相互通信来控制一些状态,这样不就把功能打散了嘛,即不够聚合。所以按照功能来抽离这些功能代码时,我会为他们创建一个 tabAlert.js 文件,里面存储着关于这个功能所有的变量与方法。

tabAlert.js文件中的大致结构是这样的:

// 引入依赖API

import { ref } from ‘vue’

// 定义一些变量

const isShow = ref(false) // 存储标签弹框的展示状态

export default function tabAlertFunction() {

/* 定义一些方法 */

// 展示标签弹框

function show() {

isShow.value = true

}

// 关闭标签弹框

function close() {

isShow.value = false

}

// 点击确认按钮以后的操作

function confirm() {

/* 此处省略点击确认按钮后更新标签内容的业务代码 */

close()

}

return {

isShow,

show,

close,

confirm,

}

}

对于为何设计这样的结构,先从导出的方法来说,我把跟该功能相关的所有方法放在了一个函数中,最后通过return导出,是因为有时候这些方法会依赖于外部其它的变量,所以用函数包裹了一层,例如:

// example.js

export default function exampleFunction(num) {

function log1() {

console.log(num + 1)

}

function log2() {

console.log(num + 2)

}

return {

log1,

log2,

}

}

从这个文件中我们发现,log1log2方法都是依赖于变量num的,但我们并没有在该文件中定义变量num,那么可以在别的组件中引入该文件时,给最外层的exampleFunction方法传递一个参数num即可

<button @click=“log1”>打印加1

<button @click=“log2”>打印加2

然后再来说说为什么变量的定义在我们导出函数的外部。再继续看我上面举的我项目中标签页功能的例子吧,用于存储标签弹框展示状态的变量isShow是在某个组件中定义的,同时标签组件也需要获取这个变量来控制展示的状态,这之间用到了父子组件通信,那么我们不妨把这个变量写在一个公共的文件中,无论哪个组件需要用到的时候,只需要导入获取就好了,因为每次获取到的都是同一个变量

这样一来,岂不是连父子组件通信都省了嘛?

我们把刚刚封装好的tabAlert.js用到组件中去,看看是什么效果

  • 侧边栏组件内容
  • 标签弹框组件内容

这时候再翻上去看看最初的代码,有没有感觉代码抽离后,变得非常规整,而且组件中少了很多的代码量。

这样通过功能来将变量和代码聚集在一起的方法,我个人认为是比较好管理的,倘若之后有一天想在该功能上新增什么小需求,只要找到tabAlert.js这个文件,在里面写方法和变量即可

展示环节

=============================================================

我就是按照这样的方法,对我原本的代码进行了抽离,下面给大家看几组抽离前抽离后的代码对比

对比一


  • 抽离前
导入配置
说明:需要上传之前保存导出的xxx.json配置文件,文件中的信息会完全覆盖当前信息

上传配置文件

<input id=“import_config_input” type=“file” class=“select-file” ref=“inputFile” @change=“fileChange”>

<lp-button type=“primary” class=“import-config-btn” @_click=“importConfig”>确认上传

  • 抽离后
导入配置
说明:需要上传之前保存导出的xxx.json配置文件,文件中的信息会完全覆盖当前信息

上传配置文件

<input id=“import_config_input” type=“file” class=“select-file” ref=“inputFile” @change=“fileChange”>

<lp-button type=“primary” class=“import-config-btn” @_click=“importConfig”>确认上传

  • 抽离出的代码文件

// 导入配置功能

import { ref } from ‘vue’

const isShowImportAlert = ref(false), // 导入配置弹框是否展示

result = ref(‘none’), // 导入的结果

isUpload = ref(false), // 判断是否上传配置文件

isImport = ref(false), // 判断配置是否导入成功

isLoading = ref(false), // 判断按钮是否处于加载状态

inputFile = ref(null), // 获取文件元素

hasFile = ref(0) // 判断文件的传入情况。0:未传入 1: 格式错误 2:格式正确

export default function importConfigFunction($message) {

// 控制弹框的展示

function handleImportConfigAlert(value) {

isShowImportAlert.value = value

if(!value) hasFile.value = 0

}

// 上传的文件内容发生改变

function fileChange(e) {

let files = e.target.files

if(files.length === 0) {

$message({

type: ‘warning’,

content: ‘请先上传配置文件’

})

}

else {

let targetFile = files[0]

if(!/.json$/.test(targetFile.name)) {

hasFile.value = 1

$message({

type: ‘warning’,

content: ‘请确认文件格式是否正确’

})

} else {

hasFile.value = 2

$message({

type: ‘success’,

content: ‘文件格式正确’

})

}

}

}

// 导入配置

function importConfig() {

let reader = new FileReader()

let files = inputFile.value.files

if(hasFile.value == 0) {

$message({

type: ‘warning’,

content: ‘请先上传配置文件’

})

}

else if(hasFile.value == 1) {

$message({

type: ‘warning’,

content: ‘请上传正确格式的文件,例如xx.json’

})

}

else if(hasFile.value == 2) {

reader.readAsText(files[0])

reader.onload = function() {

let data = this.result

window.localStorage.navInfos = data

location.reload()

}

}

}

return {

isShowImportAlert,

result,

isUpload,

isImport,

isLoading,

inputFile,

hasFile,

handleImportConfigAlert,

fileChange,

importConfig,

}

}

对比二


  • 抽离前
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值