Vue3: 使用Tdesign过程中遇到的坑洼

3,996 阅读5分钟

简介

滑进Tdesign的设计世界,哪怕只是一不小心,你也会掉进一些意想不到的坑里!但别慌张,大胆探索,和做好每一次的总结。

在这篇文章中,我将分享我们在使用Tdesign过程中遇到的坑洼,以及我个人的总结和经验分享

坑洼集合

修改插件样式

当无法通过直接deep深层属性改写的情况下,

 
  :deep(.t-drawer__header){
    padding: 0 24px;
    border-bottom: none;
    justify-content: space-between;
  }
}

可以试着在顶层加一个dom,并加上class

image.png

然后改写css

.detail-dw {
  :deep(.t-drawer__header){
    padding: 0 24px;
    border-bottom: none;
    justify-content: space-between;
  }
 }

修改t-popup样式

image.png

    <t-popup
      v-model="visibleBrush"
      placement="bottom"
      overlay-class-name="popupBrush"
      :z-index="5490"
      trigger="click"
    >

使用overlay-class-name在组件命名一个类名 然后less样式:

.popupBrush  {
  cursor: pointer;
  .t-popup__content {
    padding: 0 !important;
    background: red;
  }
}

结果并不生效,如下:

image.png

需要深入重定义

:deep(.popupBrush)  {
  cursor: pointer;
  .t-popup__content {
    padding: 0 !important;
    background: red;
  }
}

如果仍然不生效,就将.popupBrush写到顶层样式目录中去

语言包用在defineProps中报错

使用场景:

在setup里声明了一个变量,并且在defineProps初始化的时候使用了这个本地变量,如下:

image.png

具体错误如下:

image.png

分析原因:

defineProps正在引用本地声明的变量。这意味着在组件中使用defineProps去定义组件的 props 时,我们可能会错误地引用了在组件内部声明的变量。

这个问题的原因是 defineProps 函数是用来声明组件 props 的,而 props 应该是来自父组件传递的值,而不是在组件内部定义。因此,如果我们在 defineProps 中引用了本地声明的变量,那么在从父组件传递的 props 中获取值时可能会出现错误。

解决这个问题的方法很简单,我们只需要确保在 defineProps 中引用的值都是来自父组件传递的,而不是在组件内部声明的

所以上面中使用语言包只是一个例子,这样在使用setup中的本地变量也会报这样的错误,如下:

image.png 言归正传

解决方法:

<script lang="ts">
// eslint-disable-next-line import/order
import { i18n } from '@/i18n';
// @ts-ignore
const { t } = i18n.global;
const a = 'test';
export default {};
</script>
<script lang="ts" setup>
const props = defineProps({
    chengRange: {
            type: Number,
            default: a,
    },
    header: {
            type: String,
            default: t('lss.select_direct_superior'),
    },
});
</script>

image.png 可以看到,已经能成功运行 通过上面这种方式,我们可以解决上面提到的defineProps引用本地声明的变量的问题。

首先,我们导入了 i18n 对象,它是实现国际化的库。然后,在 i18n.global 中我们使用了 t 函数来获取翻译好的文本。这里通过解构赋值的方式将 t 函数赋值给了局部变量 t

在这个例子中,通过使用 @ts-ignore 忽略了 TypeScript 的类型检查,所以可以在 const { t } = i18n.global; 这一行成功将 t 赋值为 i18n.global 对象中的 t 函数。

最后,我们将一个空的对象作为默认导出。这是因为在 .vue 文件中,必须至少有一个默认导出。

尽管这种方式可以解决引用本地声明变量的问题,但是要注意 @ts-ignore 的使用会忽略 TypeScript 的类型检查,可能会带来潜在的问题。在使用这种方式时,请确保你已经确认了类型的正确性,并且了解忽略类型检查可能带来的潜在风险。

t-table那些的隐匿方法挖掘

cell-empty-content

<t-table row-key="id" :data="formData.record" :columns="columnsRecord" :loading="loading" cell-empty-content="--">
        <template #result="{ row }">
                <div class="record-result">
                        <span class="status">{{ recordStatusOptions.find((v) => v.value === row.status)?.label }}</span>
                        <span class="type">违规类型:{{ $filters.isPeriodEmpty(row.type) }}</span>
                        <span class="no">违规编号:{{ $filters.isPeriodEmpty(row.no) }}</span>
                </div>
        </template>
</t-table>

往往有缺省字段即为空的情况下,显示一些特殊字符,可以使用cell-empty-content,而不是一个个去判断。

t-enhance-table

在使用该组件的时候,每次请求都会重新收起

image.png

所以需要记录展开后的值,当重新更新数据的时候,回填该展开的项

image.png

<t-enhanced-table
    ref="table"
    row-key="id"
    drag-sort="row-handler"
    :data="data"
    :columns="columns"
    :tree="treeConfig"
    :tree-expand-and-fold-icon="treeExpandIcon"
    :before-drag-sort="beforeDragSort"
    :column-controller="{
            placement: 'bottom-left',
            fields: ['id'],
            dialogProps: { preventScrollThrough: true },
    }"
    height="calc(100vh - 240px)"
    @abnormal-drag-sort="onAbnormalDragSort"
    @drag-sort="onDragSort"
    @tree-expand-change="treeExpandChange"
>
if (res.data.length > 0) {
        nextTick(() => {
                // const rowData = table.value.getData(res.data.data[0].id);
                // table.value.toggleExpandData(rowData);
                // 在重新更新表格数据之前,先拿到当前展开的项
                const treeRows = table.value.getTreeExpandedRow();
                console.log(treeRows);
                table.value.resetData(res.data); // 
                // data.value = res.data;
                // if (isFirst.value) {
                // 	table.value.expandAll();
                // 	isFirst.value = false;
                // }
                // 重新展开之前记录的值
                treeRows.forEach((element) => {
                        const rowData = table.value.getData(element.id);
                        table.value.toggleExpandData(rowData);
                });
        });
}

TreeSelect 树选择

image.png

treeProps

透传属性treeProps,可以通过接口返回的参数,自定义对应的属性名 如下:

   <t-tree-select
      v-model="formData.category"
      :data="cateOptions"
      :tree-props="treeProps"
      clearable
      multiple
      :placeholder="'请选择服务分类'"
    />

VUE3 SETUP

const treeProps = {
  keys: {
    label: "name",
    value: "id",
    children: "children"
  }
};

image.png

还有一个隐匿属性

valueType

用于控制选中值的类型。假设数据选项为:[{ label: '姓名', value: 'name' }],value 表示值仅返回数据选项中的 value, object 表示值返回全部数据。可选项:value/object

image.png

InputNumber 数字输入框

可以这样说,关于数字、金额、浮点等需求的,选择该组件,基本能够满足。 并且结合表单验证方法,可以实现校验过程 就如同这种需求一样:

image.png 简单应对。

如下example:

 <t-form-item
  :label="'缴费金额'"
  name="money"
  class="searchForm-item"
>
  <t-input-number
    v-model="formData.money"
    theme="normal"
    :decimal-places="2"
    :placeholder="'请输入'"
    :min="0"
    class="searchForm-item"
    type="number"
  />
</t-form-item>
const rule ={
  money: [
    {
      required: true,
      message: "请输入",
      type: "error",
      trigger: "change"
    },
    { min: 0, message: "金额必须是大于等于0", type: "error", trigger: "blur" }

        // { max: 999, message: '输入字数应在0到999之间', type: 'error', trigger: 'blur' },
      ],
}

DialogPlugin

使用tsx

const confirmDia = DialogPlugin({
    header: t('user.tips'),
    theme: 'info',
    top: '300',
    zIndex: 2500,
    body:'也支持render',
    confirmBtn: () => (
            <TButton
                    theme="danger"
                    variant="outline"
                    onClick={() => {
                            onCofrmSt(confirmDia, row.id, 0);
                    }}
            >
                    {t('xx')}
            </TButton>
    ),
    className: 'modeIconPadding',
    onConfirm: async () => {
            console.log('oncofi');
    },
    onClose: () => {
            confirmDia.hide();
    },
});

持续总结,并更新!