Vue项目:仅在Contact组件禁用表格最后/唯一行内按钮
问题需求
我有三个组件:Button(ClickableText)、AppTable、Contact。Button组件在v-for循环遍历项的场景中被调用,需要实现:
- 当表格仅生成一行数据,或当前行是最后一行时,禁用该行中的Hide contact按钮
- 该禁用逻辑仅在Contact组件使用AppTable时生效
现有组件代码
Button(ClickableText)组件
<template> <div class="clickable-text" @click="() => !disabled && onClick()"> <div :class="className">{{ text }}</div> </div> </template> <script lang="ts"> import { Vue, Component, Prop } from 'vue-property-decorator'; @Component({}) export default class ClickableText extends Vue { @Prop({ default: true }) text: string; @Prop({ default: 'default' }) disabled: boolean; @Prop() classes: string; @Prop({ default: true }) clickable: boolean; @Prop({ default: () => {} }) onClick: () => void; get className() { return { disabled: this.disabled, [this.classes]: this.classes, clickable: this.clickable && !this.disabled, }; } } </script>
AppTable组件
<template> <div> <table> <thead> <tr> <th v-for="header in headers" :key="header.value"> <div @click="headerClicked(header)"> {{ header.text }} </div> </th> </tr> </thead> <tbody> <tr v-for="(item, n) in items" :key="n" data-qa="row" :id="item.id ? item.id.value : n"> <td v-for="header in headers" :key="header.value" :data-qa="header.value"> <div :class="itemClass(item, header)" @click="itemClicked(item, header)"> <div v-if="item[header.value] && item[header.value].value">{{ item[header.value].value }}</div> <div v-else> <component :is="item[header.value].component" v-bind="item[header.value].props" /> </div> </div> </td> </tr> </tbody> </table> </div> </template> <script lang="ts"> import { Vue, Component, Prop } from 'vue-property-decorator'; import { TableHeader, TableItem, TablePagination, AppTableItemClick } from './interfaces'; @Component export default class AppTable extends Vue { @Prop() headers: TableHeader[]; @Prop() items: TableItem[]; @Prop() pagination?: TablePagination; itemClass(item: TableItem, header: TableHeader) { const isClickable = item[header.value]?.clickable; return { link: isClickable, clickable: isClickable }; } headerClicked(header: TableHeader) { if (header.sortable) { this.$emit('headerClicked', header); } } itemClicked(item: TableItem, header: TableHeader): AppTableItemClick | undefined { const headerName = header.value; if (item[headerName]?.clickable) { const returnValue = { item, id: headerName }; this.$emit('itemClicked', returnValue); item[headerName]?.onClick?.(); return returnValue; } } } </script>
Contact组件中AppTable的调用
<template> <AppTable v-if="showTable" :headers="headers" :items="items" @headerClicked="onHeaderClick" /> </template>
解决方案
1. 给AppTable添加场景标识属性
修改AppTable的Props,新增isContactTable属性,用来标记当前表格是否是Contact组件使用的:
// AppTable.vue的script部分 @Prop({ default: false }) isContactTable!: boolean;
2. 在AppTable中动态控制Button的禁用状态
修改AppTable中渲染组件的代码,针对Hide contact按钮,结合表格数据条数和当前行索引,动态设置disabled属性:
<!-- AppTable.vue中渲染component的代码块 --> <component :is="item[header.value].component" v-bind="item[header.value].props" :disabled="isContactTable && (items.length === 1 || n === items.length - 1) && item[header.value].props.text === 'Hide contact'" />
isContactTable确保仅在Contact场景生效items.length === 1判断是否只有一行数据n === items.length - 1判断是否是最后一行item[header.value].props.text === 'Hide contact'确保只针对目标按钮生效
3. 修正Button组件的disabled属性默认值
原Button组件中disabled的默认值为字符串'default',存在类型错误,修正为布尔值默认false:
// Button(ClickableText)组件的Prop定义 @Prop({ default: false }) disabled!: boolean;
4. 在Contact组件中启用标识
修改Contact组件中AppTable的调用,开启isContactTable属性:
<AppTable v-if="showTable" :headers="headers" :items="items" @headerClicked="onHeaderClick" :is-contact-table="true" />
内容的提问来源于stack exchange,提问作者Neron Godfather
相关产品推荐
相关产品推荐

