便利贴--43{vue3+ts+setup+ArcoDesign 表格和表单 单页模板(整合)} --舍弃--不删--不更新
前言
因为在vue3中的去中心化设计,可以单独每个功能的(数据,方法,引用,等)都可以放在一块单独的区域,所以为了更好的规范文件写法,目前的想法是通过注释分块,来进行区分和整合,为了能够快速构建,在本章文章中会集合ArcoDesign 的框架来整理出几个常用页面的布局和组件的使用
tableOnce.vue
<template>
<div class="table">
<div class="title">{{ $t("common.search") }}</div>
<div class="searchFrom" v-if="ourData.tabelData.visibleSearch">
<a-form
:model="ourData.tabelData.searchForm"
v-if="ourData.tabelData.searchType == 0"
>
<!-- 查询 -->
<a-row :gutter="24">
<a-col :span="10">
<a-form-item field="No" :label="$t('no')" label-col-flex="100px">
<a-input
v-model="ourData.tabelData.searchForm.No"
:placeholder="$t('in')"
/>
</a-form-item>
</a-col>
<a-col :span="10">
<a-form-item field="Date" :label="$t('Date')" label-col-flex="80px">
<a-range-picker v-model="ourData.tabelData.searchForm.Date" />
</a-form-item>
</a-col>
<div style="border-left: 1px solid var(--color-neutral-3)">
<a-col :span="24">
<a-row justify="right">
<a-form-item>
<a-button type="primary" @click="onSearch">{{
$t("common.search")
}}</a-button>
</a-form-item>
</a-row>
<a-row>
<a-form-item>
<a-button @click="onReset">{{ $t("common.reset") }}</a-button>
</a-form-item>
</a-row>
</a-col>
</div>
</a-row>
</a-form>
<a-form
:model="ourData.tabelData.searchForm"
v-if="ourData.tabelData.searchType == 1"
>
<a-row :gutter="24">
<a-col :span="10">
<a-form-item field="No" :label="$t('no')" label-col-flex="100px">
<a-input
v-model="ourData.tabelData.searchForm.No"
:placeholder="$t('in')"
/>
</a-form-item>
</a-col>
<a-col :span="10">
<a-form-item field="Date" :label="$t('Date')" label-col-flex="80px">
<a-range-picker v-model="ourData.tabelData.searchForm.Date" />
</a-form-item>
</a-col>
<a-col :span="4">
<a-form-item>
<a-space>
<a-button type="primary" @click="onOpenSearch">{{
$t("common.search")
}}</a-button>
<a-button @click="onOpenReset">{{ $t("common.reset") }}</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<div class="searchTabs">
<a-space size="medium">
<a-button type="primary">{{ $t("common.add") }}</a-button>
</a-space>
<a-space size="medium" style="float: right; margin-right: 50px">
<img
src="@/assets/images/portal/filter.png"
@click="ourData.tabelData.visibleSearch = !ourData.tabelData.visibleSearch"
/><img src="@/assets/images/portal/refresh.png" @click="onReset" />
</a-space>
</div>
<div class="table_box">
<!-- 表格主体 -->
<a-table
:bordered="false"
:pagination="false"
page-position="bottom"
style="max-height: 50vh; min-height: 450px; overflow: auto"
:data="ourData.tabelData.value"
v-model:selectedKeys="ourData.tabelData.selectedKeys"
:row-selection="ourData.tabelData.rowSelection"
row-key="propertyNo"
>
<template #columns>
<a-table-column :title="$t('account.table.order')">
<template #cell="{ column, record, rowIndex }">
<span>{{
ourData.tabelData.pagination.pageSize *
(ourData.tabelData.pagination.current - 1) +
rowIndex +
1
}}</span>
</template>
</a-table-column>
<a-table-column
:title="$t('numDigital.Warehouse.tabel.title.propertyNo')"
data-index="propertyNo"
>
</a-table-column>
<a-table-column :title="$t('common.operation')" align="center">
<template #cell="{ record }">
<a-button
type="text"
@click="gotoPage('inspectionEdit', { type: 'see' })"
>{{ $t("common.detail") }}</a-button
>
<a-divider direction="vertical" />
<a-dropdown trigger="click">
<a-button type="text" status="danger">{{ $t("common.more") }}</a-button>
<template #content>
<a-doption class="down_menu">
<a-space>
<i class="iconfont icon-a-zu7947" />
<span>
{{ $t("common.edit") }}
</span>
</a-space>
</a-doption>
<a-doption class="down_menu">
<a-space>
<i class="iconfont icon-a-lujing2308" />
<span>
{{ $t("common.delete") }}
</span>
</a-space>
</a-doption>
</template>
</a-dropdown>
</template>
</a-table-column>
</template>
</a-table>
<a-pagination
:total="ourData.tabelData.pagination.total"
style="justify-content: center; margin-top: 20px"
:current="ourData.tabelData.pagination.current"
:page-size="ourData.tabelData.pagination.pageSize"
show-total
show-jumper
show-page-size
@change="pageChange"
@page-size-change="pageSizeChange"
/>
</div>
<!-- 弹窗 -->
<a-modal
:visible="modalVisible"
:title="$t('assetSettings.depreciation.newModeIn')"
title-align="start"
@cancel="handleCancel"
:footer="false"
width="auto"
>
<div style="min-width: 500px; min-height: 150px">
<a-form :model="ourData.modalForm" @submit="handleOk">
<a-row :gutter="24">
<a-col :span="13">
<a-form-item
field="leftDate"
:label="$t('reportForm.openForm.1')"
label-col-flex="100px"
>
<!-- <a-select
v-model="ourData.modalForm.leftDate"
:placeholder="$t('reportForm.openForm.1In')"
>
<a-option
v-for="item in ourData.selectOur.selectBM"
:value="item.code"
>{{ item.value }}</a-option
>
</a-select> -->
<!-- <a-cascader
v-model="ourData.modalForm.leftDate"
:options="ourData.selectOur.selectBM"
:placeholder="$t('numDigital.pleaseSelect')"
allow-clear
/> -->
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24" justify="end">
<a-col :span="7">
<a-form-item>
<a-space>
<a-button class="drawerBotton1" @click="handleCancel">{{
$t("common.cancel")
}}</a-button>
<a-button html-type="submit" type="primary" class="drawerBotton">{{
$t("feedback.hanlde")
}}</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
</a-modal>
</div>
</template>
<script lang="ts" setup>
// **************************** 模板块 ****************************↓↓↓↓↓↓
// **************************** 模板块 ****************************↑↑↑↑↑↑
import { ref, reactive, watch, computed, onMounted } from "vue";
import { Message, Modal } from "@arco-design/web-vue";
// **************************** 初始化数据 ****************************↓↓↓↓↓↓
//中英文
import { useI18n } from "vue-i18n";
const { t } = useI18n();
import { useUserStore } from "@/store";
const userStore = useUserStore();
import useLoading from "@/hooks/loading";
const { loading, setLoading } = useLoading();
// //路由
import { useRoute, useRouter } from "vue-router";
// // 路由信息
const route = useRoute();
// // 路由更改
const router = useRouter();
//更改路由方法
const gotoPage = (pageName: String, query: Object) => {
router.push({
name: pageName,
query: query,
});
};
//页面数据合集
const ourData = reactive({
//表格
tableData: {},
//弹出表单
modalForm: {},
//字典数据
selectOur: {},
});
onMounted(() => {});
// **************************** 初始化数据 ****************************↑↑↑↑↑↑
// **************************** 表格 ****************************↓↓↓↓↓↓
const onInit = () => {
ourData.tabelData = {
// tableData自带数据和分页内容和搜索信息
value: [],
pagination: {
total: 4,
current: 1,
pageSize: 10,
showTotal: true,
showJumper: true,
showPageSize: true,
}, //分页参数
searchType: 1,
searchForm: {}, //搜索表单
//多选选项
rowSelection: {
type: "checkbox",
showCheckedAll: true,
},
//多选数据
selectedKeys: [],
//显影表格
visibleSearch: true,
};
};
// 初始化表格基本数据
onInit();
//分页操作
//页码改变
const pageChange = (page: number) => {
//debugger;
ourData.tabelData.pagination.current = page;
getTabelData();
};
//每页条数改变
const pageSizeChange = (pageSize: number) => {
ourData.tabelData.pagination.current = 1;
ourData.tabelData.pagination.pageSize = pageSize;
getTabelData();
};
//获取表格数据
const getTabelData = async () => {
setLoading(true);
try {
let startTime = "",
endTime = "";
//处理借用日期
if (ourData.tabelData.searchForm.Date) {
startTime = ourData.tabelData.searchForm.Date[0] + " 00:00:00";
endTime = ourData.tabelData.searchForm.Date[1] + " 23:59:59";
}
let data = {
page: ourData.tabelData.pagination.current,
pageSize: ourData.tabelData.pagination.pageSize,
};
for (let k = 0; k < 10; k++) {
ourData.tabelData.value.push(
...[{ propertyNo: 123 }, { propertyNo: 456 }, { propertyNo: 789 }]
);
}
console.log("获取tableData");
ourData.tabelData.pagination.total = ourData.tabelData.value.length;
} catch (err) {
// you can report use errorHandler or other
} finally {
setLoading(false);
}
};
//初始化表格内容数据
getTabelData();
//查询事件
const onSearch = () => {
ourData.tabelData.pagination.pageSize = 10;
ourData.tabelData.pagination.current = 1;
getTabelData();
};
//清空查询
const onReset = () => {
onInit();
getTabelData();
};
// **************************** 表格 ****************************↑↑↑↑↑↑
// **************************** 弹窗表单 ****************************↓↓↓↓↓↓
//显影
const modalVisible = ref(true);
const modalType = ref("");
//打开弹窗
const openModal = () => {
modalVisible.value = true;
};
// 事件 清空
const handleCancel = () => {
modalVisible.value = false;
//清空表单数据
getModalData();
};
//加载表单模型数据
const getModalData = () => {
ourData.modalForm = {
leftDate: "",
};
};
getModalData();
//表单提交事件
const handleOk = (e) => {
console.log(e);
};
// **************************** 弹窗表单 ****************************↑↑↑↑↑↑
// **************************** 字典数据 ****************************↓↓↓↓↓↓
// 字典api
// import { dictList } from "@/api/feedback";
// import { api } from "@/api/api";
// 初始化字典数据
const getSelectOur = () => {
ourData.selectOur = {
onceSelect: {},
};
};
getSelectOur();
//获取字典数据
const getSelectData = async () => {
//赋值onceSelect
};
getSelectData();
//动态字典数据 通过watch监听 父数据更改↓↓↓↓↓
watch(
() => ourData.modalForm.leftDate,
() => {
getOnce(1);
},
{
deep: true,
immediate: false,
}
);
// 查询管理员信息
const getOnce = async (id) => {
//获取第二关联下拉菜单
};
//动态字典数据 通过watch监听 父数据更改↑↑↑↑↑
// **************************** 字典数据 ****************************↑↑↑↑↑↑
</script>
<style lang="less" scoped>
.table {
margin: 00.08333rem;
flex-grow: 3;
margin-left: 20px;
background-color: var(--color-bg-3);
.title {
padding: 16px 24px;
color: rgb(var(--gray-10));
font-weight: 400;
font-size: 16px;
font-family: "Source Han Sans CN";
line-height: 30px;
text-align: left;
// border-bottom: 1px solid var(--gray-3);
// border-bottom: 1px solid var(--color-neutral-3);
}
.searchTabs {
margin: 20px 0 0 24px;
}
.table_box {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 16px 24px;
}
}
</style>
affuxFormModal.vue
<template>
<div class="model">
<a-form :model="ourData.formData" @submit="formSubmit">
<div class="model_box">
<a-affix :offsetTop="80">
<a-anchor
:style="{ backgroundColor: 'var(--color-bg-1)' }"
:change-hash="false"
scroll-container=".data_main"
class="anchor"
>
<a-anchor-link
:href="'#' + item.id"
v-for="(item, index) in leftTab"
:key="index"
>{{ $t(item.label) }}</a-anchor-link
>
</a-anchor>
</a-affix>
<div class="data_main">
<div v-for="(itemtab, indextab) in leftTab">
<div :id="itemtab.id" class="inAnchorChilden">
{{ $t(itemtab.label) }}
</div>
<a-row :gutter="24" v-if="indextab == 0">
<a-col :span="20"> 1 </a-col>
</a-row>
<a-row :gutter="24" v-if="indextab == 1" class="depreciationForm">
<a-col :span="20"> 2 </a-col>
</a-row>
</div>
</div>
</div>
<a-form-item class="bottomBtn">
<a-button>{{ $t("common.cancel") }}</a-button>
<a-button html-type="submit" type="primary" class="confirmBtn">{{
$t("common.confirm")
}}</a-button>
</a-form-item>
</a-form>
<!-- 弹窗 -->
<a-modal
:visible="modalVisible"
:title="$t('assetSettings.depreciation.newModeIn')"
title-align="start"
@cancel="handleCancel"
:footer="false"
width="auto"
>
<div style="min-width: 500px; min-height: 150px">
<a-form :model="ourData.modalForm" @submit="handleOk">
<a-row :gutter="24">
<a-col :span="10">
<!-- 部门 -->
<a-form-item field="leftDate" :label="$t('reportForm.openForm.1')">
<a-input
v-model="ourData.modalForm.leftDate"
:placeholder="$t('numDigital.Warehouse.tabel.query.indexIn')"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24" justify="end">
<a-col :span="7">
<a-form-item>
<a-space>
<a-button class="drawerBotton1" @click="handleCancel">{{
$t("common.cancel")
}}</a-button>
<a-button html-type="submit" type="primary" class="drawerBotton">{{
$t("feedback.hanlde")
}}</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, watch, computed, onMounted, getCurrentInstance } from "vue";
import { useRoute, useRouter } from "vue-router"; //useRoute()获取当前路由,useRouter()操作路由
//引入提示 Message 确认框Modal
import { Message, Modal } from "@arco-design/web-vue";
//引用中英文编译
import { useI18n } from "vue-i18n";
const { t } = useI18n();
//引入api
// import {} from "@/api/assetSettings/depreciation";
//字典api
import { dictList } from "@/api/feedback";
// **************************** 模板块 ****************************↓↓↓↓↓↓
// **************************** 模板块 ****************************↑↑↑↑↑↑
// 所有数据
const ourData = reactive({
modeData: [], //列表
modalForm: {}, //单个折旧表单
approvalProcessData: {}, //资产审批流程
});
// **************************** 左侧标签页 ****************************↓↓↓↓↓↓
const leftTab = ref([
{ id: 1, label: "基本信息" },
{ id: 2, label: "附加内容" },
]);
// **************************** 左侧标签页 ****************************↑↑↑↑↑↑
//mounted生命周期
onMounted(() => {
//获取字典数据
getSelectDatas();
});
// **************************** 字典数据 ****************************↓↓↓↓↓↓
//数据
const selectOur = reactive({});
// 获取
const getSelectDatas = async () => {};
// **************************** 字典数据 ****************************↑↑↑↑↑↑
// **************************** 弹窗表单 ****************************↓↓↓↓↓↓
//显影
const modalVisible = ref(false);
const modalType = ref("");
//打开弹窗
const openModal = () => {
modalVisible.value = true;
};
// 事件 清空
const handleCancel = () => {
modalVisible.value = false;
//清空表单数据
getModalData();
};
//加载表单模型数据
const getModalData = () => {
ourData.modalForm = {
leftDate: "",
};
};
getModalData();
//表单提交事件
const handleOk = (e) => {};
// **************************** 弹窗表单 ****************************↑↑↑↑↑↑
// **************************** 总表单 ****************************↓↓↓↓↓↓
// 提交
const formSubmit = async (e) => {
openModal();
};
// **************************** 总表单 ****************************↑↑↑↑↑↑
</script>
<style lang="less" scoped>
.model {
background-color: var(--color-bg-3);
display: flex;
flex: 1;
flex-direction: column;
margin: 0.08333rem;
.arco-form {
flex: 1;
justify-content: space-between;
.arco-tabs {
padding: 16px 108px 0 60px;
}
}
}
.model_box {
display: flex; // justify-content: center;
margin: 0.1525rem;
}
.modes {
width: 100%;
height: 80px;
background-color: #f6f8fa;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 23px;
}
.data_main {
width: 100%;
max-height: calc(100vh - 1.8075rem);
overflow-y: auto;
overflow-x: hidden;
}
.bottomBtn {
display: flex;
flex-direction: row;
align-items: center;
height: 64px;
margin-bottom: 0;
// margin-left: -44px;
background: #fff;
box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.16);
:deep .arco-form-item-content-flex {
justify-content: flex-end;
.confirmBtn {
margin-right: 64px;
margin-left: 24px;
}
}
}
</style>