Skip to content

基础表格

标题分类最后更新时间发布操作
No Data
1
BasicTable.vue
<script setup lang="ts">
import type { DataTableColumns } from 'naive-ui'
import { NButton, NSwitch } from 'naive-ui'
import dayjs from 'dayjs'
import api from './api'

interface RowData {
  id: number
  title: string
  category: string
  description: string
  author: string
  createDate: string
  updateDate: string
  isPublish: boolean
  publishing: boolean
}
const columns: DataTableColumns<RowData> = [
  { type: 'selection', width: 60 },
  { title: '标题', key: 'title', width: 160 },
  { title: '分类', key: 'category', width: 100 },
  {
    title: '最后更新时间',
    key: 'updateDate',
    width: 180,
    render(row) {
      return h('span', dayjs().format('YYYY-MM-DD HH:mm:ss'))
    },
  },
  {
    title: '发布',
    key: 'isPublish',
    width: 100,
    align: 'center',
    render(row) {
      return h(NSwitch, {
        size: 'small',
        rubberBand: false,
        value: row.isPublish,
        loading: row.publishing,
        onUpdateValue: () => handlePublish(row),
      })
    },
  },
  {
    title: '操作',
    key: 'actions',
    align: 'center',
    width: 100,
    render(row) {
      return h(
        NButton,
        {
          size: 'small',
          type: 'error',
          onClick: () => handleDelete(row),
        },
        { default: () => '删除' }
      )
    },
  },
]
const pagination = reactive({ pageSize: 10 })
const loading = ref<boolean>(false)
const tableData = ref([])

initTableData()

async function initTableData() {
  loading.value = true
  try {
    const res = await api.getPosts()
    tableData.value = res.data
  } catch (error) {
    console.error(error)
    tableData.value = []
  }

  loading.value = false
}

function handlePublish(row: RowData) {
  row.publishing = true
  setTimeout(() => {
    row.isPublish = !row.isPublish
    row.publishing = false
  }, 1000)
}
function handleDelete(row: RowData) {
  if (!row.id) return
}
</script>

<template>
  <n-data-table
    :columns="columns"
    :row-key="(row:RowData) => row.id"
    :data="tableData"
    :pagination="pagination"
    :single-line="false"
    :loading="loading"
  />
</template>
api.ts
const posts = [
  {
    id: 36,
    title: '使用纯css优雅配置移动端rem布局',
    category: '移动端,Css',
    description: '通常配置rem布局会使用js进行处理,比如750的设计稿会这样...',
    content: '通常配置rem布局会使用js进行处理,比如750的设计稿会这样',
    isPublish: true,
    createDate: '2021-11-04T04:03:36.000Z',
    updateDate: '2021-11-04T04:03:36.000Z',
  },
  {
    id: 35,
    title: 'Vue2&Vue3项目风格指南',
    category: 'Vue',
    description: '总结的Vue2和Vue3的项目风格',
    content: '### 1. 命名风格\n\n> 文件夹如果是由多个单词组成,应该始终是横线连接 ',
    isPublish: false,
    createDate: '2021-10-25T08:57:47.000Z',
    updateDate: '2022-02-28T04:02:39.000Z',
  },
  {
    id: 28,
    title: '如何优雅的给图片添加水印',
    category: 'JavaScript',
    description: '优雅的给图片添加水印',
    content: '我之前写过一篇文章记录了一次上传图片的优化史',
    isPublish: false,
    createDate: '2021-06-24T18:46:19.000Z',
    updateDate: '2021-09-23T07:51:22.000Z',
  },

  {
    id: 26,
    title: '前端缓存的理解',
    category: 'Http',
    description: '谈谈前端缓存的理解',
    content: '> 背景\n\n公司有个vue-cli3移动端web项目发版更新后发现部分用户手机在钉钉内置浏览器打开出现了缓存',
    isPublish: true,
    createDate: '2021-06-10T18:51:19.000Z',
    updateDate: '2021-09-17T09:33:24.000Z',
  },
  {
    id: 18,
    title: 'Promise的五个静态方法',
    category: 'JavaScript',
    description: '简单介绍下在 Promise 类中,有5 种静态方法及它们的使用场景',
    content: '## 1. Promise.all\n\n并行执行多个 promise,并等待所有 promise 都准备就绪。再对它们进行处理。',
    isPublish: true,
    createDate: '2021-02-22T22:37:06.000Z',
    updateDate: '2021-09-17T09:33:24.000Z',
  },
]

export default {
  getPosts(): any {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({
          code: 0,
          message: 'ok',
          data: posts,
        })
      }, 1000)
    })
  },
}