Commit 49f11459 authored by hucy's avatar hucy

fix:不重要的提交

parent e6cbaafd
<script setup>
import { useDialogPluginComponent } from 'quasar';
import ICON from 'src/config/icons';
defineProps({
// ...your custom props
text: {
type: String,
default: '',
},
// Color name for component from the Quasar Color Palette
color: {
type: String,
default: 'primary',
},
showActions: {
type: Boolean,
default: true,
},
title: {
type: String,
default: '提示',
},
icon: {
type: String,
default: ICON.info,
},
});
defineEmits([
// REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent()
...useDialogPluginComponent.emits,
]);
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
useDialogPluginComponent();
// dialogRef - Vue ref to be applied to QDialog
// onDialogHide - Function to be used as handler for @hide on QDialog
// onDialogOK - Function to call to settle dialog with "ok" outcome
// example: onDialogOK() - no payload
// example: onDialogOK({ /*...*/ }) - with payload
// onDialogCancel - Function to call to settle dialog with "cancel" outcome
// this is part of our example (so not required)
function onOKClick() {
// on OK, it is REQUIRED to
// call onDialogOK (with optional payload)
onDialogOK();
// or with payload: onDialogOK({ ... })
// ...and it will also hide the dialog automatically
}
</script>
<template>
<q-dialog ref="dialogRef" @hide="onDialogHide">
<q-card class="q-dialog-plugin">
<!--
...content
... use q-card-section for it?
-->
<q-card-section class="my-card-section">
<div class="text-h6">
<q-icon :name="icon" :color="color" />{{ title }}
</div>
</q-card-section>
<q-card-section
class="my-card-content"
:style="{ minHeight: showActions ? '40px' : '70px' }"
>
{{ text }}
</q-card-section>
<!-- buttons example -->
<q-card-actions align="right" v-if="showActions">
<q-btn :color="color" flat label="取消" @click="onDialogCancel" />
<q-btn :color="color" unelevated label="确定" @click="onOKClick" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped>
.q-dialog-plugin {
}
.my-card-section {
padding: 16px;
i {
font-size: 24px;
margin-right: 6px;
}
}
.my-card-content {
padding: 16px;
padding-top: 0;
}
</style>
import DialogLayout from './dialog-layout/DialogLayout.vue';
export { DialogLayout as ComDialogLayout };
import DialogTip from './dialog-tip/DialogTip.vue';
export { DialogLayout as ComDialogLayout, DialogTip as ComDialogTip };
export default {
DialogLayout,
DialogTip,
};
export default {
success: 'bi-check-circle-fill',
error: 'bi-exclamation-triangle-fill',
warn: 'bi-exclamation-circle-fill',
info: 'bi-info-circle-fill',
success: 'fa-solid fa-circle-check',
error: 'fa-solid fa-triangle-exclamation',
warn: 'fa-solid fa-circle-exclamation',
info: 'fa-solid fa-circle-info',
question: 'fa-solid fa-circle-question',
takeColor: 'fa-solid fa-palette', // 取色
reset: 'bi-arrow-counterclockwise', // 重置
refresh: 'bi-arrow-repeat', // 刷新
......
......@@ -2,8 +2,28 @@ export default [
{
title: '主页',
caption: null,
icon: 'home',
icon: 'fa-solid fa-house',
link: '/home',
active: false,
},
{
title: 'Ag Grid',
caption: null,
children: [
{
title: 'Ag Grid Selection',
caption: null,
icon: 'fa-solid fa-list-check',
link: '/ag-grid-selection',
active: false,
},
],
},
{
title: 'Components example',
caption: null,
icon: 'fa-regular fa-lightbulb',
link: '/components-example',
active: false,
},
];
@import 'ag-grid-community/styles/ag-grid.css'; // Core grid CSS, always needed
@import 'ag-grid-community/styles/ag-theme-material.css'; // Optional theme CSS
.ag-unselectable {
-webkit-user-select: auto;
user-select: auto;
}
// .ag-unselectable {
// -webkit-user-select: auto;
// user-select: auto;
// }
......@@ -13,12 +13,13 @@
v-model="defaultRouter"
inline-label
outside-arrows
switch-indicator
no-caps
shrink
class="my-tabs"
>
<q-tab
class="my-tab"
:class="['my-tab', { 'my-tab-hasicon': isShowCloseBtn }]"
v-for="page in tabsList"
:key="page.link"
:name="page.link"
......@@ -235,7 +236,6 @@ export default defineComponent({
.my-tab {
box-sizing: border-box;
background-color: $primary-4;
margin: 0 2px;
:deep(.q-tab__content) {
display: flex;
flex-direction: row;
......@@ -251,6 +251,10 @@ export default defineComponent({
}
}
}
.my-tab-hasicon {
padding-right: 0px;
padding-left: 24px;
}
.my-tabs {
:deep(.q-tab--active) {
......
......@@ -5,10 +5,10 @@
default-opened
:label="title"
:caption="caption"
switch-toggle-side
>
<q-item
clickable
class="my-essential--item"
active-class="bg-primary-bg-light"
v-for="item in children"
@click="expansionClick(item)"
......@@ -18,7 +18,7 @@
<q-item-section
v-if="item.icon"
avatar
style="min-width: 30px; padding-right: 0px"
class="my-essential-link--item-section"
>
<q-icon :name="item.icon" />
</q-item-section>
......@@ -36,13 +36,10 @@
clickable
@click="onClick"
:active="pageStore.activeRouter?.path === link ? true : false"
class="my-essential--item"
active-class="bg-primary-bg-light"
>
<q-item-section
v-if="icon"
avatar
style="min-width: 30px; padding-right: 0px"
>
<q-item-section v-if="icon" avatar class="my-essential-link--item-section">
<q-icon :name="icon" />
</q-item-section>
......@@ -112,3 +109,16 @@ export default defineComponent({
},
});
</script>
<style lang="scss" scoped>
.my-essential--item {
align-items: center;
}
.my-essential-link--item-section {
width: 24px !important;
height: 24px !important;
min-width: 24px !important;
max-width: 24px !important;
padding: 0 !important;
margin-right: 12px !important;
}
</style>
<!--
* @FileDescription: Ag Grid Selection
* @Date: 2023-08-07
* @LastEditTime: 2023-08-08
-->
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { AgGridVue } from 'ag-grid-vue3';
import type { GridOptions } from 'ag-grid-community';
import { cloneDeep } from 'src/common/utils';
import { useMessage } from 'src/common/hooks';
import { tableData } from './config';
const { warn } = useMessage();
const show = ref(true);
const state = reactive({
rows: [] as any[],
selectedRows: [] as any[],
});
// Ag Grid
// https://www.ag-grid.com/vue-data-grid/data-update-transactions/
const gridOptions: GridOptions<any> = reactive({
suppressContextMenu: true, // 阻止“右键单击”上下文菜单
suppressCellFocus: true, // 阻止单元格聚焦,这意味着键盘导航将对网格单元格禁用
rowSelection: 'single',
enableCellTextSelection: true, // 选择单元格中的文本
defaultColDef: {
suppressMenu: true, // 阻止此列标头菜单显示
flex: 1,
},
columnDefs: [
{
headerName: '',
field: '',
maxWidth: 50,
checkboxSelection: true,
},
{
headerName: '序号',
maxWidth: 80,
valueFormatter: (params: any) => {
return params.node?.rowIndex + 1;
},
},
{ headerName: '姓名', field: 'name' },
{ headerName: '年龄', field: 'age' },
],
rowData: [],
onGridReady,
onFirstDataRendered: (params) => {
// const nodesToSelect: any[] = [];
// params.api.forEachNode((node, index) => {
// if (node.data && index === 0) {
// nodesToSelect.push(node);
// }
// });
// params.api.setNodesSelected({ nodes: nodesToSelect, newValue: true });
const nodesToSelect: any[] = [];
for (const item of state.selectedRows) {
const idStr = item.id.toString();
const rowNode = params.api.getRowNode(idStr);
rowNode ? nodesToSelect.push(rowNode) : '';
}
// 默认选中第一条
if (nodesToSelect.length < 1 && state.rows.length > 0) {
const idStr = state.rows[0].id.toString();
const rowNode = params.api.getRowNode(idStr);
rowNode ? nodesToSelect.push(rowNode) : '';
}
params.api.setNodesSelected({ nodes: nodesToSelect, newValue: true });
},
getRowId: (params) => {
return String(params.data.id);
},
onSelectionChanged: (params) => {
state.selectedRows = params.api?.getSelectedRows();
// 已选择的复选框,点击取消选择时,继续选中
// const lastId = state.selectedRows[0]?.id;
// if (state.selectedRows.length === 0 && lastId) {
// const rowNode = params.api.getRowNode(String(lastId));
// rowNode ? rowNode.setSelected(true) : '';
// }
},
});
onMounted(() => {
//
});
function onGridReady() {
state.rows = tableData;
gridOptions.api?.setRowData(tableData);
}
function onUpdata() {
const data = cloneDeep(tableData);
data[0].name = '甄漂亮';
gridOptions.api?.setRowData(data);
state.selectedRows = gridOptions.api?.getSelectedRows() as any[];
}
function onDestroy() {
show.value = false;
state.rows = [];
}
function onRedraw() {
show.value = true;
}
function onGetRowData() {
const rowData: any[] = [];
gridOptions.api?.forEachNode(function (node) {
rowData.push(node.data);
});
state.rows = rowData;
console.table(rowData);
}
function addItem() {
const newData = {
id: Date.now(),
name: 'xxx',
age: 0,
};
const newItems = [newData];
gridOptions.api?.applyTransaction({
add: newItems,
});
}
function removeItem() {
const selectedDatas = gridOptions.api?.getSelectedRows();
if (selectedDatas && selectedDatas.length > 0) {
gridOptions.api?.applyTransaction({ remove: selectedDatas });
} else {
warn('请选择一条数据');
}
}
</script>
<template>
<div class="ag-grid-selection fit">
<div class="actions">
<div class="q-gutter-xs">
<q-btn color="primary" label="更新" unelevated @click="onUpdata" />
<q-btn color="primary" label="销毁" unelevated @click="onDestroy" />
<q-btn color="primary" label="重绘" unelevated @click="onRedraw" />
<q-btn color="primary" label="添加一条" unelevated @click="addItem" />
<q-btn
color="primary"
label="删除一条"
unelevated
@click="removeItem"
/>
<q-btn
color="primary"
label="Get Row Data"
unelevated
@click="onGetRowData"
/>
</div>
</div>
<div class="table-box">
<ag-grid-vue
v-if="show"
class="ag-theme-material"
style="width: 500px; height: 600px"
:grid-options="gridOptions"
>
</ag-grid-vue>
</div>
<div>
<div>已选择</div>
<div>{{ state.selectedRows }}</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.ag-grid-selection {
display: flex;
flex-direction: column;
.table-box {
//
}
}
</style>
export const tableData = [
{
id: 1,
name: '张三',
age: 18,
},
{
id: 2,
name: '李四',
age: 20,
},
{
id: 3,
name: '王五',
age: 34,
},
{
id: 4,
name: '高力代',
age: 45,
},
];
export default [
{
path: 'ag-grid-selection',
name: 'AG_GRID_SELECTION',
component: () => import('./AgGridSelection.vue'),
meta: {
title: 'Ag Grid Selection',
permission: ['*'],
keepalive: true,
},
},
];
<!--
* @FileDescription: Components Example
* @Date: 2023-08-11
* @LastEditTime: 2023-08-11
-->
<script setup lang="ts">
import { ref } from 'vue';
import { list } from './config';
// elements
import DialogTip from './elements/DialogTip.vue';
const show = ref(false);
const name = ref('');
const title = ref('');
const draggingFab = ref(false);
const btnPos = ref([18, 18]);
function clickItem(data: any) {
name.value = data.name;
title.value = data.title;
btnPos.value = [18, 18];
show.value = true;
}
function goBack() {
show.value = false;
name.value = '';
title.value = '';
}
function moveFab(ev: any) {
draggingFab.value = ev.isFirst !== true && ev.isFinal !== true;
btnPos.value = [btnPos.value[0] - ev.delta.x, btnPos.value[1] - ev.delta.y];
}
</script>
<template>
<div>
<div v-if="show">
<q-page-sticky position="bottom-right" :offset="btnPos" class="z-top">
<q-btn
:disable="draggingFab"
v-touch-pan.prevent.mouse="moveFab"
round
color="white"
text-color="primary"
icon="bi-arrow-left"
title="返回,按住可拖动"
@click="goBack"
/>
</q-page-sticky>
<DialogTip v-if="name === 'dialog_tip'" />
</div>
<div v-else class="q-pa-sm q-gutter-sm">
<q-list dense>
<q-item
clickable
active
v-for="(item, index) in list"
:key="index"
@click="clickItem(item)"
>
<q-item-section>
<q-item-label>{{ item.title }}</q-item-label>
<q-item-label caption v-if="item.remark">
{{ item.remark }}
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</div>
</div>
</template>
<style lang="scss" scoped></style>
export const list = [
{
title: 'Dialog Tip',
name: 'dialog_tip',
remark: null,
},
];
<!--
* @FileDescription: Dialog Tip
* @Date: 2023-08-11
* @LastEditTime: 2023-08-11
-->
<script setup lang="ts">
// import { reactive } from 'vue';
import { useQuasar } from 'quasar';
import { ComDialogTip } from 'src/components';
import ICON from 'src/config/icons';
const $q = useQuasar();
function onClike(name: string) {
$q.dialog({
component: ComDialogTip,
componentProps: {
persistent: true,
text: '这是一条提示信息',
// Color name for component from the Quasar Color Palette
color: name || 'primary',
icon: ICON.question,
// title: '标题',
// showActions: false,
// ...more..props...
},
}).onOk(() => {
//
});
// .onCancel(() => {
// console.log('Cancel');
// })
// .onDismiss(() => {
// console.log('Called on OK or Cancel');
// });
}
</script>
<template>
<div class="q-pa-md">
<div class="q-gutter-xs">
<q-btn color="primary" label="Primary" @click="onClike('primary')" />
<q-btn
color="secondary"
label="Secondary"
@click="onClike('secondary')"
/>
<q-btn color="amber" label="Amber" @click="onClike('amber')" />
<q-btn color="brown-5" label="Brown 5" @click="onClike('brown-5')" />
</div>
</div>
</template>
<style lang="scss" scoped></style>
export default [
{
path: 'components-example',
name: 'COMPONENTS_EXAMPLE',
component: () => import('./ComponentsExample.vue'),
meta: {
title: 'Components example',
permission: ['*'],
keepalive: true,
},
},
];
<!--
* @FileDescription: 主页
* @Date: 2023-08-03
* @LastEditTime: 2023-08-04
* @LastEditTime: 2023-08-07
-->
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { AgGridVue } from 'ag-grid-vue3';
import type { GridOptions } from 'ag-grid-community';
import type { GridOptions, GetRowIdParams } from 'ag-grid-community';
import { sportEnums } from './config';
import CountryCellRender from './elements/CountryCellRender.vue';
......@@ -62,6 +62,10 @@ const gridOptions: GridOptions<any> = reactive({
],
rowData: [],
onGridReady,
// Server-Side Row Selection requires Row ID's to be supplied to grid.
// https://www.ag-grid.com/vue-data-grid/server-side-model-configuration/#providing-row-ids
getRowId,
});
const count = ref(0);
......@@ -80,11 +84,24 @@ function onFetch() {
fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
.then((resp) => resp.json())
.then((data: any[]) => {
if (state.sport) {
data = data.filter((item) => item.sport == state.sport);
// if (state.sport) {
// data = data.filter((item) => item.sport == state.sport);
// }
const newList: any[] = [];
let index = 1;
for (const item of data) {
item.id = index;
if (state.sport) {
item.sport == state.sport ? newList.push(item) : '';
} else {
newList.push(item);
}
index++;
}
updateData(data);
count.value = data.length;
updateData(newList);
count.value = newList.length;
});
}
function updateData(data: any) {
......@@ -127,6 +144,9 @@ function createServerSideDatasource(server: any) {
},
};
}
function getRowId(params: GetRowIdParams) {
return 'leaf-' + params.data.id;
}
function onSearch() {
onFetch();
......@@ -159,7 +179,7 @@ function onReset() {
</div>
<q-space />
<div class="count-text">
共有 <q-chip square :clickable="false">{{ count }}</q-chip
共有 <q-chip square :ripple="false">{{ count }}</q-chip
>条数据
</div>
</div>
......
import { RouteRecordRaw } from 'vue-router';
import HOME from '../modules/home/router';
import AG_GRID_SELECTION from '../modules/ag-grid-selection/router';
import COMPONENTS_EXAMPLE from '../modules/components-example/router';
const routes: RouteRecordRaw[] = [
{
......@@ -11,7 +13,7 @@ const routes: RouteRecordRaw[] = [
name: 'LaoutIndexPage',
component: () => import('pages/IndexPage.vue'),
redirect: '/home',
children: [...HOME],
children: [...HOME, ...AG_GRID_SELECTION, ...COMPONENTS_EXAMPLE],
},
],
},
......
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