Компонент Link
В Reactive Route нет готового компонента Link для каждого фреймворка, так как он значительно ограничивал бы кастомизацию. Вы можете создать свой компонент, сохраняя полную типизацию, например с таким использованием:
tsx
<Link to={{ name: 'user', params: { id: '1' }, query: { phone: '1' } }} />
<LinkProps name={'user'} params={{ id: '1' }} query={{ phone: '1' }} />tsx
<Link to={{ name: 'user', params: { id: '1' }, query: { phone: '1' } }} />
<LinkProps name={'user'} params={{ id: '1' }} query={{ phone: '1' }} />tsx
<Link to={{ name: 'user', params: { id: '1' }, query: { phone: '1' } }} />
<LinkProps name={'user'} params={{ id: '1' }} query={{ phone: '1' }} />vue
<template>
<Link :to="{ name: 'user', params: { id: '1' }, query: { phone: '1' } }" />
<LinkProps name="user" :params="{ id: '1' }" :query="{ phone: '1' }" />
</template>Для удобства написания компонента можно создать в файле router.ts выведение типа переданных аргументов.
ts
export type TypeRouterProject = ReturnType<typeof getRouter>;
export type TypeConfigsProject = ReturnType<
TypeRouterProject['getGlobalArguments']
>['configs'];tsx
import { TypeStateDynamic } from 'reactive-route';
import { TypeConfigsProject, useRouter } from '../router';
export function Link<TName extends keyof TypeConfigsProject>(props: {
to: TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
children?: any;
}) {
const { router } = useRouter();
const url = router.stateToUrl(props.to);
return (
<a
href={url}
onClick={(event) => {
event.preventDefault();
router.redirect(props.to);
}}
>
{props.children}
</a>
);
}tsx
import { TypeStateDynamic } from 'reactive-route';
import { TypeConfigsProject, useRouter } from '../router';
export function LinkProps<TName extends keyof TypeConfigsProject>(
props: TypeStateDynamic<TypeConfigsProject, TName> & {
children?: any;
replace?: boolean;
}
) {
const { router } = useRouter();
const stateDynamic = {
name: props.name,
query: 'query' in props ? props.query : undefined,
params: 'params' in props ? props.params : undefined,
replace: props.replace,
} as TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
const url = router.stateToUrl(stateDynamic);
return (
<a
href={url}
onClick={(event) => {
event.preventDefault();
router.redirect(stateDynamic);
}}
>
{props.children}
</a>
);
}tsx
import { TypeStateDynamic } from 'reactive-route';
import { TypeConfigsProject, useRouter } from '../router';
export function Link<TName extends keyof TypeConfigsProject>(props: {
to: TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
children?: any;
}) {
const { router } = useRouter();
const url = router.stateToUrl(props.to);
return (
<a
href={url}
onClick={(event) => {
event.preventDefault();
router.redirect(props.to);
}}
>
{props.children}
</a>
);
}tsx
import { TypeStateDynamic } from 'reactive-route';
import { TypeConfigsProject, useRouter } from '../router';
export function LinkProps<TName extends keyof TypeConfigsProject>(
props: TypeStateDynamic<TypeConfigsProject, TName> & {
children?: any;
replace?: boolean;
}
) {
const { router } = useRouter();
const stateDynamic = {
name: props.name,
query: 'query' in props ? props.query : undefined,
params: 'params' in props ? props.params : undefined,
replace: props.replace,
} as TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
const url = router.stateToUrl(stateDynamic);
return (
<a
href={url}
onClick={(event) => {
event.preventDefault();
router.redirect(stateDynamic);
}}
>
{props.children}
</a>
);
}tsx
import { TypeStateDynamic } from 'reactive-route';
import { createMemo } from 'solid-js';
import { TypeConfigsProject, useRouter } from '../router';
export function Link<TName extends keyof TypeConfigsProject>(props: {
to: TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
children?: any;
}) {
const { router } = useRouter();
const url = createMemo(() => router.stateToUrl(props.to));
return (
<a
href={url()}
onClick={(event) => {
event.preventDefault();
router.redirect(props.to);
}}
>
{props.children}
</a>
);
}tsx
import { TypeStateDynamic } from 'reactive-route';
import { createMemo } from 'solid-js';
import { TypeConfigsProject, useRouter } from '../router';
export function LinkProps<TName extends keyof TypeConfigsProject>(
props: TypeStateDynamic<TypeConfigsProject, TName> & {
children?: any;
replace?: boolean;
}
) {
const { router } = useRouter();
const stateDynamic = createMemo(() => {
return {
name: props.name,
query: 'query' in props ? props.query : undefined,
params: 'params' in props ? props.params : undefined,
replace: props.replace,
} as TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
});
const url = createMemo(() => router.stateToUrl(stateDynamic()));
return (
<a
href={url()}
onClick={(event) => {
event.preventDefault();
router.redirect(stateDynamic());
}}
>
{props.children}
</a>
);
}vue
<script setup lang="ts" generic="TName extends keyof TypeConfigsProject">
import { TypeStateDynamic } from 'reactive-route';
import { computed } from 'vue';
import { TypeConfigsProject, useRouter } from '../router';
const props = defineProps<{
to: TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
}>();
const { router } = useRouter();
const url = computed(() => router.stateToUrl(props.to));
</script>
<template>
<a :href="url" @click.prevent="router.redirect(props.to)">
<slot />
</a>
</template>vue
<script setup lang="ts" generic="TName extends keyof TypeConfigsProject">
import { TypeStateDynamic } from 'reactive-route';
import { computed } from 'vue';
import { TypeConfigsProject, useRouter } from '../router';
const props = defineProps<TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean }>();
const { router } = useRouter();
const stateDynamic = computed(() => {
return {
name: props.name,
query: (props as any).query,
params: (props as any).params,
replace: props.replace,
} as TypeStateDynamic<TypeConfigsProject, TName> & { replace?: boolean };
});
const url = computed(() => router.stateToUrl(stateDynamic.value));
</script>
<template>
<a :href="url" @click.prevent="router.redirect(stateDynamic)">
<slot />
</a>
</template>Дополнительно
Эти примеры не являются официальной реализацией, но корректная работа проверена во всех текущих комбинациях реактивной системы и UI фреймворка.