Use the operation config to flexibly control the display and behavior of the operation column.
Set operation to false to hide both the operation column and the top "Add" button.
浏览器不支持,请手动复制 operation-hide.en.vue < template>
< np-table :option = " option" />
</ template>
< script setup lang = " ts" >
import type { TableOption } from 'naive-plus'
type User = { id : number; name: string; age: number; address: string }
const mockData : User[ ] = [
{ id : 1 , name : 'John' , age : 30 , address : 'New York' } ,
{ id : 2 , name : 'Jane' , age : 25 , address : 'Los Angeles' } ,
{ id : 3 , name : 'Bob' , age : 35 , address : 'Chicago' } ,
]
const option : TableOption< User> = {
columns : [
{ key : 'name' , label : 'Name' } ,
{ key : 'age' , label : 'Age' } ,
{ key : 'address' , label : 'Address' } ,
] ,
api : {
fetch : async ( { page, pageSize } ) => ( {
items : mockData. slice ( ( page - 1 ) * pageSize, page * pageSize) ,
itemCount : mockData. length,
} ) ,
} ,
operation : false ,
}
</ script>
Use prefixRender and suffixRender to insert custom content before and after the default action buttons.
浏览器不支持,请手动复制 operation-render.en.vue < template>
< np-table :option = " option" />
</ template>
< script setup lang = " ts" >
import { h } from 'vue'
import { NButton } from 'naive-ui'
import type { TableOption } from 'naive-plus'
type User = { id : number; name: string; age: number; address: string }
const mockData : User[ ] = [
{ id : 1 , name : 'John' , age : 30 , address : 'New York' } ,
{ id : 2 , name : 'Jane' , age : 25 , address : 'Los Angeles' } ,
{ id : 3 , name : 'Bob' , age : 35 , address : 'Chicago' } ,
]
const option : TableOption< User> = {
columns : [
{ key : 'name' , label : 'Name' } ,
{ key : 'age' , label : 'Age' } ,
{ key : 'address' , label : 'Address' } ,
] ,
api : {
fetch : async ( { page, pageSize } ) => ( {
items : mockData. slice ( ( page - 1 ) * pageSize, page * pageSize) ,
itemCount : mockData. length,
} ) ,
} ,
operation : {
label : 'Actions' ,
width : 200 ,
prefixRender : rowData =>
h (
NButton,
{ size : 'small' , type : 'info' , style : 'margin-right:4px' } ,
( ) => ` View # ${ rowData. id} `
) ,
suffixRender : rowData =>
h (
NButton,
{ size : 'small' , type : 'warning' , style : 'margin-left:4px' } ,
( ) => ` Logs `
) ,
} ,
}
</ script>
Use options to configure dropdown menu items, and use onSelect to handle clicks on custom items.
{ type: 'edit' } / { type: 'del' } reuses the built-in edit/delete logic (triggers onBefore, opens the dialog, etc.)Custom key options trigger the onSelect callback on click
浏览器不支持,请手动复制 operation-custom.en.vue < template>
< div>
< n-alert v-if = " lastKey" type = " success" style = " margin-bottom : 12px" >
onSelect triggered, key =
< strong> {{ lastKey }}</ strong>
</ n-alert>
< np-table :option = " option" />
</ div>
</ template>
< script setup lang = " tsx" >
import { ref } from 'vue'
import { NAlert } from 'naive-ui'
import type { TableOption } from 'naive-plus'
type User = { id : number; name: string; age: number; address: string }
const lastKey = ref ( '' )
const mockData : User[ ] = [
{ id : 1 , name : 'John' , age : 30 , address : 'New York' } ,
{ id : 2 , name : 'Jane' , age : 25 , address : 'Los Angeles' } ,
{ id : 3 , name : 'Bob' , age : 35 , address : 'Chicago' } ,
]
const option : TableOption< User> = {
columns : [
{ key : 'name' , label : 'Name' } ,
{ key : 'age' , label : 'Age' } ,
{ key : 'address' , label : 'Address' } ,
] ,
api : {
fetch : async ( { page, pageSize } ) => ( {
items : mockData. slice ( ( page - 1 ) * pageSize, page * pageSize) ,
itemCount : mockData. length,
} ) ,
} ,
operation : {
label : 'Actions' ,
options : [
{ type : 'edit' } ,
{ type : 'del' , label : 'Delete (Danger)' } ,
{ key : 'detail' , label : 'Detail' } ,
{ key : 'export' , label : ( ) => < span style= "color: red" > Export< / span> } ,
] ,
onSelect : key => {
lastKey. value = key
} ,
} ,
}
</ script>
options also accepts a function to build dropdown items from the current row.
浏览器不支持,请手动复制 operation-options-function.en.vue < template>
< div>
< n-alert v-if = " lastKey" type = " success" style = " margin-bottom : 12px" >
onSelect triggered, key =
< strong> {{ lastKey }}</ strong>
</ n-alert>
< np-table :option = " option" />
</ div>
</ template>
< script setup lang = " tsx" >
import { ref } from 'vue'
import { NAlert } from 'naive-ui'
import type { TableOption } from 'naive-plus'
type User = {
id : number
name : string
age : number
address : string
locked? : boolean
}
const lastKey = ref ( '' )
const mockData : User[ ] = [
{ id : 1 , name : 'John' , age : 30 , address : 'New York' } ,
{ id : 2 , name : 'Jane' , age : 25 , address : 'Los Angeles' , locked : true } ,
{ id : 3 , name : 'Bob' , age : 35 , address : 'Chicago' } ,
]
const option : TableOption< User> = {
columns : [
{ key : 'name' , label : 'Name' } ,
{ key : 'age' , label : 'Age' } ,
{ key : 'address' , label : 'Address' } ,
] ,
api : {
fetch : async ( { page, pageSize } ) => ( {
items : mockData. slice ( ( page - 1 ) * pageSize, page * pageSize) ,
itemCount : mockData. length,
} ) ,
} ,
operation : {
label : 'Actions' ,
options : ( rowData, rowIndex ) => [
{ type : 'edit' } ,
{ type : 'del' , disabled : rowData. locked } ,
{ key : 'detail' , label : ` Detail ${ rowIndex + 1 } ` } ,
] ,
onSelect : key => {
lastKey. value = key
} ,
} ,
}
</ script>
When options only contains { type: 'edit' } / { type: 'del' }, the built-in items are reused. Use defaultOptions to override their texts and props (merged per edit / del, so overriding only label keeps the built-in key), while the same fields in options take priority.
const option: TableOption = {
operation: {
defaultOptions: {
edit: { label: 'Edit' , key: 'edit' } ,
del: { label: 'Delete' , key: 'delete' } ,
} ,
} ,
}
Without defaultOptions, the texts come from the locale of NpConfigProvider; they can also be set globally through Table.operation of NpConfigProvider.
Note: the built-in del.label is a render function that renders NText type="error". Passing a string in the example above replaces that render function, so the delete item loses its red text style. Render NText type="error" yourself if you want to keep it.
operation? :
| false
| {
label? : string
width? : number | string
prefixRender? : ( rowData: T , rowIndex: number ) => VNode
suffixRender? : ( rowData: T , rowIndex: number ) => VNode
options? : TableOperationOption[ ] | ( ( rowData: T , rowIndex: number ) => TableOperationOption[ ] )
defaultOptions? : TableOperationDefaultOptions
onSelect? : ( key: string ) => void | boolean
onBefore? : ( rowData: T , type: 'add' | 'edit' | 'del' ) => boolean | T | void | Promise < ... >
}
Partial<Record<'edit' | 'del', Omit<TableOperationOption, 'type'>>>, used to replace the defaults of the built-in edit / delete items.
Field Description Type typeBuilt-in type, reuses the edit/delete logic 'edit' | 'del'keyCustom option identifier, triggers the onSelect callback string | numberlabelCustom option display label string | (() => VNode)
Built-in types and custom keys can be mixed, e.g. [{ type: 'edit' }, { type: 'del' }, { key: 'export', label: 'Export' }].