vue3 + tsx 表格 Action 单独封装组件用法

news2024/11/15 15:52:04
前言

先上图看右侧列 action 的 UI 效果:

正常来说,如果一个表格的附带 action 操作,我们一般会放在最右侧的列里面实现,这个时候有些UI 框架支持在 SFC 模板里面定义额外的 solt,当然如果不支持,更通用的做法是通过 vue 的 h 函数来实现,纯粹用 js 或 ts 组装组件方式实现,这种方式很灵活,但有一个弊端,当定义的组件很多的时候,比如上图有4 个Button,还得定义按钮样式和点击事件,代码就显的非常乱。

更为优雅的做法是,把这一小块的功能给单独定义成一个 vue 组件,可以用 SFC 也可以用 JSX/TSX 实现,然后事件通过回调完成,代码就显得非常整洁了。

定义 Action 组件

这里用 tsx 实现:

import { defineComponent, PropType, toRefs } from 'vue'
import { NSpace, NTooltip, NButton, NIcon, NPopconfirm } from 'naive-ui'
import {AreaChartOutlined, DeleteOutlined, EditOutlined,
PlayCircleOutlined,PauseCircleOutlined,RedoOutlined,AlignCenterOutlined} from "@vicons/antd";
import {SolrListActionModel} from "@/service/middleware/types";

const props = {
    row: {
        type: SolrListActionModel as PropType<SolrListActionModel>
    }
}

export default defineComponent({
    name: 'SolrTableAction',
    props,
    emits: [
        'start',
        'stop',
        'restart',
        'showLog',
    ],
    setup(props, ctx) {

        const handleStartAction = () => {
            ctx.emit('start')
        }
        const handleStopAction = () => {
            ctx.emit('stop')
        }
        const handleRestartAction = () => {
            ctx.emit('restart')
        }
        const handleShowLogAction = () => {
            ctx.emit('showLog')
        }

        return {
            handleStartAction,
            handleStopAction,
            handleRestartAction,
            handleShowLogAction,
            ...toRefs(props)
        }
    },
    render() {
        return (
            <NSpace>
                {this.row?.start ? <NTooltip trigger={'hover'}>
                    {{
                        default: () => "启动",
                        trigger: () => (
                            <NButton
                                size='small'
                                type='info'
                                tag='div'
                                circle
                                onClick={this.handleStartAction}
                                class='btn-edit'
                            >
                                <NIcon>
                                    <PlayCircleOutlined></PlayCircleOutlined>
                                </NIcon>
                            </NButton>
                        )
                    }}
                </NTooltip>
                    :""
                }
                {
                   this.row?.stop?<NTooltip trigger={'hover'}>
                        {{
                            default: () => "停止",
                            trigger: () => (
                                <NButton
                                    size='small'
                                    type='info'
                                    tag='div'
                                    circle
                                    onClick={this.handleStopAction}
                                    class='btn-edit'
                                >
                                    <NIcon>
                                        <PauseCircleOutlined></PauseCircleOutlined>
                                    </NIcon>
                                </NButton>
                            )
                        }}
                    </NTooltip>:
                       ""
                }
                {
                    this.row?.restart?<NTooltip trigger={'hover'}>
                            {{
                                default: () => "重启",
                                trigger: () => (
                                    <NButton
                                        size='small'
                                        type='info'
                                        tag='div'
                                        circle
                                        onClick={this.handleRestartAction}
                                        class='btn-edit'
                                    >
                                        <NIcon>
                                            <RedoOutlined></RedoOutlined>
                                        </NIcon>
                                    </NButton>
                                )
                            }}
                        </NTooltip>:
                        ""
                }
                {
                    this.row?.showLog?<NTooltip trigger={'hover'}>
                            {{
                                default: () => "日志",
                                trigger: () => (
                                    <NButton
                                        size='small'
                                        type='info'
                                        tag='div'
                                        circle
                                        onClick={this.handleShowLogAction}
                                        class='btn-edit'
                                    >
                                        <NIcon>
                                            <AlignCenterOutlined></AlignCenterOutlined>
                                        </NIcon>
                                    </NButton>
                                )
                            }}
                        </NTooltip>:
                        ""
                }
                {this.$slots.extraAction?.()}
            </NSpace>
        )
    }
})
在 Table 列里面引用

定义好之后,在 table 里面引用就非常简单了,只需要把 props 属性传递一下,然后定义回调处理事件即可:

        const columns = [
            {
                title: '服务名',
                key: 'server_name',
                align: 'center'
            },
            {
                title: '运行状态',
                key: 'process_state',
                align: 'center'
            },
            {
                title: '主机IP',
                key: 'process_ip',
                align: 'center'
            },
            {
                title: '启动信息',
                key: 'process_description',
                align: 'center'
            },
            {
                title: '操作',
                key: 'operation',
              //列宽自适应
                ...COLUMN_WIDTH_CONFIG['operation'](4),
                align: 'center',
                render: (row: SolrList)=>{
                    let model=new SolrListActionModel(row)
                   return  h(SolrTableAction, {
                        row: model,
                        onStart: () => {

                        },
                        onStop:()=>{

                        },
                       onRestart:()=>{

                       },
                       onShowLog:()=>{

                       }
                    })


                }
            }
        ] as TableColumns<any>
列宽自适应工具类

这个是为了该列的宽度,根据实际情况重新分布:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { isNumber, sumBy } from 'lodash'
import type {
  TableColumns,
  CommonColumnInfo
} from 'naive-ui/es/data-table/src/interface'

export const COLUMN_WIDTH_CONFIG = {
  selection: {
    width: 50
  },
  index: {
    width: 50
  },
  linkName: {
    width: 200
  },
  linkEllipsis: {
    style: 'max-width: 180px;line-height: 1.5'
  },
  name: {
    width: 200,
    ellipsis: {
      tooltip: true
    }
  },
  state: {
    width: 120
  },
  type: {
    width: 130
  },
  version: {
    width: 80
  },
  time: {
    width: 180
  },
  timeZone: {
    width: 220
  },
  operation: (number: number): CommonColumnInfo => ({
    fixed: 'right',
    width: Math.max(30 * number + 12 * (number - 1) + 24, 100)
  }),
  userName: {
    width: 120,
    ellipsis: {
      tooltip: true
    }
  },
  ruleType: {
    width: 120
  },
  note: {
    width: 180,
    ellipsis: {
      tooltip: true
    }
  },
  dryRun: {
    width: 140
  },
  times: {
    width: 120
  },
  duration: {
    width: 120
  },
  yesOrNo: {
    width: 100,
    ellipsis: {
      tooltip: true
    }
  },
  size: {
    width: 100
  },
  tag: {
    width: 160
  },
  copy: {
    width: 50
  }
}

export const calculateTableWidth = (columns: TableColumns) =>
  sumBy(columns, (column) => (isNumber(column.width) ? column.width : 0))

export const DefaultTableWidth = 1800
总结

通用这种单独定义组件的方式,大大提高了我们代码的可读性,并且后续这个组件可以单独扩展和改变样式而不影响主列表页的迭代,最后我们要注意给 h 组件的传递 props 的方式,直接使用 props name:value 的形式即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1914698.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

医疗器械网络安全 | 漏洞扫描、渗透测试没有发现问题,是否说明我的设备是安全的?

尽管漏洞扫描、模糊测试和渗透测试在评估系统安全性方面是非常重要和有效的工具&#xff0c;但即使这些测试没有发现任何问题&#xff0c;也不能完全保证您的医疗器械是绝对安全的。这是因为安全性的评估是一个多维度、复杂且持续的过程&#xff0c;涉及多个方面和因素。以下是…

7.10号小项目部分说明

总体说明 糖锅小助手 我这次主要对上次糖锅小助手界面添加了一个侧边栏&#xff08;侧边输入框放置了三个按钮&#xff0c;可以跳转到其他ai聊天界面&#xff0c;还可以退出聊天界面回到登录界面&#xff09;和一个日期输入框&#xff08;日期输入框获取时间&#xff0c;根据时…

史上最齐全电动弃流装置(弃流控制柜/流量式雨水弃流装置)这里都有,井座式、304不锈钢材质

电动弃流装置组成部分有&#xff1a;PLC控制柜、雨量传感器/电磁流量计、弃流装置 进出水管可以定制不同接口&#xff0c;可以适用于连接波纹管、PVC管 电动弃流装置的工作原理如下&#xff1a; 首先&#xff0c;雨量传感器或电磁流量计实时监测降雨量或水流流量等相关数据&…

TCP 握手数据流

这张图详细描述了 TCP 握手过程中&#xff0c;从客户端发送 SYN 包到服务器最终建立连接的整个数据流转过程&#xff0c;包括网卡、内核、进程中的各个环节。下面对每个步骤进行详细解释&#xff1a; 客户端到服务器的初始连接请求 客户端发送 SYN 包&#xff1a; 客户端发起…

AI降痕工具:一键去除论文中的AI代写痕迹

在这个充满创意和创新的时代&#xff0c;AI已经渗透到我们生活的方方面面。然而&#xff0c;随着AI的飞速发展&#xff0c;AI的痕迹在论文创作中愈发明显。 这不禁让人思考&#xff0c;如何让论文回归纯粹&#xff0c;展现人类独有的思考和见解。“论文去AI痕迹”不仅是对学术…

vue3-openlayers WebGL加载地图(栅格切片、矢量切片)

本篇介绍一下使用vue3-openlayers WebGL加载地图&#xff08;栅格切片、矢量切片&#xff09; 1 需求 vue3-openlayers WebGL加载地图&#xff08;栅格切片、矢量切片&#xff09; 2 分析 栅格切片使用ol-webgl-tile-layer 矢量切片使用ol-vector-tile-layer&#xff08;默…

海外视频媒体发布/发稿:如何在国外媒体以视频的形式宣发

1. 背景介绍 在如今数字化时代&#xff0c;每个国家都拥有着各自的视频媒体平台&#xff0c;而主流媒体也都纷纷加入了视频发布的行列。视频媒体的宣发形式主要包括油管Youtube等视频分享平台&#xff0c;以及图文配合的发布方式。通过在视频中夹带链接&#xff0c;媒体可以以…

服务器安全运维方案介绍

随着信息技术的飞速发展&#xff0c;服务器已成为企业信息化建设的核心基础设施。然而&#xff0c;服务器安全运维问题也日益凸显&#xff0c;如何保障服务器的稳定运行和数据安全&#xff0c;已成为企业面临的重要挑战。本文旨在介绍一套全面的服务器安全运维方案&#xff0c;…

『C + ⒈』‘\‘

&#x1f942;在反斜杠(\)有⒉种最常用的功能如下所示&#x1f44b; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main(void) {int a 10;int b 20;int c 30;if (a 10 &&\b 20 &&\c 30){printf("Your print\n");}else{prin…

【leetcode刷题笔记】02.复写零

题目&#xff1a; 思路&#xff1a; 代码实现 class Solution { public:void duplicateZeros(vector<int>& arr) {//1.模拟异地操作int prev0,cur0;int lenarr.size();while(cur<len){//arr[prev]不是0就都走一步if(arr[prev]!0){prev;cur;}//arr[prev]是0就pre…

FlutterFlame游戏实践#15 | 生命游戏 - 演绎启动

theme: cyanosis 本文为稀土掘金技术社区首发签约文章&#xff0c;30天内禁止转载&#xff0c;30天后未获授权禁止转载&#xff0c;侵权必究&#xff01; Flutter\&Flame 游戏开发系列前言: 该系列是 [张风捷特烈] 的 Flame 游戏开发教程。Flutter 作为 全平台 的 原生级 渲…

78000A 信号分析软件

思仪(Ceyear) 78000A 信号分析软件 78000A 信号分析软件是一款能够在电脑上运行的应用软件&#xff0c;预留了开放式的 SCPI 控制指令&#xff0c;可以远程控制信号/频谱分析仪采集数据&#xff0c;也可以回放仿真数据或者采集的历史数据文件&#xff0c;执行通用频谱测量、矢…

Windows 下安装 Memcached

Memcached 安装包下载 官网上并未提供 Memcached 的 Windows 平台安装包。 我们可以使用以下链接来下载&#xff0c;你需要根据自己的系统平台及需要的版本号点击对应的链接下载即可&#xff1a; 32位系统 1.2.5版本&#xff1a;http://static.jyshare.com/download/memcache…

(Windows环境)FFMPEG编译,包含编译x264以及x265

本文使用 MSYS2 来编译 ffmpeg 一、安装MSYS2 MSYS2 是 Windows 下的一组编译套件&#xff0c;它可以在 Windows 系统中模拟 Linux 下的编译环境&#xff0c;如使用 shell 运行命令、使用 pacman 安装软件包、使用 gcc (MinGW) 编译代码等。 MSYS2 的安装也非常省心&#x…

视频共享交换平台LntonCVS视频监控平台智慧加油站安全管理方案

加油站作为危化品行业的一部分&#xff0c;日常的加油和卸油作业安全至关重要。目前国内加油站的管理主要依赖于人为管控、监控摄像头和人工巡检&#xff0c;这些方法存在效率低下和反应滞后的问题。为了有效应对安全风险&#xff0c;急需引入人工智能、物联网和大数据技术&…

Android14系统应用统一裁剪方案

Android14系统应用统一裁剪方案 背景 当前移除集成到系统里的应用,一般都是根据应用名,到各个mk文件里逐个在PRODUCT_PACKAGES中删除;这种方法,耗时而且不易管理集成到系统里的应用;需要有一个统一管理删除不需要应用的方案。 方案 参考PRODUCT_PACKAGES变量,添加PRO…

NVIDIA良心给显卡免费升级,只为挨更多的骂

起猛了&#xff0c;还真的以为 NVIDIA 良心发现了。 众所周知&#xff0c;英伟达对于咱们普通游戏玩家向来不屑一顾。只因为游戏业务在 NVIDIA 收入中占比较少。 在最新的 40 系显卡 RTX 4070 Ti Super 显卡中&#xff0c;NVIDIA悄悄给它来了一次核心「升级」&#xff0c;将原…

开发问卷微信小程序:从零到部署

开发问卷小程序&#xff1a;从零到部署 引言 微信小程序作为一种轻量级的应用形式&#xff0c;以其便捷性和广泛的用户基础&#xff0c;成为开发者的新宠。本博客将详细介绍如何使用HBuilderX编辑器和uView UI框架&#xff0c;开发一款问卷小程序。 环境准备 HBuilderX下载与…

快速拿下GIS开发的正确方式→定制属于自己的gis学习路线图

随着技术融合&#xff0c;人工智能、大数据、物联网与GIS的结合应用&#xff0c;以及移动GIS和云GIS解决方案的兴起&#xff0c;GIS行业的市场规模和应用深度持续增长&#xff0c;为智慧城市、环境保护、自然资源规划、智能交通、商业分析与研究、应急管理等多个领域带来革新。…

【ajax+node.js+webpack+git】学习笔记---ajax01

一、学习资料 1.学习课程 黑马程序员前端AJAX入门到实战全套教程&#xff0c;包含学前端框架必会的&#xff08;ajaxnode.jswebpackgit&#xff09;&#xff0c;一套全覆盖_哔哩哔哩_bilibili 2.学习框架 二、AJAX 1.定义 使用XMLHttpRequest对象与服务器通信。具有异步特性…