调整文件结构
一开始把表单控件、查询控件、列表控件等都放在了一个页面里面,然后发现代码有点乱,也不便于更换,只是数据交互方面方便了一点。
于是分成了多个组件的形式如下:
index
这个是左侧的菜单导航,调用子路由加载对应的组件data-list
数据列表组件,加上查询控件、操作按钮、分页、表单等控件。
因为数据列表是核心,添加数据后要更新列表,查询后要更新列表、分页后也要更新列表,所以就把各个控件直接放在列表组件里面了。
<template>
<!--查询功能-->
<data-find/>
<!--操作按钮-->
<div style="background:#fff;">
<el-space wrap>
<el-button type="primary" @click="addNew"> 添 加 </el-button>
<el-button type="primary" @click="update"> 修 改 </el-button>
<el-button type="primary" @click="deleteData"> 删 除 </el-button>
<el-button type="primary" @click="loadList"> 更 新 </el-button>
</el-space>
</div>
<!--数据列表-->
<nf-grid-list
v-bind="meta"
:data-list="dataList"
/>
<!--分页功能-->
<data-page/>
<!--弹窗的表单-->
{{formState}}
<data-edit :moduleId="moduleId" >
</data-edit>
</template>
操作按钮也可以封装成控件,现在还没忙过了封装。
这样结构是不是很清晰了,而且便于位置调整。
也可以做成不同风格的组件,然后进行替换。
- data-edit
实现数据的添加、修改和查看的功能,主要放置表单控件,加载表单控件需要的meta,协调数据等功能。
<template>
<!--弹窗的表单-->
<el-dialog
:title="formState.editState + '客户信息'"
:modal="true"
v-model="formState.isOpen"
>
<nf-form
ref="formControl"
v-model="formModel"
v-model:partModel="partModel"
:meta="meta"
>
</nf-form>
<el-button type="primary" @click="addNew"> 确 定 </el-button>
</el-dialog>
</template>
用弹窗来实现表单,el-dialog 的用法还没研究透。
- data-find
实现查询功能,放置查询控件,加载查询控件需要的meta,提供查询条件。
<template>
<nf-find
ref="findControl"
v-model="query"
:meta="meta"
/>
</template>
放上查询控件。
data-page
实现分页功能,这个没有封装,直接使用 el-pagination 来实现。crud-manage.js
存放共享数据和状态管理。
import { provide, inject, reactive } from 'vue'
// 管理类
export default function crudManage () {
/**
* 表单的状态
*/
const formState = reactive({
isOpen: false,
editState: 'add' // add/update/show
})
const formStates = reactive({})
/**
* 数据源
*/
const dataSource = reactive([])
// 注入状态
const register = (id) => {
provide('dataSource', dataSource)
provide('formState', formState)
if (typeof formStates[id] === 'undefined') {
formStates[id] = {
id: id,
isOpen: false,
editState: 'add' // add/update/show
}
provide('formState_' + id, formStates[id])
}
}
/**
* 获取弹窗表单的状态
* @returns 返回弹窗表单的状态
*/
const getFormState = (id) => {
if (typeof id === 'undefined') {
if (typeof inject('formState') === 'undefined') {
return formState
} else {
return inject('formState')
}
} else {
if (typeof inject('formState_' + id) === 'undefined') {
return formState
} else {
return inject('formState_' + id)
}
}
}
/**
* 表单添加、修改数据,列表获取数据
* @returns 返回共用的数据源
*/
const getDataSource = () => {
if (typeof inject('dataSource') === 'undefined') {
return dataSource
} else {
return inject('dataSource')
}
}
/**
* 表单里面添加新数据
*/
const formAddNewData = (obj) => {
let arr = []
if (typeof inject('dataSource') === 'undefined') {
arr = dataSource
} else {
arr = inject('dataSource')
}
console.log('inject--', inject)
console.log('dataSource', arr)
arr.push(obj)
}
return {
formState, // 弹窗表单的状态
getFormState,
getDataSource,
formAddNewData,
register // 注入
}
}
可以用Vuex实现,只是感觉有点大材小用,另外也是尝试一下注入的用法。
然后就发现个问题,在子组件里面,直接取 inject('formState') 能取出来,但是放在函数里面就取不出来了,也不知道是哪里写的有问题。所以只好在外面先取出来存放在ds里面,然后再在函数里面push。不知道差哪了。
// 注入
const {
getFormState,
getDataSource
} = crudManage()
const ds = getDataSource() // 这里可以获取
// 添加新数据
const addNew = () => {
const newData = {
id: new Date().valueOf()
}
Object.assign(newData, formModel)
inject('formState') // 在这里取不到,
ds.unshift(newData)
}
- 为啥要分得这么细致呢?
因为我喜欢原子级的组件,这样统一组件的接口风格后,然后每个组件里的代码就可以变得很少,便于维护和更换。再把共用代码提取出来,便于复用。
因为做项目,需要各种风格的页面结构,变得是页面,js代码几乎没啥变化,既然vue3提出来composition API,那么就别浪费了,拿来用呗。
本来今天想把数据都联动起来的,结果卡住了。后面是查询、分页和列表的联动。这个应该加上webSQL了。
满满的调试风格,控件类型还没有改。。。
随便加的数据。
明明用的UI库,为啥还是不好看呢?没有艺术细胞真愁人。。。