1、目的:
自己用vite创建了一个前端项目,UI使用的是 NaiveUI,部分组件达不到自己的预期,但是又是通用的,所以这时候就想整个自定义组件了;
2、简单实现(创建一个自定义数据表格为例)
(1)在src\components路径下创建对应的文件夹,创建自定义表格组件:
CommonTable.vue 是自定义组件的主体内容
<template>
<h6>{{title}}</h6>
<n-data-table
:columns="tableColumns"
:data="data"
:pagination="pagination"
:bordered="false"
>
</n-data-table>
</template>
<script setup>
import {NDataTable} from "naive-ui"
import {basicProps} from './props'
import {unref,computed,reactive,ref} from 'vue'
const props = defineProps({
...basicProps
});
const title = unref(props.tableTitle) || '';
const tableAction=reactive(props.actionColumns) || {};
const tableColumns=reactive(props.columns) || [];
tableColumns.forEach(( item,index)=>{
if(item.key=="action"){
return;
}
if(index==tableColumns.length-1){
tableColumns.push(props.actionColumns)
}
});
console.log(tableColumns);
</script>
index.ts是用于组件批量导出
// @ts-ignore
import CommonTable from './CommonTable.vue';
export {CommonTable};
props.ts是用于自定义组件参数
import { NDataTable } from 'naive-ui';
export const basicProps = {
...NDataTable.props, // 这里继承原 UI 组件的 props
tableTitle: {
type: String,
default: null,
},
actionColumns:{
type: Array,
default:[]
}
}
(2)其他页面使用自定义组件
<template>
<CommonTable
:tableTitle="tableTitle"
:columns="columns"
:data="data"
:pagination="pagination"
:bordered="false"
:actionColumns="actionColumns"
/>
</template>
<script setup lang="ts">
import {NDataTable,useMessage,NButton} from 'naive-ui'
import { CommonTable } from '@/components/CommonTable/index';
import {columns} from './column'
import {ref,reactive,onMounted,h} from "vue"
import {getUserInfo} from "@/api/common/sysUser"
const pagination=reactive ({
pageSize: 10
});
const data = reactive([]);
const message=useMessage();
const tableTitle=ref("用户信息");
onMounted(() => {
getUserInfo().then((respons)=>{
Object.assign(data,respons.data);
})
});
const actionColumns = reactive({
title: '操作',
key: 'action',
render: (row)=> {
return[
h(
NButton,
{
strong: true,
tertiary: true,
size: 'small',
onClick:()=>editData(row),
},
{ default: () => '编辑' }
),
h(
NButton,
{
strong: true,
tertiary: true,
size: 'small',
onClick:()=>delData(row),
},
{ default: () => '删除' }
)]
}
});
function editData(row){
message.info("修改信息")
}
function delData(row){
message.info("删除信息")
}
</script>
<style scoped>
</style>
3、实现效果
这样一个简单的自定义组件就完成了,先整个简单的,后面再慢慢加其他功能吧
踩过的坑:
(1)使用h()方法时,需要传方法对象的参数传成了执行方法:
错误写法:(这样写会导致页面加载时就自动调用editData(row),然后button的onclick方法失效)
h(
NButton,
{
strong: true,
tertiary: true,
size: 'small',
onClick:editData(row),
},
{ default: () => '编辑' }
),
正确写法:
h(
NButton,
{
strong: true,
tertiary: true,
size: 'small',
onClick:()=>editData(row),
},
{ default: () => '编辑' }
),