naive-ui
naive-ui copied to clipboard
Can TreeOption.label accept "string | (() => VNodeChild)" instead of just "string"?
This function solves the problem (这个功能解决的问题)
Hello.
I need to render a Tree
component but labels should support localization. I'm trying to use a translation function (t()
) from Vue-i18n
library like below:
export default defineComponent({
components: { NLayoutSider, NTree },
setup() {
const { t } = useI18n<{}, string>({useScope: 'global'});
const filters: TreeOption[] = [
{ key: '1', label: () => t('tickets.filter.responsibility.group'), children: [
{ key: '1-1', label: () => t('tickets.filter.responsibility.curated') },
{ key: '1-2', label: () => t('tickets.filter.responsibility.forObservation') }
]}
]
return { filters }
}
});
</script>
<template>
<n-layout-sider content-style="padding: 24px" width="300px" show-trigger bordered :native-scrollbar="false">
<n-tree :data="filters" cascade checkable check-on-click default-expand-all :selectable="false" :default-checked-keys="['1']"></n-tree>
</n-layout-sider>
</template>
The above throws type error because label
accepts only string
. The only way I found at the moment is to use suffix
or preffix
instead of label
:
const filters: TreeOption[] = [
{ key: '1', suffix: () => t('tickets.filter.responsibility.group'), children: [
{ key: '1-1', suffix: () => t('tickets.filter.responsibility.curated') },
{ key: '1-2', suffix: () => t('tickets.filter.responsibility.forObservation') }
]}
]
The above works fine but looks not really correct.
Similar data format has Menu
component but label
there accepts string | (() => VNodeChild)
instead of just string
, so no any issues there with translation.
Can TreeOption.label
be updated so that it will accept string | (() => VNodeChild)
?
Probably there is another (better) way to implement localization in such cases?
Any way thank yo very mush for so good library, it's awesome.
Expected API (期望的 API)
No any changes in API, particular intefrace only.
Why not make filters a computed
:
export default defineComponent({
components: { NLayoutSider, NTree },
setup() {
const { t } = useI18n<{}, string>({useScope: 'global'});
const filters: TreeOption[] = computed(() => [
{ key: '1', label: t('tickets.filter.responsibility.group'), children: [
{ key: '1-1', label: t('tickets.filter.responsibility.curated') },
{ key: '1-2', label: t('tickets.filter.responsibility.forObservation') }
]}
])
return { filters }
}
});
However I think we can add the API. For your case I think a computed
is better.
Thanks @07akioni for your response. With computed it works perfectly. But type have to be wrapped with ComputedRef
, otherwise getting the following error:
Type 'ComputedRef<{ key: string; suffix: () => string; children: { key: string; suffix: () => string; }[]; }[]>' is missing the following properties from type 'TreeOption[]': length, pop, push, concat, and 26 more.
So finally it looks like below:
import type { ComputedRef } from 'vue';
export default defineComponent({
components: { NLayoutSider, NTree },
setup() {
const { t } = useI18n<{}, string>({useScope: 'global'});
const filters: ComputedRef<TreeOption[]> = computed(() => [
{ key: '1', label: t('tickets.filter.responsibility.group'), children: [
{ key: '1-1', label: t('tickets.filter.responsibility.curated') },
{ key: '1-2', label: t('tickets.filter.responsibility.forObservation') }
]}
])
return { filters }
}
});
This issue does not have any recent activity. If you are still experiencing similar problems, open a new error, including a minimal copy of the problem