Commit 22e164bd authored by hucy's avatar hucy

fix:导航tab优化

parent e0fc674c
......@@ -10,9 +10,9 @@
"dependencies": {
"@antv/x6": "^1.32.11",
"@quasar/extras": "^1.0.0",
"ag-grid-community": "^28.0.0",
"ag-grid-enterprise": "^28.0.0",
"ag-grid-vue3": "^28.0.0",
"ag-grid-community": "^28.2.1",
"ag-grid-enterprise": "^28.2.1",
"ag-grid-vue3": "^28.2.1",
"animejs": "^3.2.1",
"axios": "^0.27.2",
"core-js": "^3.6.5",
......@@ -30,6 +30,7 @@
},
"devDependencies": {
"@quasar/app-webpack": "^3.0.0",
"@quasar/quasar-app-extension-qmediaplayer": "^2.0.0-beta.6",
"@types/lodash-es": "^4.17.6",
"@types/node": "^12.20.21",
"@typescript-eslint/eslint-plugin": "^5.10.0",
......@@ -2428,6 +2429,37 @@
"url": "https://donate.quasar.dev"
}
},
"node_modules/@quasar/quasar-app-extension-qmediaplayer": {
"version": "2.0.0-beta.6",
"resolved": "https://registry.npmjs.org/@quasar/quasar-app-extension-qmediaplayer/-/quasar-app-extension-qmediaplayer-2.0.0-beta.6.tgz",
"integrity": "sha512-Mrqqny92+/Kj5TuHzXLsbHF8j4Ltjuhwdq+tkkpx99Iw0zeE5lcFDTNzmiAllN8+W7h57FzDWiidvsh8dXPnDg==",
"dev": true,
"dependencies": {
"@quasar/quasar-ui-qmediaplayer": "^2.0.0-beta.6"
},
"engines": {
"node": ">= 10.0.0",
"npm": ">= 5.6.0",
"yarn": ">= 1.6.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/hawkeye64"
}
},
"node_modules/@quasar/quasar-ui-qmediaplayer": {
"version": "2.0.0-beta.6",
"resolved": "https://registry.npmjs.org/@quasar/quasar-ui-qmediaplayer/-/quasar-ui-qmediaplayer-2.0.0-beta.6.tgz",
"integrity": "sha512-j0Y6NCMkup/fjwpOT2kWPG+w3X1yVxmRaSHxQRtWLsWHjiSheaJLWKqZDJ9UarEKL8rtS/CUtadD+ENvcBEHHQ==",
"dev": true,
"dependencies": {
"@quasar/extras": "^1.13.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/hawkeye64"
}
},
"node_modules/@quasar/ssr-helpers": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@quasar/ssr-helpers/-/ssr-helpers-2.2.0.tgz",
......@@ -3252,23 +3284,21 @@
}
},
"node_modules/ag-grid-community": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-28.0.0.tgz",
"integrity": "sha512-ovatVo8iGbJZHQRY2ga92IXLSPiLq8zzKIHsli4DU073P/e334gGrk9aTjAD0N0qRie+iKCvkQiZFPo07Wzl1Q==",
"license": "MIT"
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-28.2.1.tgz",
"integrity": "sha512-DMZh/xD/FqYP17qJ1M92PolTYe+hrKuEaf+A4h13O6qn2x/xZQrTRGW5DgnQLR/uLMe1XXZQPKR3UKgAlKo69A=="
},
"node_modules/ag-grid-enterprise": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/ag-grid-enterprise/-/ag-grid-enterprise-28.0.0.tgz",
"integrity": "sha512-bTyTU+Fc6aw8aXgbaIlsuDsQ9mPXjTOQpEQm3J6cg947iEhO6W/74VWh+MicYZaEKK2/wDkcchhVgDADUOpe+A=="
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-enterprise/-/ag-grid-enterprise-28.2.1.tgz",
"integrity": "sha512-FIqIiaMMO9m8eqfu64rZ7dOK8vQFqD+Dp9CTpSfjMtyUp4IoRE36c+mUpUGLX/bIix9LltpaUmr185nFM1Alrw=="
},
"node_modules/ag-grid-vue3": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/ag-grid-vue3/-/ag-grid-vue3-28.0.0.tgz",
"integrity": "sha512-qQQEuOiiJLkK1l4aHIo7PMG6iU7QHZHOMvYPnKDHjdEKvEU3NKuw6pJB4Ot7EdUnnqSBJOKx7/FMibHelerijw==",
"license": "MIT",
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-vue3/-/ag-grid-vue3-28.2.1.tgz",
"integrity": "sha512-n7+l51zFCZm3SVT2pI0lVVwL8gsDPebqNLfEy4DS17OlV5IL7c1eNXRosv/QMu+YHOEMVcwFRWH380nIjVF/+w==",
"dependencies": {
"ag-grid-community": "~28.0.0",
"ag-grid-community": "~28.2.1",
"vue": "^3.0.0"
}
},
......@@ -13292,6 +13322,24 @@
"integrity": "sha512-p3JKgTjRlJ1YQXbqTw3Bsa4j0mQdt5dq+WfYvyb7MgKGdephHCKdR/kxA5PCTAmJanGJuDKqRdyGYX/hYN4KGw==",
"dev": true
},
"@quasar/quasar-app-extension-qmediaplayer": {
"version": "2.0.0-beta.6",
"resolved": "https://registry.npmjs.org/@quasar/quasar-app-extension-qmediaplayer/-/quasar-app-extension-qmediaplayer-2.0.0-beta.6.tgz",
"integrity": "sha512-Mrqqny92+/Kj5TuHzXLsbHF8j4Ltjuhwdq+tkkpx99Iw0zeE5lcFDTNzmiAllN8+W7h57FzDWiidvsh8dXPnDg==",
"dev": true,
"requires": {
"@quasar/quasar-ui-qmediaplayer": "^2.0.0-beta.6"
}
},
"@quasar/quasar-ui-qmediaplayer": {
"version": "2.0.0-beta.6",
"resolved": "https://registry.npmjs.org/@quasar/quasar-ui-qmediaplayer/-/quasar-ui-qmediaplayer-2.0.0-beta.6.tgz",
"integrity": "sha512-j0Y6NCMkup/fjwpOT2kWPG+w3X1yVxmRaSHxQRtWLsWHjiSheaJLWKqZDJ9UarEKL8rtS/CUtadD+ENvcBEHHQ==",
"dev": true,
"requires": {
"@quasar/extras": "^1.13.0"
}
},
"@quasar/ssr-helpers": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@quasar/ssr-helpers/-/ssr-helpers-2.2.0.tgz",
......@@ -13934,21 +13982,21 @@
"dev": true
},
"ag-grid-community": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-28.0.0.tgz",
"integrity": "sha512-ovatVo8iGbJZHQRY2ga92IXLSPiLq8zzKIHsli4DU073P/e334gGrk9aTjAD0N0qRie+iKCvkQiZFPo07Wzl1Q=="
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-28.2.1.tgz",
"integrity": "sha512-DMZh/xD/FqYP17qJ1M92PolTYe+hrKuEaf+A4h13O6qn2x/xZQrTRGW5DgnQLR/uLMe1XXZQPKR3UKgAlKo69A=="
},
"ag-grid-enterprise": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/ag-grid-enterprise/-/ag-grid-enterprise-28.0.0.tgz",
"integrity": "sha512-bTyTU+Fc6aw8aXgbaIlsuDsQ9mPXjTOQpEQm3J6cg947iEhO6W/74VWh+MicYZaEKK2/wDkcchhVgDADUOpe+A=="
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-enterprise/-/ag-grid-enterprise-28.2.1.tgz",
"integrity": "sha512-FIqIiaMMO9m8eqfu64rZ7dOK8vQFqD+Dp9CTpSfjMtyUp4IoRE36c+mUpUGLX/bIix9LltpaUmr185nFM1Alrw=="
},
"ag-grid-vue3": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/ag-grid-vue3/-/ag-grid-vue3-28.0.0.tgz",
"integrity": "sha512-qQQEuOiiJLkK1l4aHIo7PMG6iU7QHZHOMvYPnKDHjdEKvEU3NKuw6pJB4Ot7EdUnnqSBJOKx7/FMibHelerijw==",
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-vue3/-/ag-grid-vue3-28.2.1.tgz",
"integrity": "sha512-n7+l51zFCZm3SVT2pI0lVVwL8gsDPebqNLfEy4DS17OlV5IL7c1eNXRosv/QMu+YHOEMVcwFRWH380nIjVF/+w==",
"requires": {
"ag-grid-community": "~28.0.0",
"ag-grid-community": "~28.2.1",
"vue": "^3.0.0"
}
},
......
import { Notify } from 'quasar';
import ICON from 'src/config/icons';
const creatNotify = function (type: string, msg: string) {
const creatNotify = function (type: string, icon: string, msg: string) {
Notify.create({
position: 'top',
type,
icon,
textColor: 'white',
message: msg,
position: 'top',
});
};
type IMessage = {
......@@ -16,16 +19,16 @@ type IMessage = {
const message: IMessage = {
success: (msg: string) => {
creatNotify('positive', msg);
creatNotify('positive', ICON.success, msg);
},
error: (msg: string) => {
creatNotify('negative', msg);
creatNotify('negative', ICON.error, msg);
},
warn: (msg: string) => {
creatNotify('warning', msg);
creatNotify('warning', ICON.warn, msg);
},
info: (msg: string) => {
creatNotify('info', msg);
creatNotify('info', ICON.info, msg);
},
};
......
......@@ -50,7 +50,8 @@ const usePageStore = defineStore(PAGE_STORE_KEY, {
}
this.saveToSession();
},
removePage(path: string) {
removePage(params: any) {
const path = params.link;
const index = findIndex(this.tabRouterList, ['path', path]);
if (path === this.activeRouter.path) {
if (index > 0) {
......@@ -59,10 +60,25 @@ const usePageStore = defineStore(PAGE_STORE_KEY, {
this.activeRouter = this.tabRouterList[index + 1];
}
}
if (params.keepalive) {
this.allPageKeys.splice(index, 1);
}
delArrObj(this.tabRouterList, { path: path });
this.saveToSession();
},
removeNotCurrentPage(params: any) {
const path = params.link;
if (params.keepalive) {
this.allPageKeys = [params.name];
} else {
this.allPageKeys = [];
}
this.tabRouterList = this.tabRouterList.filter((item) => {
return item.path === path;
});
this.saveToSession();
},
saveToSession() {
session.setItem(PAGE_STORE_KEY, JSON.stringify(this.$state));
},
......
......@@ -13,7 +13,7 @@
<q-item-section>
<q-item-label>{{ title }}</q-item-label>
<q-item-label caption>{{ caption }}</q-item-label>
<q-item-label caption v-if="caption">{{ caption }}</q-item-label>
</q-item-section>
</q-item>
</template>
......
export default {
success: 'bi-check-circle-fill',
error: 'bi-exclamation-triangle-fill',
warn: 'bi-exclamation-circle-fill',
info: 'bi-info-circle-fill',
num0: 'fa-solid fa-0', // 数字0
idCard: 'fa-regular fa-address-card', // 身份证
mapLocation: 'bi-pin-map-fill', // 地图定位
......
......@@ -33,13 +33,6 @@ a:hover {
.bg-pause {
background: #df7861;
}
// 导航栏激活颜色
.text-headeractive {
color: $primary-3;
}
.bg-headeractive {
background: $primary-3;
}
// tooltip样式
.com-tooltip-sty {
......@@ -97,10 +90,10 @@ a:hover {
// 标题列调整大小句柄颜色
--ag-header-column-resize-handle-color: var(--my-ag-grid-active) !important;
--ag-selected-row-background-color: var(--my-ag-grid-primary-2) !important;
--ag-range-selection-background-color: var(--my-ag-grid-primary-2) !important;
--ag-row-hover-color: var(--my-ag-grid-primary-1) !important;
--ag-column-hover-color: var(--my-ag-grid-primary-1) !important;
--ag-selected-row-background-color: var(--my-ag-grid-primary-5) !important;
--ag-range-selection-background-color: var(--my-ag-grid-primary-5) !important;
--ag-row-hover-color: var(--my-ag-grid-primary-2) !important;
--ag-column-hover-color: var(--my-ag-grid-primary-2) !important;
--ag-input-focus-border-color: var(--my-ag-grid-primary-1) !important;
--ag-border-color: var(--my-ag-grid-primary) !important;
......
......@@ -25,8 +25,8 @@ $accent: #9c27b0;
$dark: #1d1d1d;
$positive: #8bc24c;
$negative: #d2001a;
$positive: #81c784;
$negative: #dd4a48;
$info: #a696c8;
$warning: #ffb200;
......@@ -62,6 +62,7 @@ $header-heigyht: 50px;
--my-ag-grid-primary-light: rgba(165, 189, 22, 0.05);
--my-ag-grid-primary-1: rgba(165, 189, 22, 0.1);
--my-ag-grid-primary-2: rgba(165, 189, 22, 0.2);
--my-ag-grid-primary-5: rgba(165, 189, 22, 0.5);
--my-ag-grid-active: rgb(97, 112, 17);
--my-ag-grid-text: #fff7f7;
......
......@@ -14,14 +14,8 @@
</q-avatar>
</q-btn>
<q-toolbar-title> Quasar App </q-toolbar-title>
<q-tabs
v-model="defaultRouter"
no-caps
shrink
active-color="white"
active-bg-color="headeractive"
>
<q-toolbar-title style="min-width: 140px"> Quasar App </q-toolbar-title>
<q-tabs v-model="defaultRouter" no-caps shrink class="my-tabs">
<q-tab
class="my-tab"
v-for="page in tabsList"
......@@ -31,16 +25,35 @@
@click.stop="clickTab(page)"
>
<q-btn
v-show="tabsList.length > 1"
v-show="isShowCloseBtn"
dense
flat
round
size="sm"
icon="close"
title="关闭"
@mousedown.stop="doNothing"
@click.stop="closeTab(page)"
>
</q-btn>
<q-menu touch-position context-menu v-if="isShowCloseBtn">
<q-list dense style="min-width: 100px">
<q-item clickable v-close-popup>
<q-item-section @click="closeTab(page)"
>关闭当前页面</q-item-section
>
</q-item>
<q-item clickable v-close-popup>
<q-item-section @click="closeNotCurrentPage(page)"
>关闭非当前页面</q-item-section
>
</q-item>
<q-item clickable v-close-popup>
<q-item-section @click="closeAll">关闭所有</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-tab>
</q-tabs>
......@@ -71,9 +84,16 @@
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, reactive, toRefs } from 'vue';
import {
defineComponent,
ref,
onMounted,
reactive,
toRefs,
computed,
} from 'vue';
import { onBeforeRouteUpdate, useRouter } from 'vue-router';
import { usePageStore } from 'src/common/hooks';
import { usePageStore, useMessage } from 'src/common/hooks';
import EssentialLink from 'components/EssentialLink.vue';
// import TopLeftLoading from './TopLeftLoading.vue';
import TopLeftLoading from './TopLeftText.vue';
......@@ -91,6 +111,8 @@ export default defineComponent({
setup() {
const pageStore = usePageStore();
const router = useRouter();
const { info } = useMessage();
const leftDrawerOpen = ref(false);
const defaultRouter = ref('/page1');
const linksList = ref<any>([]);
......@@ -106,6 +128,19 @@ export default defineComponent({
}
next();
});
const isShowCloseBtn = computed(() => {
let flag = true;
const { tabsList } = state;
if (tabsList.length === 1) {
const target = tabsList[0];
if (target.link === '/home') {
flag = false;
}
}
return flag;
});
onMounted(() => {
getLinksList();
const path = router.currentRoute.value.path;
......@@ -116,12 +151,19 @@ export default defineComponent({
const getLinksList = () => {
const lists = [
{
title: '主页',
caption: null,
icon: require('./menuListIcons/home.svg'),
link: '/home',
active: false,
},
{
title: '一',
caption: '日历',
icon: require('./menuListIcons/page1.svg'),
link: '/page1',
active: true,
active: false,
},
{
title: '贰',
......@@ -206,6 +248,7 @@ export default defineComponent({
link: item.path,
keepalive: item.meta?.keepalive,
permission: item.meta?.permission,
name: item.name,
};
});
};
......@@ -215,9 +258,25 @@ export default defineComponent({
};
const closeTab = (page: any) => {
pageStore.removePage(page.link);
const { tabsList } = state;
if (tabsList.length === 1) {
router.push('/home');
pageStore.removePage(page);
getTabsList();
} else {
pageStore.removePage(page);
getTabsList();
router.push(pageStore.activeRouter.path);
}
};
const closeNotCurrentPage = (page: any) => {
pageStore.removeNotCurrentPage(page);
getTabsList();
};
const closeAll = () => {
info('正在开发中...');
};
const doNothing = () => {
......@@ -236,13 +295,19 @@ export default defineComponent({
defaultRouter,
clickTab,
closeTab,
closeNotCurrentPage,
closeAll,
doNothing,
isShowCloseBtn,
};
},
});
</script>
<style lang="scss" scoped>
.my-tab {
box-sizing: border-box;
background-color: $primary-4;
margin: 0 2px;
:deep(.q-tab__content) {
display: flex;
flex-direction: row;
......@@ -258,4 +323,12 @@ export default defineComponent({
}
}
}
.my-tabs {
padding: 0 36px;
box-sizing: border-box;
:deep(.q-tab--active) {
background-color: $primary-2;
}
}
</style>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1672903394187" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15179" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M119.838 786.652V581.34l18-55.742 367.084-344.66a10.322 10.322 0 0 1 14.154 0l367.084 344.66 18 55.742v205.312L512 809.88z" fill="#E7ECF1" p-id="15180"></path><path d="M504.924 144.938L119.838 507.598v73.742l385.084-362.66a10.322 10.322 0 0 1 14.154 0L904.16 581.34v-73.742L519.078 144.938a10.322 10.322 0 0 0-14.154 0zM119.838 823.814l392.162 18 392.162-18 18-18.582-18-18.58H119.838l-18 18.58z" fill="#C6D0DA" p-id="15181"></path><path d="M625.02 786.652V548.878a10.32 10.32 0 0 0-10.322-10.322H409.302a10.322 10.322 0 0 0-10.322 10.322v237.772L512 809.88z" fill="#ECB85E" p-id="15182"></path><path d="M398.98 823.814l113.02 18 113.02-18v-37.162H398.98z" fill="#EAA949" p-id="15183"></path><path d="M904.162 870.27l-392.162 18-392.162-18-18-24.332 18-22.124h784.324l18 22.124z" fill="#CF8151" p-id="15184"></path><path d="M119.838 907.43h784.324l18-19.16-18-18H119.838l-18 18.58z" fill="#BD6E45" p-id="15185"></path><path d="M1024 926.57v-141.964a10.32 10.32 0 0 0-3.292-7.558l-49.596-46.14a10.324 10.324 0 0 0-14.062 0l-49.596 46.14a10.324 10.324 0 0 0-3.292 7.558v141.964l59.92 18zM797.96 926.57v-141.964a10.32 10.32 0 0 0-3.292-7.558l-49.596-46.14a10.324 10.324 0 0 0-14.062 0l-49.596 46.14a10.318 10.318 0 0 0-3.292 7.558v141.964l59.92 18zM571.92 926.57v-141.964a10.32 10.32 0 0 0-3.292-7.558l-49.596-46.14a10.324 10.324 0 0 0-14.062 0l-49.596 46.14a10.318 10.318 0 0 0-3.292 7.558v141.964l59.92 18zM345.878 926.57v-141.964a10.32 10.32 0 0 0-3.292-7.558l-49.596-46.14a10.324 10.324 0 0 0-14.062 0l-49.596 46.14a10.318 10.318 0 0 0-3.292 7.558v141.964l59.92 18z" fill="#E2AE84" p-id="15186"></path><path d="M904.162 349.158v-141.93c0-11.402-9.244-20.646-20.646-20.646h-67.408c-11.402 0-20.646 9.244-20.646 20.646v39.562l41.926 73.71z" fill="#DC4955" p-id="15187"></path><path d="M795.464 320.532l108.698 102.368v-73.742l-108.698-102.368z" fill="#D82F3C" p-id="15188"></path><path d="M466.694 78.244L13.808 504.756A43.92 43.92 0 0 0 0 536.728c0 13.59 5.748 24.84 14.4 32.572 0 0 41.496-1.526 59.628-18.6L504.924 144.896a10.322 10.322 0 0 1 14.154 0l430.896 405.802c18.13 17.074 59.628 18.6 59.628 18.6 8.652-7.732 14.4-18.982 14.4-32.572a43.92 43.92 0 0 0-13.808-31.972L557.306 78.244c-25.45-23.968-65.162-23.968-90.612 0z" fill="#DC4955" p-id="15189"></path><path d="M504.922 107.158L14.4 569.3c15.856 14.168 41.496 16.474 59.628-0.6L504.924 162.896a10.322 10.322 0 0 1 14.154 0L949.974 568.7c18.13 17.074 43.772 14.768 59.628 0.6L519.078 107.158a10.32 10.32 0 0 0-14.156 0z" fill="#D82F3C" p-id="15190"></path><path d="M914.484 963.732h99.194a10.32 10.32 0 0 0 10.322-10.322v-26.838h-119.838v26.838a10.322 10.322 0 0 0 10.322 10.322zM688.444 963.732h99.194a10.322 10.322 0 0 0 10.322-10.322v-26.838h-119.838v26.838a10.32 10.32 0 0 0 10.322 10.322zM462.404 963.732h99.192a10.32 10.32 0 0 0 10.322-10.322v-26.838H452.08v26.838a10.324 10.324 0 0 0 10.324 10.322zM236.364 963.732h99.194a10.322 10.322 0 0 0 10.322-10.322v-26.838h-119.84v26.838a10.324 10.324 0 0 0 10.324 10.322z" fill="#D7A379" p-id="15191"></path><path d="M119.838 926.57v-141.964a10.32 10.32 0 0 0-3.292-7.558l-49.596-46.14a10.324 10.324 0 0 0-14.062 0l-49.596 46.14A10.324 10.324 0 0 0 0 784.606v141.964l59.92 18z" fill="#E2AE84" p-id="15192"></path><path d="M10.322 963.732h99.194a10.322 10.322 0 0 0 10.322-10.322v-26.838H0v26.838a10.322 10.322 0 0 0 10.322 10.322z" fill="#D7A379" p-id="15193"></path><path d="M448.048 674.914v25.226a15.514 15.514 0 0 0 31.028 0v-25.226a15.514 15.514 0 0 0-31.028 0z" fill="#BD6E45" p-id="15194"></path></svg>
\ No newline at end of file
<!--
* 主页
-->
<script setup lang="ts">
import MyPoems from '../page10/element/MyPoems.vue';
</script>
<template>
<my-poems />
</template>
<style lang="scss" scoped></style>
......@@ -14,24 +14,33 @@
<q-item :key="index" v-if="item.id === '1'">
<div class="q-gutter-sm full-width">
<q-btn
outline
unelevated
label="success"
color="positive"
:icon="ICON.success"
@click="onClick('success')"
/>
<q-btn
outline
unelevated
label="error"
color="negative"
:icon="ICON.error"
@click="onClick('error')"
/>
<q-btn
outline
unelevated
label="warn"
color="warning"
:icon="ICON.warn"
@click="onClick('warn')"
/>
<q-btn outline label="info" color="info" @click="onClick('info')" />
<q-btn
unelevated
label="info"
color="info"
:icon="ICON.info"
@click="onClick('info')"
/>
</div>
</q-item>
......@@ -237,7 +246,7 @@ function onClick(type: string) {
warn('警告');
break;
case 'info':
info('提示信息');
info('提示');
break;
default:
......
......@@ -11,7 +11,7 @@ const props = defineProps<{
const $q = useQuasar();
function delRow() {
const msg = `确定<strong>删除</strong>当前行<span class="text-red text-weight-bold">${props.params.data.name}</span>?`;
const msg = `确定<strong>删除</strong>当前行<span class="text-warning text-weight-bold">${props.params.data.name}</span>?`;
$q.dialog({
title: '<i class="bi bi-exclamation-circle text-warning"></i>&nbsp;提示',
message: msg,
......
......@@ -20,6 +20,9 @@ import AgGridDetailGrids from './element/AgGridDetailGrids.vue';
import AgGridTreeData from './element/AgGridTreeData.vue';
import AgGridTreeFileBrowser from './element/AgGridTreeFileBrowser.vue';
import AgGridCustomDateComponent from './element/AgGridCustomDateComponent.vue';
import AgGridSelection from './element/AgGridSelection.vue';
import AgGridCheckboxSelection from './element/AgGridCheckboxSelection.vue';
import AgGridGroupSelection from './element/AgGridGroupSelection.vue';
const listData = [
{
......@@ -66,10 +69,22 @@ const listData = [
title: 'Ag Grid 自定义日期组件',
name: 'ag-grid-custom-date-component',
},
{
title: 'Ag Grid 选择',
name: 'ag-grid-selection',
},
{
title: 'Ag Grid 复选框选择',
name: 'ag-grid-checkbox-selection',
},
{
title: 'Ag Grid 组选择',
name: 'ag-grid-group-selection',
},
];
const isShow = ref(true);
const elementName = ref('ag-grid-detail-grids');
const elementTitle = ref('Vue Data Grid: Master / Detail - Detail Grids');
const elementName = ref('ag-grid-group-selection');
const elementTitle = ref('Ag Grid 组选择');
function onclick(data: any) {
elementTitle.value = data.title;
......@@ -117,6 +132,13 @@ function goBack() {
<ag-grid-custom-date-component
v-if="elementName === 'ag-grid-custom-date-component'"
/>
<ag-grid-selection v-if="elementName === 'ag-grid-selection'" />
<ag-grid-checkbox-selection
v-if="elementName === 'ag-grid-checkbox-selection'"
/>
<ag-grid-group-selection
v-if="elementName === 'ag-grid-group-selection'"
/>
</div>
</div>
<div v-else>
......
<!--
* Ag Grid 复选框选择
* https://www.ag-grid.com/vue-data-grid/row-selection/#checkbox-selection
-->
<script setup lang="ts">
import { ref, reactive, onMounted, watch } from 'vue';
import { AgGridVue } from 'ag-grid-vue3';
import AG_GRID_LOCALE from 'src/config/ag-grid-locale';
const defaultColDef = {
flex: 1,
minWidth: 100,
suppressMenu: true, // 是否禁用标题行菜单
};
const gridApi = ref<any>(null);
const gridColumnApi = ref<any>(null);
const checkAllUsable = ref<any>(null);
const columnDefs = reactive([
{
field: 'athlete',
headerName: '运动员',
checkboxSelection: (params: any) => {
return params.data && params.data.year !== 2012;
},
showDisabledCheckboxes: true,
},
{ field: 'sport', headerName: '运动' },
{ field: 'year', maxWidth: 120, headerName: '年份' },
]);
const state = reactive({
rowData: [] as any,
selected: [],
});
watch(checkAllUsable, (val: any) => {
if (val === true) {
gridApi.value.forEachNode((node: any) => {
node.setSelected(true);
});
} else if (val === false) {
deselectRows();
}
});
onMounted(() => {
//
});
function getData() {
fetch('https://www.ag-grid.com/example-assets/small-olympic-winners.json')
.then((resp) => resp.json())
.then((data) => {
state.rowData = data;
console.log('state.rowData[0]', state.rowData[0]);
});
}
function onGridReady(params: any) {
gridApi.value = params.api;
gridColumnApi.value = params.columnApi;
getData();
}
function onFirstDataRendered(params: any) {
params.api.forEachNode((node: any) =>
node.setSelected(node.data && node.data.year == 2012)
);
}
function onSelectionChanged() {
const length1 = state.rowData.length;
const selectedRows = gridApi.value.getSelectedRows();
const length2 = selectedRows.length;
state.selected = selectedRows.map((item: any) => item.athlete);
if (length1 && length1 === length2) {
checkAllUsable.value = true;
} else if (length1 !== length2) {
checkAllUsable.value = null;
} else {
checkAllUsable.value = false;
}
}
// function isRowSelectable(params: any) {
// return !!params.data && params.data.year === 2012;
// }
function deselectRows() {
// gridApi.value.deselectAll();
gridApi.value.forEachNode((node: any) => {
let falg = false;
if (node.data && node.data.year == 2012) {
falg = true;
}
node.setSelected(falg);
});
}
</script>
<template>
<div class="box">
<div class="text">
<div>固定选中<q-chip square :ripple="false">年份=2012</q-chip>的行</div>
<q-checkbox v-model="checkAllUsable" label="选择全部可选内容" dense />
<span>已选择:{{ state.selected.join(',') }}</span>
</div>
<!--
rowSelection="multiple":多选,按住control键多选;【control+shift+鼠标点击】可选中多行
animateRows=true:启用行动画
:masterDetail="true" 启用展开的细节网格行
:isRowMaster="isRowMaster" 确定哪一个行该展开
rowSelection="single" single单选 multiple多选
-->
<div class="ag-table">
<ag-grid-vue
style="height: 550px"
class="ag-theme-alpine"
:animateRows="true"
:localeText="AG_GRID_LOCALE"
:defaultColDef="defaultColDef"
:columnDefs="columnDefs"
:rowData="state.rowData"
rowSelection="multiple"
:suppressRowClickSelection="true"
@grid-ready="onGridReady"
@first-data-rendered="onFirstDataRendered"
@selection-changed="onSelectionChanged"
>
</ag-grid-vue>
</div>
</div>
</template>
<style lang="scss" scoped>
.text {
padding: 10px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
row-gap: 10px;
}
.ag-table {
padding: 0 10px 10px 10px;
}
</style>
<!--
* Ag Grid 组选择
* https://www.ag-grid.com/vue-data-grid/row-selection/#group-selection
-->
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { AgGridVue } from 'ag-grid-vue3';
import AG_GRID_LOCALE from 'src/config/ag-grid-locale';
const defaultColDef = {
flex: 1,
minWidth: 100,
suppressMenu: true, // 是否禁用标题行菜单
};
const gridApi = ref<any>(null);
const gridColumnApi = ref<any>(null);
const autoGroupColumnDef = reactive({
headerName: '运动员',
field: 'athlete',
minWidth: 250,
sortable: true,
cellRenderer: 'agGroupCellRenderer',
cellRendererParams: {
checkbox: true,
},
});
const columnDefs = reactive([
{
field: 'year',
minWidth: 150,
rowGroup: true,
hide: true,
sortable: true,
headerName: '年份',
},
{
field: 'country',
rowGroup: true,
hide: true,
sortable: true,
headerName: '国家',
},
{ field: 'sport', headerName: '运动' },
{ field: 'gold', aggFunc: 'sum', headerName: '金牌' },
{ field: 'silver', aggFunc: 'sum', headerName: '银牌' },
{ field: 'bronze', aggFunc: 'sum', headerName: '铜牌' },
{
field: 'age',
minWidth: 120,
aggFunc: 'sum',
headerName: '年龄',
},
{ field: 'date', minWidth: 150, headerName: '日期' },
]);
const state = reactive({
rowData: [] as any,
});
onMounted(() => {
//
});
function getData() {
fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
.then((resp) => resp.json())
.then((data) => {
state.rowData = data;
console.log('state.rowData[0]', state.rowData[0]);
});
}
function onGridReady(params: any) {
gridApi.value = params.api;
gridColumnApi.value = params.columnApi;
getData();
}
function onFirstDataRendered() {
//
}
function onSelectionChanged() {
// const selectedNodes = gridApi.value.getSelectedNodes();
// console.log('selectedNodes', selectedNodes);
}
</script>
<template>
<div class="box">
<!--
rowSelection="multiple":多选,按住control键多选;【control+shift+鼠标点击】可选中多行
animateRows=true:启用行动画
:masterDetail="true" 启用展开的细节网格行
:isRowMaster="isRowMaster" 确定哪一个行该展开
rowSelection="single" single单选 multiple多选
:suppressContextMenu="true" 阻止显示右键单击时的上下文菜单
:suppressCellFocus="true" 阻止单元格聚焦
-->
<div class="ag-table">
<ag-grid-vue
style="height: 550px"
class="ag-theme-alpine"
:animateRows="true"
:localeText="AG_GRID_LOCALE"
:suppressContextMenu="true"
:suppressCellFocus="true"
:defaultColDef="defaultColDef"
:columnDefs="columnDefs"
:rowData="state.rowData"
:autoGroupColumnDef="autoGroupColumnDef"
:groupSelectsChildren="true"
rowSelection="multiple"
:suppressAggFuncInHeader="true"
:suppressRowClickSelection="true"
@grid-ready="onGridReady"
@first-data-rendered="onFirstDataRendered"
@selection-changed="onSelectionChanged"
>
</ag-grid-vue>
</div>
</div>
</template>
<style lang="scss" scoped>
.ag-table {
padding: 0 10px 10px 10px;
}
</style>
<!--
* AG-grid 选择
* https://www.ag-grid.com/vue-data-grid/selection-overview/
-->
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { AgGridVue } from 'ag-grid-vue3';
import AG_GRID_LOCALE from 'src/config/ag-grid-locale';
const defaultColDef = {
flex: 1,
minWidth: 100,
suppressMenu: true, // 是否禁用标题行菜单
};
const gridApi = ref<any>(null);
const gridColumnApi = ref<any>(null);
const columnDefs = reactive([
{ field: 'athlete', minWidth: 150, headerName: '运动员' },
{ field: 'age', maxWidth: 90, headerName: '年龄' },
{ field: 'country', minWidth: 150, headerName: '国家' },
{ field: 'year', maxWidth: 90, headerName: '年份' },
{ field: 'date', minWidth: 150, headerName: '日期' },
{ field: 'sport', minWidth: 150, headerName: '运动' },
{ field: 'gold', headerName: '金牌' },
{ field: 'silver', headerName: '银牌' },
{ field: 'bronze', headerName: '铜牌' },
{ field: 'total', headerName: '共计' },
]);
const selectionGroup = ref('single');
const rowSelectionOpt = reactive([
{
label: '单选',
value: 'single',
},
{
label: '多选',
value: 'multiple',
},
{
label: '单击多选',
value: 'both',
},
]);
const state = reactive({
rowData: [] as any,
selected: [],
});
const rowSelection = computed(() => {
let val = '';
switch (selectionGroup.value) {
case 'single':
val = 'single';
break;
case 'multiple':
val = 'multiple';
break;
default:
val = 'multiple';
break;
}
return val;
});
onMounted(() => {
//
});
function getData() {
fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
.then((resp) => resp.json())
.then((data) => {
state.rowData = data;
console.log('state.rowData[0]', state.rowData[0]);
});
}
function onGridReady(params: any) {
gridApi.value = params.api;
gridColumnApi.value = params.columnApi;
getData();
}
function onSelectionChanged() {
const selectedRows = gridApi.value.getSelectedRows();
state.selected = selectedRows.map((item: any) => item.athlete);
}
function deselectRows() {
gridApi.value.deselectAll();
}
</script>
<template>
<div class="box">
<div class="text">
<span>已选择:{{ state.selected.join(',') }}</span>
<q-option-group
dense
v-model="selectionGroup"
:options="rowSelectionOpt"
color="primary"
inline
/>
<q-btn
color="primary"
label="取消所有选择"
no-caps
@click="deselectRows"
/>
</div>
<!--
rowSelection="multiple":多选,按住control键多选;【control+shift+鼠标点击】可选中多行
animateRows=true:启用行动画
:masterDetail="true" 启用展开的细节网格行
:isRowMaster="isRowMaster" 确定哪一个行该展开
rowSelection="single" single单选 multiple多选
-->
<div class="ag-table">
<ag-grid-vue
style="height: 550px"
class="ag-theme-alpine"
:animateRows="true"
:pagination="true"
:paginationPageSize="10"
:localeText="AG_GRID_LOCALE"
:defaultColDef="defaultColDef"
:columnDefs="columnDefs"
:rowData="state.rowData"
:rowSelection="rowSelection"
:rowMultiSelectWithClick="selectionGroup === 'both'"
@grid-ready="onGridReady"
@selection-changed="onSelectionChanged"
>
</ag-grid-vue>
</div>
</div>
</template>
<style lang="scss" scoped>
.text {
padding: 10px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
row-gap: 10px;
}
.ag-table {
padding: 0 10px 10px 10px;
}
</style>
......@@ -12,6 +12,16 @@ const routes: RouteRecordRaw[] = [
component: () => import('pages/IndexPage.vue'),
redirect: '/page9',
children: [
{
path: 'home',
name: 'HOME',
component: () => import('../modules/home/PageHome.vue'),
meta: {
title: '主页',
permission: ['*'],
keepalive: false,
},
},
{
path: 'page1',
name: 'PAGE1',
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment