共计 4388 个字符,预计需要花费 11 分钟才能阅读完成。
项目开始时间 2023 年 10 月 01 日
项目现状 目前(维护中)
一、总结:
1、期间遇到问题,自己网上查资料,最终解决;
去百度搜索的时候,很多情况搜不到的原因是自己没有用专业的语句,口语化的语句很少能搜到答案,有时候问一问别人或许不能直接解决问题,但是却给了我们另一个思路去搜索,这样说不定就能找到答案。
2、前一天晚上想好第二天要做的内容,划分好时间,提高开发效率。
3、拿到需求到代码实现经历了怎样的过程?
站在用户角度使用:
拿到 ui 设计稿,把所有的页面先点一点,大概了解有哪些功能?在这一步,我们可以参考其他成熟的系统,如果有类似功能的话,就去点一点,了解每个操作。知道新功能的基本流程是哪些。
站在技术角度:
思考自己上一步都做了些什么。每个功能的要点在哪里。实现的难点在哪里。可能会发生什么样的情况,类似于 if…else 方式的思考。这一步,我们作为技术,考虑的是如何实现。
4、项目描述:
5、项目技术:Vue3 + element-plus + vue-router + Pinia + axios + Echarts
6、项目职责:
使用 Pinia 实现数据统一管理;
使用 Vue3 的 vite 框架、element-plus 实现快速布局;
使用 watchEffect 方法统一监听数据,从而更高效的解决数据变,页面变;
使用 Axios 网络请求库,调用后端接口获取数据,并将数据处理后传递给组件进行展示;
进行代码调试和单元测试,确保项目的稳定性和可靠性;
利用组件化思想,将页面封装成多个组件提高代码的复用性和可维护性;
性能优化,减少不必要的更新、使用异步组件加载、懒加载路由等,以提升页面加载速度和用户体验;
二、系统遇到的问题:
1、适配
什么是自适应布局?
自适应设计是能使网页自适应显示在不同大小终端设备上新网页设计方式及技术。简单的来说自适应就是让同一个页面自动适应不同大小的设备,从而解决为不同设备提供不同版本的页面问题。
解决方式:响应式布局,系统分为 header 上,menu 左,main 右,使用 flex 布局,并且右边 main 处不能出现滚动条,只可以 table 出现滚动条。
2、element-plus 的 tree 组件(一键选择)
需求:页面上展示所有的二 / 三级指标,要求点击按钮“一键选择二 / 三级指标”,tree 组件的复选框勾选上。
问题:使用 tree 组件自带方法 setCheckedKeys,但是时好时坏,有些时候复选框勾不全,控制台会报错。
解决方式:使用 tree 组件自带方法 default-checked-keys。点击按钮时请求拿到所有的二三级指标并循环,根据等级字段判断,把 ID push 到 default-checked-keys 变量中。
setCheckedKeys:设置目前选中的节点,使用此方法必须设置 node-key
属性
default-checked-keys:默认勾选的节点的 key 的数组
3. 把后端返回的数据,转成 tree 数据
第一种方式:
后端返回的数据
转换成 tree 代码
export let transformData2 = (nodes) => {const map = {};
let node;
let roots = [];
// 将所有节点转换成一个映射表
for (let i = 0; i {return item.fid || item.sjjgbm == nodes[i].jgbm || nodes[i].id;
});
if (hasChidren) {nodes[i].children = [];}
}
// 将所有子节点添加到其父节点的 children 属性中
for (let i = 0; i
第二种方式:
后端返回的数据
转换成 tree 代码
export let transformData = (nodes) => {const map1 = [];
// 第一级树
nodes.map((item, index) => {map1[index] = {};
map1[index].id = item.flmc_parent_id;
map1[index].zbmc = item.flmc_parent;
map1[index].children = [];});
// 去重
for (let i = 0; i {nodes.map((v, i) => {if (item.id == v.flmc_parent_id) {map1[index].children[i] = {};
map1[index].children[i].id = v.flmc_id;
map1[index].children[i].zbmc = v.flmc;
map1[index].children[i].children = [];}
});
});
// 去重
const newArr = map1.map((item) => {return item.children.filter((v, i, arr) => {return arr.indexOf(v) === i;
});
});
// 去重
newArr.map((item) => {
for (let i = 0; i
m.map((item, index) => {nodes.map((v, i) => {if (item.id == v.flmc_id) {item.children[i] = {...v, // 展开运算符};
}
});
})
);
// 去重
const dudududu = newArr.map((item) => {return item.map((m) => {return m.children.filter((v, i, arr) => {return arr.indexOf(v) === i;
});
});
});
// 去重
dudududu.map((item) => {item.map((m) => {for (let i = 0; i
4、前端实现分页(分享)
使用了 v3 的 watchEffect
watchEffect 也是监听数据,但是它会立即运行一个函数,而不是懒侦听。
如果需要页面加载完毕立即执行的话,还是用 watchEffect
watchEffect 它与 watch 的区别主要有以下几点:
1. 不需要手动传入依赖
2. 每次初始化时会执行一次回调函数来自动获取依赖
3. 无法获取到原值,只能得到变化后的值
4.watch
是惰性的,因此仅当依赖项更改时才会触发。watchEffect
在创建组件后立即运行,然后跟踪依赖关系。
const tableData = ref([]);
const currentTableData = ref([]); // table 组件的 data 值
const current = ref(1); // 页码
const total = ref(1); // 总条数
watchEffect(() => {
current.value = 1;
total.value = tableData.value.length;
currentTableData.value = tableData.value.filter((item, index) => index {
current.value = val;
const index = 30 * (val - 1);
const nums = 30 * val;
const tables = [];
for (let i = index; i {// 页面刚进来时,请求的数据给到 tableData.value});
5、页面跳转后,点击返回,改为返回来源页。
// 页面相关参数
const searchParams = reactive({
ckzYear: "",
year: "2024",
SchemeName: "",
faName: "",
isJCindex: "",
options: [],
newArr: [],
homeList: [],});
// 点击按钮跳转
let ckFun = async (item) => {let _data = Object.assign(searchParams, {});
setstorage("nowPageData", JSON.stringify(_data)); // 这两行代码用来往 sessionStorage 存数据
router.push("/StatisticalAnalysis-detail");
};
// 模板渲染后,立即执行的函数
onMounted(() => {if (getstorage("nowPageData")) {let _obj = JSON.parse(getstorage("nowPageData"));
Object.keys(searchParams).forEach((key) => {searchParams[key] = _obj[key] || searchParams[key];
});
removelist("nowPageData");
}
});
6、计算指标分(综合计算)
需求:出院患者微创手术占比 = (日间手术台次数 / 同期出院患者择期手术总台次数) * 100%
思路:
1. 拿到分子和分母的 value
2. 用字符串 replace 方法替换 str.replace(换下的值,换上的值)
3. 使用 eval。(eval 是 Javascript 内置函数,用于计算字符串表达式的值。例如eval(2+3) 返回的是 5。)
实现代码:
// 审核确定按钮
let util = () =>
{
// 计算公式编码
let jsgsbm = "({SJYLZL_GNDW_5_51 / SJYLZL_GNDW_5_52 * 100%})"
// 计算公式名称
let jsgsmc = "(5.1. 出院患者微创手术台次数 /5.2. 同期出院患者手术台次数)*100%"
// 分子和分母信息
let fz_fm = [
{
bool: false,
cqz: "0",
faid: 1,
fz_or_fm: "fz",
khdx: "医院",
khnf: "2024",
value: "221",
zbdm: "SJYLZL_GNDW_5_51",
zbmc: "出院患者微创手术台次数"
}, {
bool: false,
cqz: "0",
faid: 1,
fz_or_fm: "fm",
khdx: "医院",
khnf: "2024",
value: "226",
zbdm: "SJYLZL_GNDW_5_52",
zbmc: "同期出院患者手术台次数"
}
]
let str = "";
for (var i = 0; i
原文地址: 医院绩效考核系统