项目的状态与方法管理
项目背景
实习有个项目,是关于数据采集的后台管理,是一个新项目,使用的技术栈比较新,Vue 3 , Pinia ,element-plus 等等。
这里面的状态管理除了 Pinia 以外 ,就是通过function export的方式进行暴露,然后修改那个函数中的状态或调用方法。一开始我拿到这个 Vue 3 项目,我看到最外层和许多页面的文件夹内有个文件夹叫
我百思不得其解,hooks 不是 React 的东西吗?
然后我就开始解读这个项目,发现这个文件夹包含着许多状态与方法,控制着页面的显示(模态框的显示、数据、标题和表单验证规则等等)。只要是能封装的东西都能塞进去这里面,而且分模块存放,页面的状态和方法一目了然。虽然我还是不知道这个文件夹为什么要叫hooks。这跟React的hooks就只有一个状态管理功能是重叠的。这跟使用useContext管理单页面状态倒是有点像。
使用
就拿点击打开编辑模态框的举例。
<el-button size="small" type="primary" @click="handleAdd_Edit(false)">
触发点击事件会触发handleAdd_Edit这个方法,这个方法在这个vue文件中没有定义,在这个文件中搜索发现是在一个叫hooks的文件中引入的。这里还引入了dialogVisible这个状态。该页面会直接使用。
import { useInfo } from '@/hooks'
const {
info: systemInfo,
form, formRef,
dialogVisible,
isCreate,
dialogTitle,
handleCloseDialog,
handleAdd_Edit
} = useInfo<ISystemInfo>({
title: '系统信息',
})
useInfo函数中:
/** 新增编辑前处理 */
function handleAdd_Edit(type: boolean, readonly: boolean = false) {
if (type) {
isCreate.value = true;
form.value = deepClone(defaultInfo);
} else {
isCreate.value = false;
form.value = deepClone(info.value);
}
isReadonly.value = readonly;
handleOpenDialog();
}
handleAdd_Edit方法中会调用handleOpenDialog方法
function handleOpenDialog() {
dialogVisible.value = true;
}
在这个handleOpenDialog方法会修改dialogVisible这个值
useInfo函数的最后,会把需要用到的方法和状态都暴露出去
return {
formRef: formRef as Ref<FormInstance>,
info,
form,
dialogVisible,
isCreate,
isReadonly,
dialogTitle,
deviceActiveIsDiabled,
handleOpenDialog,
handleCloseDialog,
handleAdd_Edit,
getInfo,
handleSubmit,
handleDelete,
};
刚刚讲到,这个页面已经从useInfo函数中拿了dialogVisible这个状态,所以直接使用就行。
<el-dialog
width="52%"
v-model="dialogVisible"
:title="dialogTitle"
:before-close="handleCloseDialog"
>
就此我们一起走完了调用方法修改状态和引用状态的过程。
思考
那么问题来了,这是不是有点本末倒置,我直接用Pinia管理全局的状态,然后再再调用useCounterStore()中的方法不香吗?
Pinia 支持 Vue Devtools,Pinia stores 完全是响应式的,如果使用文件导出函数和状态的方法,函数中忘记修改状态那岂不是更麻烦?
其实文件导出函数和状态的方法的优点要从项目的结构出发,Pinia一般是存放在store文件夹中,而本方法是按照状态和函数的功能进行分类,存放在最外层和许多页面的文件夹内。这样可以直接在某页面的文件夹中看hooks文件中使用的状态和函数。可维护性高。(虽然我觉得Pinia模块化后也很方便)。