因为是封装的原因,所以只要看:<page-content />组件和配置文件contentTableConfig
<template> <div class="user"> <page-content :cOntentTableConfig="contentTableConfig" pageName="users" ></page-content> </div> </template> <script lang="ts"> import { defineComponent } from "vue"; //引入展示 table 组件 import PageContent from "@/components/page-content"; //引入展示 table 组件的数据和配置 import { contentTableConfig } from "./config/content.config"; export default defineComponent({ name: "users", components: { PageContent }, setup() { return { contentTableConfig }; } }); </script> <style scoped> .content { padding: 20px; border-top: 20px solid #f5f5f5; } </style>
export const cOntentTableConfig= { title: "用户列表", propList: [ { prop: "name", label: "用户名", minWidth: "100" }, { prop: "realname", label: "真实姓名", minWidth: "100" }, { prop: "cellphonne", label: "电话号码", minWidth: "200" }, { prop: "enable", label: "状态", minWidth: "100", slotName: "status" }, { prop: "createAt", label: "创建时间", minWidth: "230", slotName: "createAt" }, { prop: "updateAt", label: "更新时间", minWidth: "230", slotName: "updateAt" }, { label: "操作", minWidth: "120", slotName: "handler" } ], showIndexColumn: true, showSelectColumn: true };
<template> <div class="page-content"> <hy-table v-bind="contentTableConfig" :listData="dataList"> <!-- 1.header 中的插槽 --> <template #headerHandler> <el-button type="primary" size="medium">新建用户</el-button> </template> <!-- 2.列中的插槽 --> <template #status="scope"> <el-button plain size="mini" :type="scope.row.enable ? 'success' : 'danger'" > {{ scope.row.enable ? "启用" : "禁用" }} </el-button> </template> <template #createAt="scope"> <span>{{ $filters.formatTime(scope.row.createAt) }}</span> </template> <template #updateAt="scope"> <span>{{ $filters.formatTime(scope.row.updateAt) }}</span> </template> <template #handler> <div class="handle-btns"> <el-button icon="el-icon-edit" size="mini" type="text" >编辑</el-button > <el-button icon="el-icon-delete" size="mini" type="text" >删除</el-button > </div> </template> </hy-table> </div> </template> <script lang="ts"> import { defineComponent, computed } from "vue"; import { useStore } from "@/store"; import HyTable from "@/base-ui/table"; export default defineComponent({ components: { HyTable }, props: { contentTableConfig: { //配置文件,这个要传给子组件 HyTable type: Object, require: true }, pageName: { type: String, required: true } }, setup(props) { const dataList = computed(() => store.getters[`system/pageListData`](props.pageName) ); return { dataList }; } }); </script> <style scoped> .page-content { padding: 20px; border-top: 20px solid #f5f5f5; } </style>
<template> <div class="hy-table"> <div class="header"> <slot name="header"> <div class="title">{{ title }}</div> <div class="handler"> <slot name="headerHandler"></slot> </div> </slot> </div> <el-table :data="listData" border style="width: 100%" @selection-change="handleSelectionChange" > <el-table-column v-if="showSelectColumn" type="selection" align="center" width="60" ></el-table-column> <el-table-column v-if="showIndexColumn" type="index" label="序号" align="center" width="80" ></el-table-column> <template v-for="propItem in propList" :key="propItem.prop"> <el-table-column v-bind="propItem" align="center"> <template #default="scope"> <slot :name="propItem.slotName" :row="scope.row"> {{ scope.row[propItem.prop] }} </slot> </template> </el-table-column> </template> </el-table> <div class="footer"> <slot name="footer"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="total, sizes, prev, pager, next, jumper" :total="400" > </el-pagination> </slot> </div> </div> </template> <script lang="ts"> import { defineComponent, PropType } from "vue"; export default defineComponent({ props: { listData: { type: Array, required: true }, title: { //通过 page-content 组件传过来的 contentTableConfig 对象的属性会不会自动解析,是不是这儿出问题了? type: String, default: "" }, propList: { type: Array as PropType<any[]>, required: true }, showIndexColumn: { type: Boolean, default: false }, showSelectColumn: { type: Boolean, default: false } }, emits: ["selectionChange"], setup(props, { emit }) { const handleSelectiOnChange= (value: any) => { emit("selectionChange", value); }; const handleSizeChange = () => { return; }; const handleCurrentChange = () => { return; }; return { handleSelectionChange, handleSizeChange, handleCurrentChange }; } }); </script> <style scoped lang="less"> .header { display: flex; height: 45px; padding: 0 5px; justify-content: space-between; align-items: center; .title { font-size: 20px; font-weight: 700; } .handler { align-items: center; } } .footer { margin-top: 15px; .el-pagination { text-align: right; } } </style>
![]() | 1 Uahh 2022-10-17 14:24:22 +08:00 试试把 contentTableConfig 变量名改成 content_table_config |
![]() | 2 moreant 2022-10-17 14:48:58 +08:00 page-content.vue 组件的 props 的 contentTableConfig 类型是 Object ,volar 无法推断出类型吧 |
![]() | 5 tomieric 2022-10-17 15:46:27 +08:00 ```js propList: { type: Array as PropType<any[]>, required: true }, ``` 我只看到这个 |
7 slmakm OP |
![]() | 8 moreant 2022-10-17 17:33:15 +08:00 @slmakm page-content.vue 文件 ```js import type { PropType } from 'vue' interface ContentProp { prop: string label: string minWidth: string } interface Content { title: string propList: Array<ContentProp> showIndexColumn: boolean showSelectColumn: boolean } export default defineComponent({ props: { book: { // 提供相对 `Object` 更确定的类型 type: Object as PropType<Content>, required: true } } }) ``` 参考 https://cn.vuejs.org/guide/typescript/options-api.html#typing-component-props:~:text=%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8-,PropType,-%E8%BF%99%E4%B8%AA%E5%B7%A5%E5%85%B7%E7%B1%BB%E5%9E%8B 顺便一提,建议早用组合式与 <script setup> 早舒服 |
![]() | 10 current 2022-10-18 19:22:54 +08:00 被 cue 的莫名其妙。。。 |