wip: crud table
This commit is contained in:
parent
af983d16b9
commit
9ea8ffd7fd
12
src/components/query-bar/QueryBar.vue
Normal file
12
src/components/query-bar/QueryBar.vue
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<div min-h-60 p-15 flex items-start justify-between b-1 bc-ccc rounded-8 bg="#fafafc">
|
||||||
|
<n-space wrap :size="[35, 15]">
|
||||||
|
<slot />
|
||||||
|
</n-space>
|
||||||
|
|
||||||
|
<div flex-shrink-0>
|
||||||
|
<n-button secondary type="primary">重置</n-button>
|
||||||
|
<n-button ml-20 type="primary">搜索</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
29
src/components/query-bar/QueryBarItem.vue
Normal file
29
src/components/query-bar/QueryBarItem.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<div flex items-center>
|
||||||
|
<label v-if="!isNullOrWhitespace(label)" w-80 flex-shrink-0 :style="{ width: labelWidth + 'px' }">
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
<div :style="{ width: contentWidth + 'px' }" flex-shrink-0>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { isNullOrWhitespace } from '@/utils/is'
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 80,
|
||||||
|
},
|
||||||
|
contentWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 220,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
44
src/components/table/CrudModal.vue
Normal file
44
src/components/table/CrudModal.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<n-modal v-model:show="show" :style="{ width }" preset="card" :title="title" size="huge" :bordered="false">
|
||||||
|
<slot />
|
||||||
|
<template v-if="showFooter" #footer>
|
||||||
|
<footer flex justify-end>
|
||||||
|
<slot name="footer">
|
||||||
|
<n-button @click="show = false">取消</n-button>
|
||||||
|
<n-button ml-20 type="primary" @click="emit('onSave')">保存</n-button>
|
||||||
|
</slot>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
</n-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
default: '600px',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
showFooter: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:visible', 'onSave'])
|
||||||
|
const show = computed({
|
||||||
|
get() {
|
||||||
|
return props.visible
|
||||||
|
},
|
||||||
|
set(v) {
|
||||||
|
emit('update:visible', v)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
16
src/components/table/CrudTable.vue
Normal file
16
src/components/table/CrudTable.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<QueryBar v-if="$slots.queryBar" mb-30>
|
||||||
|
<slot name="queryBar" />
|
||||||
|
</QueryBar>
|
||||||
|
<slot />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const loading = ref(false)
|
||||||
|
const tableData = ref([])
|
||||||
|
const showModal = ref(true)
|
||||||
|
const segmented = {
|
||||||
|
content: 'soft',
|
||||||
|
footer: 'soft',
|
||||||
|
}
|
||||||
|
</script>
|
5
src/composables/useCRUD.js
Normal file
5
src/composables/useCRUD.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const ACTIONS = {
|
||||||
|
view: '查看',
|
||||||
|
edit: '编辑',
|
||||||
|
add: '新增',
|
||||||
|
}
|
@ -1,24 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<CommonPage show-footer title="文章">
|
<CommonPage show-footer title="文章">
|
||||||
<n-data-table
|
<template #action>
|
||||||
mt-20
|
<n-button type="primary" @click="modalVisible = true">
|
||||||
:loading="loading"
|
<TheIcon icon="material-symbols:add" :size="18" class="mr-5" /> 新建文章
|
||||||
:scroll-x="1600"
|
</n-button>
|
||||||
:data="tableData"
|
</template>
|
||||||
:columns="columns"
|
|
||||||
:pagination="pagination"
|
<CrudTable>
|
||||||
:row-key="(row) => row.id"
|
<template #queryBar>
|
||||||
@update:checked-row-keys="handleCheck"
|
<QueryBarItem label="标题" :label-width="50">
|
||||||
/>
|
<n-input v-model:value="queryForm.title" type="text" placeholder="请输入标题" />
|
||||||
|
</QueryBarItem>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<n-data-table
|
||||||
|
:loading="loading"
|
||||||
|
:scroll-x="1600"
|
||||||
|
:data="tableData.filter((item) => item.title.includes(queryForm.title))"
|
||||||
|
:columns="columns"
|
||||||
|
:pagination="pagination"
|
||||||
|
:row-key="(row) => row.id"
|
||||||
|
@update:checked-row-keys="handleCheck"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 新增/编辑/查看 -->
|
||||||
|
<CrudModal v-model:visible="modalVisible" :title="modalTitle" @on-save="handleSave"> 内容 </CrudModal>
|
||||||
|
</CrudTable>
|
||||||
</CommonPage>
|
</CommonPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { usePostTable } from './usePostTable'
|
import { usePostTable } from './usePostTable'
|
||||||
|
|
||||||
const router = useRouter()
|
const queryForm = reactive({
|
||||||
|
title: '',
|
||||||
|
})
|
||||||
|
const modalVisible = ref(false)
|
||||||
|
const modalTitle = ref('新增文章')
|
||||||
|
|
||||||
const pagination = ref({ pageSize: 10 })
|
const pagination = reactive({ pageSize: 10 })
|
||||||
const { loading, columns, tableData, initColumns, initTableData } = usePostTable()
|
const { loading, columns, tableData, initColumns, initTableData } = usePostTable()
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
@ -26,8 +46,8 @@ onBeforeMount(() => {
|
|||||||
initTableData()
|
initTableData()
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleCreate() {
|
function handleSave() {
|
||||||
router.push('/example/table/post-create')
|
modalVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCheck(rowKeys) {
|
function handleCheck(rowKeys) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
import { NButton, NSwitch } from 'naive-ui'
|
import { NButton, NSwitch } from 'naive-ui'
|
||||||
import { formatDateTime } from '@/utils'
|
import { formatDateTime } from '@/utils'
|
||||||
import api from './api'
|
|
||||||
import { renderIcon } from '@/utils/icon'
|
import { renderIcon } from '@/utils/icon'
|
||||||
|
import api from './api'
|
||||||
|
|
||||||
export const usePostTable = () => {
|
export const usePostTable = () => {
|
||||||
// refs
|
// refs
|
||||||
@ -31,6 +31,21 @@ export const usePostTable = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleEdit(row) {
|
||||||
|
if (row && row.id) {
|
||||||
|
$dialog.confirm({
|
||||||
|
content: '确定删除?',
|
||||||
|
confirm() {
|
||||||
|
$message.success('删除成功')
|
||||||
|
initTableData()
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
$message.success('已取消')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleRecommend(row) {
|
async function handleRecommend(row) {
|
||||||
if (row && row.id) {
|
if (row && row.id) {
|
||||||
row.recommending = true
|
row.recommending = true
|
||||||
@ -84,7 +99,7 @@ export const usePostTable = () => {
|
|||||||
{
|
{
|
||||||
title: '推荐',
|
title: '推荐',
|
||||||
key: 'isRecommend',
|
key: 'isRecommend',
|
||||||
width: 100,
|
width: 120,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
render(row) {
|
render(row) {
|
||||||
@ -100,7 +115,7 @@ export const usePostTable = () => {
|
|||||||
{
|
{
|
||||||
title: '发布',
|
title: '发布',
|
||||||
key: 'isPublish',
|
key: 'isPublish',
|
||||||
width: 100,
|
width: 120,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
render(row) {
|
render(row) {
|
||||||
@ -116,11 +131,20 @@ export const usePostTable = () => {
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
width: 120,
|
width: 200,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
render(row) {
|
render(row) {
|
||||||
return [
|
return [
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
size: 'small',
|
||||||
|
type: 'primary',
|
||||||
|
onClick: () => handleEdit(row),
|
||||||
|
},
|
||||||
|
{ default: () => '编辑', icon: renderIcon('material-symbols:edit-outline', { size: 14 }) }
|
||||||
|
),
|
||||||
h(
|
h(
|
||||||
NButton,
|
NButton,
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user