ඔබ ඔබේ ව්යාපෘතිය සඳහා කොටස් නිර්මාණය කරන විට, එය සියල්ල විනෝද හා පහසු ආරම්භ කරයි.MyButton.vue
ටිකක් ස්ටයිල් එකක් දාලා මෙන්න.
<template>
<button class="my-fancy-style">
<slot></slot>
</button>
</template>
එවිට ඔබ වහාම තේරුම් ගන්නේ ඔබ දොළහක් අවශ්ය බව, ඔබේ නිර්මාණ කණ්ඩායම එය විවිධ වර්ණ හා ප්රමාණයන් ඇති කිරීමට අවශ්ය නිසා, වම් හා දකුණු මත අයිකන්, ගණන් සමග ...
const props = withDefaults(defineProps<{
theme?: ComponentTheme;
small?: boolean;
icon?: IconSvg; // I’ve described how I cook icons in my previous article
rightIcon?: IconSvg;
counter?: number;
}>(), {
theme: ComponentTheme.BLUE,
icon: undefined,
rightIcon: undefined,
counter: undefined
});
එය තවමත් හොඳයි; එය තේරුම් ගත හැකිය.ඇත්තටම, ඔබට එකම වර්ණයේ "සහ" සහ "අක්" බොත්තම් ලබා ගත නොහැකි අතර, ඔබට පරිශීලක සන්නිවේදන ප්රතික්රියා කිරීමට ඔවුන්ට අවශ්ය වේ.
const props = withDefaults(defineProps<{
theme?: ComponentTheme;
small?: boolean;
icon?: IconSvg;
rightIcon?: IconSvg;
counter?: number;
disabled?: boolean;
loading?: boolean;
}>(), {
theme: ComponentTheme.BLUE,
icon: undefined,
rightIcon: undefined,
counter: undefined
});
හොඳයි, ඔබට අදහසක් ලැබෙනු ඇත: යමක් වෘත්තීය වනු ඇත, පැතිරීම වැනිwidth: 100%
හෝ ස්වයංක්රීය අවධානය එකතු කිරීම - අපි හැමෝම දන්නේ Figma හි සරල බව සැබෑ ජීවිතයේ දුෂ්කර වේ.
දැන් සබැඳි බොත්තම සිතන්න: එය එකම පෙනුමකි, නමුත් ඔබ එය පීඩනය කරන විට, ඔබ අභ්යන්තර හෝ අභ්යන්තර සබැඳි වෙත යන්න.<RouterLink>
හෝ<a>
සෑම විටම ටැග්, නමුත් කරුණාකර නොකරන්න.to
සහhref
ඔබේ ආරම්භක අංගයට ප්රතිලාභ, නමුත් ඔබ ඉක්මනින් හුස්ම දැනෙනු ඇත:
<component
:is="to ? RouterLink : href ? 'a' : 'button'"
<!-- ugh! -->
අනිවාර්යයෙන්ම, ඔබ ඔබේ බොත්තම ආකර්ෂණය කරන "වැඩි මට්ටමක" අංගයක් අවශ්ය වනු ඇත (එවිට එය මෘදුකාංග සකස් කිරීම් සහ අනෙකුත් උනන්දුවක් ඇති වනු ඇත, නමුත් සරලතාවය සඳහා මම ඒවා අවලංගු කරමි):
<template>
<component
:is="props.to ? RouterLink : 'a'"
:to="props.to"
:href="props.href"
class="my-link-button"
>
<MyButton v-bind="$attrs">
<slot></slot>
</MyButton>
</component>
</template>
<script lang="ts" setup>
import MyButton from './MyButton.vue';
import { RouteLocationRaw, RouterLink } from 'vue-router';
const props = defineProps<{
to?: RouteLocationRaw;
href?: string;
}>();
</script>
ඒක තමයි අපේ කතාව පටන් ගන්නේ.
Square One
Square එකහොඳයි, මූලික වශයෙන් එය වැඩ කරනු ඇත, මම බොරු නොකරමි.<MyLinkButton :counter=“2">
, සහ එය හොඳයි.ඒත් සකස් කළ ප්රොප් සඳහා කිසිදු ස්වයංක්රීය සම්පූර්ණයක් නොලැබෙනු ඇත, එය ශක්තිමත් නොවේ:
අපි නිහඬව ප්රතිපත්තිය ප්රදර්ශනය කළ හැක, නමුත් IDE ඔවුන් ගැන කිසිවක් දන්නේ නැහැ, එය ලැජ්ජාවකි.
සරල හා පැහැදිලි විසඳුම ඔවුන් පැහැදිලිව ප්රදර්ශනය කිරීමයි:
<template>
<component
:is="props.to ? RouterLink : 'a'"
:to="props.to"
:href="props.href"
class="my-link-button"
>
<MyButton
:theme="props.theme"
:small="props.small"
:icon="props.icon"
:right-icon="props.rightIcon"
:counter="props.counter"
:disabled="props.disabled"
:loading="props.loading"
>
<slot></slot>
</MyButton>
</component>
</template>
<script lang="ts" setup>
// imports...
const props = withDefaults(
defineProps<{
theme?: ComponentTheme;
small?: boolean;
icon?: IconSvg;
rightIcon?: IconSvg;
counter?: number;
disabled?: boolean;
loading?: boolean;
to?: RouteLocationRaw;
href?: string;
}>(),
{
theme: ComponentTheme.BLUE,
icon: undefined,
rightIcon: undefined,
counter: undefined,
}
);
</script>
එය ක්රියා කරනු ඇත. IDE නිවැරදි autocomplete ඇත. අපි එය සහාය කිරීමට බොහෝ වේදනාවක් හා පසුතැවිලි ඇති වනු ඇත.
අනිවාර්යයෙන්ම, "ඔබ නැවත නැවත නොකරන්න" මූලධර්මය මෙහි යෙදුනේ නැත, එබැවින් අප සෑම යාවත්කාලීන කිරීමක්ම සැමරීමට අවශ්ය වනු ඇත. එක් දිනකදී, ඔබට තවත් ප්රතිපත්තියක් එකතු කිරීමට අවශ්ය වනු ඇත. ඔව්, බොත්තම සහ LinkButton බොහෝ විට ප්රතිපත්තියක් ඇති වනු ඇත, නමුත් TextInput සහ එය මත රඳා පවතී: PasswordInput, EmailInput, NumberInput, DateInput, HellKnowsWhatElseInput.
අන්තිමේදී, එය නරකයි.අපිට ඇති වඩාත් ප්රොප්ස්, එය නරක වනු ඇත.
Clean It Up
පිරිසිදු කරන්න UpAnonymous එකක් නැවත භාවිතා කිරීම ඉතාම අමාරුයි, එබැවින් ඒකට නම දෙන්න.
// MyButton.props.ts
export interface MyButtonProps {
theme?: ComponentTheme;
small?: boolean;
icon?: IconSvg;
rightIcon?: IconSvg;
counter?: number;
disabled?: boolean;
loading?: boolean;
}
අපි අන්තර්ජාලයෙන් පිටතට යැවිය නොහැක.vue
අන්තර්ගතය නිසා ගොනුscript setup
මැජික්, එබැවින් අපි වෙන්ව ඇති නිර්මාණය කිරීමට අවශ්ය.ts
ෆේස්බුක් පිටුවක, අප මෙහි ලබා ඇති දේ බලන්න:
const props = withDefaults(defineProps<MyButtonProps>(), {
theme: ComponentTheme.BLUE,
icon: undefined,
rightIcon: undefined,
counter: undefined,
});
වඩාත් පිරිසිදු, එය නොවේද?එහෙනම් මෙන්න උරුමය:
interface MyLinkButtonProps {
to?: RouteLocationRaw;
href?: string;
}
const props = defineProps<MyButtonProps & MyLinkButtonProps>();
කෙසේ වෙතත්, මෙහි ප්රශ්නයක් ඇත: දැන්, මූලික ප්රොප්ස් ලෙස ප්රතිකාර කරන විටMyLinkButton
's props, ඔවුන් ප්රවර්ධනය නොකරන්නේv-bind=”$attrs”
තවදුරටත්, එබැවින් අප එය කළ යුතුය.
<!-- MyLinkButton.vue -->
<component
:is="props.to ? RouterLink : 'a'"
:to="props.to"
:href="props.href"
class="my-link-button"
>
<MyButton v-bind="props"> <!-- there we go -->
<slot></slot>
</MyButton>
</component>
එය හොඳයි, නමුත් අපි අපට අවශ්ය වඩා ටිකක් පාවිච්චි කරනවා:
ඔබ දකින පරිදි, දැන් අපගේ මූලික බොත්තම දhref
එය ප්රචලිතයක් නොවේ, හුදෙක් ටිකක් අවුල් සහ අතිරේක බයිට්, නමුත් සීතල නොවේ.
<template>
<component
:is="props.to ? RouterLink : 'a'"
:to="props.to"
:href="props.href"
class="my-link-button"
>
<MyButton v-bind="propsToPass">
<slot></slot>
</MyButton>
</component>
</template>
<script lang="ts" setup>
// imports and definitions…
const props = defineProps<MyButtonProps & MyLinkButtonProps>();
const propsToPass = computed(() =>
Object.fromEntries(
Object.entries(props).filter(([key, _]) => !["to", "href"].includes(key))
)
);
</script>
දැන්, අපි ලබා ගත යුතු දේ පමණක් සකස් කරමු, නමුත් ඒ සියලු string literals අපූරු පෙනුමක් නොවේ, ඔවුන් ද?
Interfaces vs Abstract Interfaces
Abstract Interfaces සහ Abstract Interfacesඔබ කවදාවත් නිවැරදි ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොම ඔක්කොමසිතුවිලිඅපගේ ව්යුහයන් ගැන මෙටා දත්ත ලබා ගැනීමට අපට ඉඩ සලසයි. අවාසනාවකට මෙන්, TypeScript හි, පරිගණක ප්රතිඵලදායී වේ; ඔවුන් ක්රියාකාරී වේලාවක පවතින අතර, අපි පහසුවෙන් සොයා ගත නොහැක කුමන ක්ෂේත්රයේ අයිතිය.MyButtonProps
.
ඒ කියන්නේ අපිට විකල්ප දෙකක් තියෙනවා.මුලින්ම, අපි දේවල් සැබෑවටම තබා ගත හැකිය: අපි සෑම අවස්ථාවකදීම ප්රතිපත්තියක් එකතු කරන විටMyLinkButton
අපි එයත් ඉවත් කළ යුතුයිpropsToPass
(අපි ඒ ගැන අමතක වුණත් ඒක ලොකු දෙයක් නෙවෙයි.)
දෙවෙනි ක් රමය වන්නේ පරිශීලකයන් වෙනුවට ඔක්කොම භාවිතා කිරීමයි.ඒක තේරුමක් නැතිව ඇති, නමුත් මට යමක් සකස් කරන්න: එය භයානක නොවේ; මම පොරොන්දු වෙමි.ඒභයානක
// MyButton.props.ts
export const defaultMyButtonProps: MyButtonProps = {
theme: ComponentTheme.BLUE,
small: false,
icon: undefined,
rightIcon: undefined,
counter: undefined,
disabled: false,
loading: false,
};
ඔස්ටේට් නිර්මාණය කිරීම සඳහා පමණක් ඔස්ටේට් නිර්මාණය කිරීම තේරුමක් නැත, නමුත් අපි එය default props සඳහා භාවිතා කළ හැකිය.MyButton.vue
තව තවත් පිරිසිදු වෙයි:
const props = withDefaults(defineProps<MyButtonProps>(), defaultMyButtonProps);
දැන් අපිට update කරන්න ඕනේpropsToPass
INMyLinkButton.vue
:
const propsToPass = computed(() =>
Object.fromEntries(
Object.entries(props).filter(([key, _]) =>
Object.hasOwn(defaultMyButtonProps, key)
)
)
);
මෙම වැඩ කිරීමට, අපි පැහැදිලිව සලකා බැලිය යුතුය සියලුundefined
සහnull
ක්ෂේත් රdefaultMyButtonProps
එහෙම නැත්තම් ‘අනුකූලතාවය’ නොලැබේවි.
මෙම ක්රමයෙන්, ඔබ මූලික අංගයට ප්රතිපත්තිය එකතු කරන විට, ඔබ ආකෘතියට මූලික වටිනාකම් සහිතව එය එකතු කිරීමට අවශ්ය වනු ඇත. එබැවින්, ඔව්, එය නැවත ස්ථාන දෙකක් වන අතර, සමහර විට එය පසුගිය පරිච්ඡේදයේ විසඳුමකට වඩා හොඳ නැත.
I’m Done
මම කලේඑය මාතෘකාවක් නොවේ, නමුත් එය TypeScript හි සීමාවන් තුළ කළ හැකි හොඳම දෙයක් විය හැකිය.
SFC ගොනුව තුළ prop වර්ග ඇති කිරීම වඩාත් හොඳය, නමුත් මම එය වෙනස් ගොනුවකට මාරු කිරීම වඩාත් නරක විය හැකි බව කියන්න බැහැ.ඒත් එය අනිවාර්යයෙන්ම prop නැවත භාවිතය වඩා හොඳ විය, එබැවින් මම එය වැඩ ලෙස හැඳින්වෙන අළුත් සටනක කුඩා ජයග් රහණයක් ලෙස සැලකිලිමත් වනු ඇත.
මෙම ලිපිය GitHub හි ලබා ගත හැක.
Github