jeecgboot项目前端vue3.0项目BasicTable组件实现父子组件之间的关联, jeecgboot项目前端uni-app前端下程序项目打包
jeecgboot项目前端vue3.0项目BasicTable组件实现父子组件之间的关联, jeecgboot项目前端uni-app前端下程序项目打包
文章目录
一、jeecgboot项目前端vue3.0项目BasicTable组件实现父子组件之间的关联
1、需求说明
1:实现勾选父table的多选,子列表的多选全部选中
2:子列表的多选全部选中,勾选父table的多选
3:实现父列表和子列表的多选关联
2、代码实现
<template>
<BasicTable
@register="registerTable"
:expandedRowKeys="expandedRowKeys"
:rowSelection="parentRowSelection"
:expand-column-width="80"
:indentSize="0"
:clickToRowSelect="false"
@expand="handleExpand"
:scroll="{ x: 1300, y: 1000 }"
>
<template #headerCell="{ column, title }">
<template v-if="!column.customTitle">
<span> 任务明细 </span>
</template>
<HeaderCell v-else :column="column" />
</template>
<template #emptyText>
<i class="emptyTextImg">
<img :src="emptyText" />
</i>
<div class="emptyTextTitle">暂无数据</div>
</template>
<template #expandedRowRender="{ record }">
<BasicTable
style="margin-left: 0px"
:key="record.id"
:ref="`tableRef${record.id}`"
:columns="innerColumns"
:data-source="record.taskCodingInfoList"
:clickToRowSelect="false"
:rowSelection="childRowSelection(record)"
rowKey="childId"
:canResize="false"
:pagination="false"
:showActionColumn="true"
:showIndexColumn="true"
:bordered="false"
:actionColumn="{
title: '管理任务',
width: 200,
slots: { customRender: 'actionChild' },
}"
>
<template #actionChild="{ record: recordData }">
<TableAction class="action" :actions="getTableActionChild(recordData)" :dropDownActions="getDropDownAction(recordData)" />
<!-- -->
</template>
<template #emptyText>
<i class="emptyTextImg">
<img :src="emptyText" />
</i>
<div class="emptyTextTitle">暂无数据</div>
</template>
</BasicTable>
</template>
<template #action="{ record }">
<TableAction class="action" :actions="getTableAction(record)" />
</template>
</BasicTable>
</template>
<script lang="ts" name="system-menu">
import { ref, defineComponent, watch, onMounted } from 'vue';
import { columns, innerColumns } from '../codeManagement.data';
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import HeaderCell from '/@/components/Table/src/components/HeaderCell.vue';
import { useModal } from '/@/components/Modal';
import { list, finishTask, cancelTask } from '../codeManagement.api';
import { cancelOrder } from '/@/views/orderManaged/codedDocument/codedDocument.api';
import emptyText from '/@/assets/images/emptyText.png';
import { submitOrder } from '/@/views/orderManaged/codedDocument/codedDocument.api';
export default defineComponent({
components: { BasicTable, TableAction, HeaderCell},
props: {
searchData: {
type: Object,
default: () => ({}),
},
},
setup(props, ctx) {
let searchData = ref();
onMounted(() => {
searchData.value = props.searchData;
setProps({ searchInfo: { tabNo: '1', ...searchData.value } });
reload();
});
watch(
() => props.searchData,
(nValue) => {
searchData.value = nValue;
setProps({ searchInfo: { tabNo: '1', ...searchData.value } });
reload();
},
{
deep: true,
}
);
let headers = {
'Content-Type': 'application/x-www-form-urlencoded;boundary = ' + new Date().getTime(),
};
// 列表页面公共参数、方法
const { prefixCls, tableContext } = useListPage({
tableProps: {
title: '',
api: list,
columns: columns,
size: 'small',
isTreeTable: false,
striped: true,
useSearchForm: false,
showTableSetting: false,
bordered: false,
rowKey: 'id',
tableSetting: { fullScreen: true },
clickToRowSelect: false,
searchInfo: { tabNo: '1', ...searchData.value },
afterFetch: afterFetch,
immediate: false,
actionColumn: {
width: 200,
},
},
});
function afterFetch(record) {
record.map((item) => {
if (!!item.taskCodingInfoList && item.taskCodingInfoList.length > 0) {
item.taskCodingInfoList.forEach((i) => {
i.childId = i.id;
i.parentId = item.id;
});
}
});
console.log(record);
return record;
}
//注册table数据
const [registerTable, { reload, getDataSource, setProps }] = tableContext;
// 父表选中状态
const parentSelectedKeys = ref([]);
const selectedChildKeys = ref([]);
// 子表选中状态(每个父节点独立)
const childSelectedKeys = ref({});
const childRowSelection = (parent) => ({
selectedRowKeys: childSelectedKeys.value[parent.id] || [],
hideSelectAll: true,
type: 'checkbox',
columnWidth: 30,
selectedSelect: (record, selected) => handleChildSelect(record, selected, parent),
});
// 父表选中事件(递归处理子节点)
var handleParentSelect = (parent, selected) => {
console.log(parent, selected);
// 更新父表选中状态
parentSelectedKeys.value = selected ? [...parentSelectedKeys.value, parent.id] : parentSelectedKeys.value.filter((k) => k !== parent.id);
// 递归更新子表选中状态
const updateChildren = (children) => {
children.forEach((child) => {
const childList = childSelectedKeys.value[parent.id] || [];
childSelectedKeys.value[parent.id] = selected
? [...new Set([...childList, child.childId])]
: childList.filter((k) => k !== child.childId);
if (child.taskCodingInfoList) updateChildren(child.taskCodingInfoList);
});
};
updateChildren(parent.taskCodingInfoList || []);
};
// 子表选中事件(联动父表)
const handleChildSelect = (child, selected, parent) => {
console.log(child, selected, parent, '1111');
// 更新子表选中状态
const childList = childSelectedKeys.value[parent.id] || [];
childSelectedKeys.value[parent.id] = selected ? [...childList, child.childId] : childList.filter((k) => k !== child.childId);
// 判断是否全选子节点
const allChildrenSelected = parent.taskCodingInfoList.every((c) => childSelectedKeys.value[parent.id]?.includes(c.childId));
// 更新父表选中状态
if (allChildrenSelected && !parentSelectedKeys.value.includes(parent.id)) {
parentSelectedKeys.value = [...parentSelectedKeys.value, parent.id];
} else if (!allChildrenSelected && parentSelectedKeys.value.includes(parent.id)) {
parentSelectedKeys.value = parentSelectedKeys.value.filter((k) => k !== parent.id);
}
};
const parentRowSelection = {
selectedRowKeys: parentSelectedKeys,
selectedSelect: handleParentSelect,
type: 'checkbox',
columnWidth: 30,
checkStrictly: false, // 开启父子自动联动:ml-citation{ref="1,3" data="citationList"}
};
/**
* 展开事件
* */
// 展开key
let expandedRowKeys = ref<any[]>([]);
function handleExpand(expanded, record) {
expandedRowKeys.value = [];
if (expanded === true) {
expandedRowKeys.value.push(record.id);
}
}
/**
* 新增
*/
function handleCreate(record) {
openModal1(true, {
title: '分配赋码任务',
type: 'add',
record: record,
});
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '取消',
popConfirm: {
title: '确认取消',
confirm: handleCancelOrder.bind(null, record),
},
},
];
}
async function handleCancelOrder(record) {
let formData = new FormData();
formData.append('id', record.id);
await cancelOrder(formData, headers);
reload();
}
function getTableActionChild(record) {
return [
{
label: '完成',
onClick: handleFinished.bind(null, record),
ifShow: record.status == '1',
},
];
}
function getDropDownAction(record) {
return [
{
label: '终止',
popConfirm: {
title: '确认终止',
confirm: handleStopTask.bind(null, record),
},
ifShow: false,
},
];
}
/**
* 终止任务
*/
async function handleStopTask(record) {
let formData = new FormData();
formData.append('taskId', record.id);
await cancelTask(formData, headers);
reload();
}
/**
* 任务完成
*/
async function handleFinished(record) {
console.log(record.id);
let formData = new FormData();
formData.append('taskId', record.id);
await finishTask(formData, headers);
reload();
}
return {
innerColumns,
emptyText,
registerTable,
handleChildSelect,
handleParentSelect,
childRowSelection,
parentRowSelection,
selectedChildKeys,
handleExpand,
expandedRowKeys,
handleCreate,
getTableActionChild,
getDropDownAction,
getTableAction,
};
},
});
</script>
<style lang="less" scoped>
</style>
注:需要修改hooks文件中的文件内容实现selectedSelect方法,返回选中的数据,我选中的状态
修改的内容
修改的文件路径
二、 jeecgboot项目前端uni-app前端下程序项目打包
JeecgUniapp 移动框架,采用uniapp、vue2、colorui框架,一份代码多终端适配,同时支持APP、小程序、H5! 实现了与JeecgBoot低代码平台 完美对接! 目前已经实现登录、用户信息、通讯录、公告、移动首页、九宫格等基础功能,更多功能请自己扩展。
- 跨平台:产品采用H5开发,能跨平台适用各种移动终端;一次开发,处处使用,大大降低终端开发成本。
- 自适应:界面统一采用自适应的布局思想,自适应不同终端分辨率。
- 通用性:产品功能都围绕常用办公需求,普遍适用绝大多数企业的日常需要。
- 系统集成:让所有系统和应用集成在一起展现,让用户更方便找到所需功能,更自由地处理工作事宜。
- 极简开发:内置各类模板,只需按照业务逻辑进行简单配置,即可轻松实现在线生成表单、自定义门户等功能。
下载源码
1、项目简介
- 一个uni-app工程,默认包含如下目录及文件
┌─components uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─hybrid 存放本地网页的目录,详见
├─platforms 存放各平台专用页面的目录,详见
├─pages 业务页面文件存放的目录
│├─index
││ └─index.vue index页面
│├─list
││ └─list.vue list页面
├─static 存放应用引用静态资源(如图片、视频等)的目录,**注意:**静态资源只能存放于此
├─wxcomponents 存放小程序组件的目录,详见
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
└─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
- jeecg-boot-uniapp项目,包含的非uni-app工程默认的其他目录
┌─_docs 项目的一些文档日志存放目录
├─api 请求服务端的接口文件存放目录
├─common 通用的文件
│├─luch-request 存放的是大神封装的request请求插件目录
│├─router 存放路由配置的目录
│├─service 存放请求拦截和开发环境配置
│├─util 存放的一些工具类
├─plugin 存放项目插件的目录
└─store 状态管理目录
2、启动项目
- 配置接口地址
配置文件:env/.env.development - 项目运行H5
pnpm run dev
- 运行小程序
- 下载 微信开发者工具
- 在.evn文件中 VITE_WX_APPID = ‘你的小程序appid’(也可使用测试号)
- 运行命令
pnpm run dev:mp - 把 dist/dev/mp-weixin 导入到工具
3、项目打包
- 项目地址配置
.env.production VITE_SERVER_BASEURL 改成生产地址// 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = ‘production’
// 是否去除console 和 debugger
VITE_DELETE_CONSOLE = true
// 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
VITE_SERVER_BASEURL = ‘你线上的地址’ - 打包h5
- 运行命令
pnpm run build:h5 或 pnpm run build - 产物放服务器
产物地址:dist/build/h5
- 运行命令
- 打包 Android
- uniapp 开发者中心实名认证
- 确认你是是该应用的成员或者拥有者
- HBuilderX 编辑器 发行 – 云打包
修改为自己的appId
打包页面配置等待 2-5 分钟,打包成功(产物地址:dist/release/apk/)
更多推荐
所有评论(0)