wip: crud table

This commit is contained in:
张传龙 2022-08-31 10:16:38 +08:00
parent af983d16b9
commit 9ea8ffd7fd
7 changed files with 168 additions and 18 deletions

View 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>

View 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>

View 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>

View 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>

View File

@ -0,0 +1,5 @@
const ACTIONS = {
view: '查看',
edit: '编辑',
add: '新增',
}

View File

@ -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) {

View File

@ -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,
{ {