持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
一、前言
今天来试试Naive库的数据表格data table,类似这种封装好的table表格,之前有试用过几个公司封装过的table,也是这种将表格的列内容,用这种option的形式,动态配置好表格的内容,封装的方式各有不同,但是感觉都一般,用起来有种得不偿失的感觉。这次试试流行naive的框架里的数据表格data-table,看上去似乎还是比较nb的,我们来试试看吧。
二、data-table
在试官方例子的过程中,真的越来越感觉在用excel表格了,确实是有点nb。
目前我将script标签里的setup去掉了
之前在setup里,和官网给的例子不太兼容,因为setup里不需要return是直接执行的,会导致许多问题。
好接下来我们开始
(1) 首先还是引入一下
我在全局引入了NDataTable和NButton这两个组件,当然也可以在文件里按需引入,但请注意似乎只会生效一个。
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import {
create,
NButton,
NIcon,
NIconWrapper,
NDataTable
} from 'naive-ui'
const naive = create({
components: [NButton, NIcon, NIconWrapper, NDataTable]
})
createApp(App).use(naive).mount('#app')
然后局部引入了vue的相关api,同时引入了naive-ui的DataTableColumns,用来撰写每一行的内容。
import type { DataTableColumns } from 'naive-ui'
import { h, defineComponent, ref, nextTick } from 'vue'
复制代码
(2)编写编辑模式
用defineComponent编写编辑模式函数,这里props负责规定好传入参数的规范,value是修改后的值,onUpdateValue则是更新函数。将这两个值传入setup函数里,等待备用。
在setup里返回一个div,这个div挂载了点击函数handleOnClick,用来修改编辑状态,若是编辑状态,则修改div里的元素为input框,若不是编辑模式,则修改div里的元素为一个普通的值。
同时在编辑模式下,返回的input框,还挂载了onChange和onBlur事件,在值发生变化,或者焦点状态发生变化时,都会触发handleChange函数,一是更新值到对应的数据里去,二是取消编辑状态。
// 编辑的模式
const ShowOrEdit = defineComponent({
props: {
value: [String, Number],
onUpdateValue: [Function, Array]
},
setup (props) {
const isEdit = ref(false)
const inputRef = ref(null)
const inputValue = ref(props.value)
function handleOnClick () {
isEdit.value = true
nextTick(() => {
inputRef.value.focus()
})
}
function handleChange () {
props.onUpdateValue(inputValue.value)
isEdit.value = false
}
return () =>
h(
'div',
{
onClick: handleOnClick
},
isEdit.value
? h(NInput, {
ref: inputRef,
value: inputValue.value,
onUpdateValue: (v:string) => {
inputValue.value = v
},
onChange: handleChange,
onBlur: handleChange
})
: props.value
)
}
})
(3)用函数定义好数据的内容
这里我们用一种函数的方式定义好表格的内容,一共三行,键值对也很清晰,这里需要注意的是,需要有个唯一的值,给data-table当主键,我选用了key属性,该属性唯一,适合当主键。
const createData = () => [
{
key: 0,
name: 'John Brown',
age: '32',
address: 'New York No. 1 Lake Park'
},
{
key: 1,
name: 'Jim Green',
age: '42',
address: 'London No. 1 Lake Park'
},
{
key: 2,
name: 'Joe Black',
age: '32',
address: 'Sidney No. 1 Lake Park'
}
]
(4)在export default defineComponent里,书写剩余逻辑
第一步
先引用上面定义好的createData函数创建好数据, 我试过直接定义data,但对于这种在页面上会被修改到的数据,要实现双向绑定的话,vue3官网似乎是要求必须用ref声明的
const data = ref(createData())
第二步
在createColumns定义好每一列的内容,包括每一列的函数调用等等,比如第一二列我写成了可以自由切换编辑状态的模式,所以我需要在对应的render里调用了第二小节定义好的编辑模型ShowOrEdit,传入value值和onUpdateValue的具体函数逻辑。同时如果还挂载了其他自定义函数,比如我挂载在第四列按钮上的函数play,需要在createColumns里提前声明。
const createColumns = ({
play
}: {
play: (row: Song) => void
}): DataTableColumns<Song> => {
return [
{
title: 'name',
key: 'name',
align: 'center',
render (row, index) {
return h(
ShowOrEdit,
{
value: row.name,
onUpdateValue (v:string) {
data.value[index].name = String(v)
}
}
)
}
},
{
title: 'Age',
key: 'age',
align: 'center',
resizable: true,
ellipsis: {
tooltip: true,
lineClamp: 2,
expandTrigger: 'click'
},
render (row, index) {
return h(
ShowOrEdit,
{
value: row.age,
onUpdateValue (v:string) {
data.value[index].age = v
}
}
)
}
},
{
title: 'address',
key: 'address',
align: 'center',
resizable: true,
minWidth: 100,
maxWidth: 500
},
{
title: 'Action',
key: 'actions',
render (row) {
return h(
NButton,
{
strong: true,
tertiary: true,
size: 'small',
onClick: () => play(row)
},
{ default: () => 'Play' }
)
}
}
]
}
第三步
用第二步的函数生成好columns,并且将要挂载在按钮上的play函数,具体的逻辑执行内容完善。我是挂载了useMessage组件,该组件效果和element的message效果差不多。下面函数的内容不过是将拿到的行数据里的name值,用弹窗提示的方式弹出而已。(这里useMessage的使用还有点小坑,后期跟你们说一声)
const columns = createColumns({
play (row: Song) {
const message = useMessage()
message.info(`Play ${row.name}`) // 相当于vue2的message弹窗提示
}
})
第四步
由于我们使用的export default defineComponent,所以必须像vue2那样,将需要用的值都return出来,页面上才能正常使用,不然会找不到对应的变量。
const pagination = false as const // 断言函数设置pagination为false
// 必须像vue2那样return出来
return {
data,
columns,
pagination
}
第五步
在template里写好表格,key值用我们的row.key充当,其他属性基本对号入座即可。
<div v-if="data.length > 0" style="width: 1200px;height: 1200px;">
DATA-TABLE表格
<n-data-table
:key="(row) => row.key"
:columns="columns"
:data="data"
:pagination="pagination"
:bordered="true"
/>
(5)来看看效果吧
可以看到我们之间点击内容,就会生成input框,可以编辑,可以保存,基本靠拢excel了
三、小结
今天尝试了naive的数据表格,只试用了官网的其中一个例子--可切换的可编辑表格,官网给的说法就是,不太简单,但胜在好看 。整个过程试验下来,体验感还不错,功能都让人眼前一亮,就是可能需要根据项目做一点适配,刚开始用,适配起来还有点难度,走了不少弯路,大家感兴趣可以去官网看看,例子也比较丰富,可以试着敲一敲。
ps: 我是地霊殿__三無,大家一起学习,共同进步!