简介
在Typscript中,我们可以使用PropType进行类型的推断与验证。在日常的开发中我们常常会遇到下面这样的场景:
我们通过request请求从服务端获取了一条数据,数据是个Array的格式,Array中的每个元素又是一个对象,像下面这样的数据
const intro = [
{
title: "标题一",
description: "描述一",
totalNum: 1
},
{
title: "标题二",
description: "描述二",
totalNum: 2
},
{
title: "标题三",
description: "描述三",
totalNum: 3
},
]
此时我们如果封装几个方法在ts文件中,用于处理这样的服务端数据,在传参的过程中,我们可能用一个Array类型去接这个intro数组,但可能项目多人开发,别人在使用这个数组时就不了解这个Array中具体每个元素是什么类型,此时我们使用PropType。
使用
一个小栗子,在非setup语法糖的环境中使用PropType
export interface CompProps {
title: string;
description: string;
totalNum: number;
}
<template>
<div class="backbox">
<div class="introbox">
<div v-for="item in intro">
<div class="intro">title = {{ item.title }}</div>
<div class="intro">description = {{ item.description }}</div>
<div class="intro">totalNum = {{ item.totalNum }}</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from "vue";
import { CompProps } from './prop';
export default defineComponent({
name: "Comp",
props: {
intro: {
type: Array as PropType<CompProps[]>,
required: true
},
}
})
</script>
<style lang="less" scoped>
.introbox {
background-color: antiquewhite;
padding: 20px;
.intro {
display: inline-block;
padding: 20px;
margin: 10px;
background-color: silver;
}
}
</style>
<template>
<div>
<h2>PropType属性的类型验证</h2>
<div>
<Comp :intro="intro"></Comp>
</div>
</div>
</template>
<script setup lang="ts">
import Comp from './component/index.vue';
const intro = [
{
title: "标题一",
description: "描述一",
totalNum: 1
},
{
title: "标题二",
description: "描述二",
totalNum: 2
},
{
title: "标题三",
description: "描述三",
totalNum: 3
},
]
</script>
<style></style>
当我们在上边这段代码的文件中,使用鼠标停在Comp元素上时,此时vscode给出的提示是下面这张图里的样子 :
可以看到intro不是个Array类型,而是PropType<CompProps[]>类型。
一个小栗子,在setup语法糖中使用PropType
export interface CompNum {
num: number;
id: number;
}
<template>
<div class="backbox">
<div class="btnbox" v-for="num in numbs">
<div class="btn" :id="String(num.id)" @click="buttonEvent($event)">{{ num.num }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType, ref } from 'vue';
import { CompNum } from './prop';
const props = defineProps({
nums: {
type: Array as PropType<CompNum[]>,
default: []
}
});
const emits = defineEmits(['update:nums']);
const numbs = ref(props.nums);
const buttonEvent = (event: any) => {
let index = event.target.id;
let arr = numbs.value;
arr[index].num++;
numbs.value = arr;
emits('update:nums', numbs);
}
</script>
<style scoped lang="less">
.btnbox {
display: flex;
flex-direction: row;
background-color: cadetblue;
}
.btn{
display: inline-block;
padding: 25px 40px 25px 40px;
margin: 10px 40px 10px 20px;
background-color: aquamarine;
text-align: center;
}
</style>
<template>
<div>
<h2>PropType属性的类型验证</h2>
<div>
<Btns v-model:nums="numsRef"></Btns>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
import Btns from './component/button.vue';
const intro = [
{
title: "标题一",
description: "描述一",
totalNum: 1
},
{
title: "标题二",
description: "描述二",
totalNum: 2
},
{
title: "标题三",
description: "描述三",
totalNum: 3
},
]
let one = { num: intro[0].totalNum, id: 0 };
let two = { num: intro[1].totalNum, id: 1 };
let three = { num: intro[2].totalNum, id: 2};
const nums = [one, two, three];
const numsRef = ref(nums);
watch(() => numsRef.value,
(value) => {
console.log("newValue = ", value);
},
{deep: true}
);
</script>
<style></style>