میدونیم که در vuejs باید اطلاعات رو به صورت prop در اختیار کامپوننت ها قرار بدیم و همینطور نام prop ها رو باید دقیقا در کامپوننت ذکر کنیم. از طرفی vue به ما اجازه میده که با استفاده از یک مکانیزم قدرتمند، این prop ها رو اعتبارسنجی کنیم تا یک لایه امنیتی برای کامپوننت برقرار بشه
اعتبار سنجی دیتاتایپ (Data Type) در prop خیلی ساده است. کافی است پراپرتی type رو برابر با نوع primitiveType موردنظرت قرار بدی
export default {
props: {
propX: Number, // Basic type check
propY: [String, Number], // Multiple Type Check
propZ: {
type: String,
required: true // Required of type string
},
propH: {
type: Number,
default: 100 // set a default value for type Number
},
}
}
برای Complex type ها هم دقیقا همین روش اعتبارسنجی قابل پیاده سازی هست.
export default {
props: {
// Object with a default value
propA: {
type: Object,
// Object defaults (same as array) returns from a function.
default(rawProps) {
return { message: 'hello' }
// This function has access to raw props as the argument.
}
},
propB: {
type: Array, // Array Prop validation
default() {
return []
}
}
}
}
مقادیری که برای پراپرتی type در اعتبارسنجی قابل استفاده است، اینهاست:
علاوه بر ابنها میتونید برای type یک کلاس یا تابع constructor تعریف کنید. Vue اعتبارسنجی این کلاس با مقدار ورودی prop رو با استفاده از instance of چک خواهد کرد.
class Car{
constructor(name, brand) {
this.name = name
this.brand = brand
}
}
// use it as a prop like so
export default {
props: {
author: Car
}
}
Vue همچنین برای prop ها از تابع validate پشتیبانی میکنه. این تابع به مقادیر خام props دسترسی داره و باید یک boolean رو به عنوان نتیجه اعتبارسنجی برگردونه
prop: {
validator(val) {
return ['harry', 'hermione', 'ron'].includes(val)
}
}
گاهی اوقات هم نیازه که مقادیر یک prop رو با استفاده از Enum اعتبارسنجی کنید. از اونجایی که جاوااسکریپت از Enum ها پشتیبانی نمیکنه، میتونید یک Enum رو به این صورت fake کنید:
export const HogwartzGroup = Object.freeze({
GRYFFINDOR: "گریفیندور",
SLYTHERIN: "اسلیترین",
RAVENCLAW: "راونکلاو",
HUFFLEPUFF: "هافلپاف"
});
حالا باید اون رو در جای مناسب import کنید تا هم به عنوان تابع validator و هم به عنوان مقدار پیش فرض مورد استفاده قرار بگیره.
<template>
<span :class="`group--${group}`">
You are in {{ group }} Group of Hogwartz
</span>
</template>
<script>
import { HogwartzGroup } from "./enums";
export default {
props: {
group: {
validator(value) {
return Object.values(HogwartzGroup).includes(value);
},
default: HogwartzGroup.GRYFFINDOR,
},
},
};
</script>
از اونجایی که تایپ اسکریپت به صورت پیش فرض از اینترفیس ها و enum ها پشتیبانی میکنه، ترکیب تایپ اسکریپت با اعتبارسنجی Vue قدرت بیشتری برای اعتبارسنجی propها به ما میده
میتونیم از ترکیب interface و ابزار PropType برای ساخت prototype های پیچیده استفاده کنیم تا مطمئن بشیم آبجکت ارسال شده، از یک ساختار مشخص تبعیت میکنه
<script lang="ts">
import Vue, { PropType } from 'vue'
interface Car{
name: string
brand: string
usage: number
}
const Component = Vue.extend({
props: {
car: {
type: Object as PropType<Car>,
required: true,
validator (car: Car) {
return !!car.name;
}
}
}
})
</script>
در همین مقاله در مورد فیک کردن Enum توضیح دادیم چون جاوااسکریپت از Enum ها پشتیبانی نمیکنه. اما در تایپ اسکریپت دیگه نیازی به این کار نیست چون بصورت پیش فرض Enum ها رو در خودشداره
<script lang="ts">
import Vue, { PropType } from 'vue'
enum HogwartzGroup{
GRYFFINDOR: "گریفیندور",
SLYTHERIN: "اسلیترین",
RAVENCLAW: "راونکلاو",
HUFFLEPUFF: "هافلپاف"
}
export default {
props: {
group: {
type: String as PropType<HogwartzGroup>,
default: HogwartzGroup.GRYFFINDOR,
},
},
};
</script>
همه این مواردی که گفته شد، در Vue 3 هم معتبره. چه در options api و چه در composition api
اما اگر قرار باشه از <script setup> استفاده کنیم قضیه یک مقدار فرق حواهدکرد. در این حالت prop ها باید با استفاده از defineProps تعریف بشن:
<script setup>
const props = defineProps(['car'])
// props.car
</script>
<script setup>
defineProps({
name: String,
usage: Number
})
</script>
اگر هم از تایپ اسکریپت با <script setup> استفاده کنی میتونی تایپ ها رو اینطوری تعریف کنی:
<script setup lang="ts">
defineProps<{
name?: string
usage?: number
}>()
</script>
یا وقتی از interface استفاده کنی:
<script setup lang="ts">
interface Props {
name: string
usage?: number
}
const props = defineProps<Props>()
</script>
اعتبارسنجی dataType ها، به عنوان خط مقدم مقابله با باگ ها در اپلیکیشن های رو به رشد شناخته میشه. ابزار اعتبارسنجی داخلی vue برای prop ها به خودی خود قدرتمند هست. اما ترکیب اون با تایپ اسکریپت میتونه قدرت مانور شما برای کار با کامپوننت ها رو افزایش میده و در نهایت باعث افزایش کیفیت کدنویسی و کاهش باگ های پروژه خواهد شد.