7.1 defineProps接收参数
props最主要的作用就是接收父组件的传参,在Vue2里直接使用props接收参数即可,而在vue3需要依赖defineProps来接参。
这里举一个简单的例子,父组件传一个数组给子组件渲染出来。下面分别对比一下2和3的语法:
父组件Person.vue:
xml
<template>
<div class="person">
<Child :list="personList"></Child>
</div>
</template>
<script lang="ts" setup name="Person">
import Child from './Child.vue'
let personList = [
{id:'asyud7asfd01',name:'张三',age:60},
{id:'asyud7asfd02',name:'李四',age:18},
{id:'asyud7asfd03',name:'王五',age:5}
]
</script>
子组件Child.vue:
css
<template>
<div class="child">
<ul>
<li v-for="p in list" :key="p.id">
{{ p.name }} -- {{ p.age }}
</li>
</ul>
</div>
</template>
1、Vue2
Vue2的接参方式是把参数放在props里。
xml
<script>
export default {
props: {
list: null
}
}
</script>
这里先不限定接参的类型,在后面会详细讲解。
2、Vue3
Vue3的接参方式有点不同,它需要依赖defineProps函数。它里面传入一个数组,里面的每一项是接参的参数名。
xml
<script lang="ts" setup>
defineProps(['list'])
</script>
7.2 使用props参数
对Vue2来说,props的参数跟定义在data里的属性一样,直接使用this.即可读取;但是Vue3相对麻烦一些,它需要先把props存起来,然后再使用。
1、Vue2
xml
<script>
export default {
props: {
list: null
},
mounted() {
console.log(this.list);
}
}
</script>
2、Vue3
Vue3可得注意一下,不能直接使用props里的参数,必须先定义一个变量把props存起来,然后再使用。我们先打印一下整个props的结构:
xml
<script lang="ts" setup>
const propParam = defineProps(['list'])
console.log(propParam)
</script>
实际上它帮我们包裹成一个对象,我们如果要使用,就以键值对来读取即可,例如上面读取list参数,那就是propParam.list。
7.3 限制props参数类型
1、Vue2
Vue2添加类型限制有两种方式,一种是直接在冒号:后面加类型,一种是通过对象里的type进行设置。
xml
<script>
export default {
props: {
/* 第一种 */
// list: Array,
/* 第二种 */
list: {
type: Array
}
}
}
</script>
2、Vue3
Vue3的类型限制是通过defineProps的泛型实现。它里面传入一个对象,通过键值对的方式对每一个参数进行设置。
ini
<script lang="ts" setup>
const propParam = defineProps<{list: Array<object>}>();
</script>
当然如果想使用ts的接口或者自定义类型来进行设置也是可以的,用法一样。
src/types/index.ts:
typescript
// 定义一个接口,用于限制person对象的具体属性
export interface PersonInter {
id:string,
name:string,
age:number
}
/* 一个自定义类型 */
export type Persons = PersonInter[]
src/components/child.vue:
xml
<script lang="ts" setup>
import {type Persons} from '@/types'
const propParam = defineProps<{list: Persons}>();
</script>
注意:使用了泛型来限制参数类型之后,defineProps方法里就不要传数组了,因为它通过泛型就已经知道你要接收的参数了。例如没有添加限制的写法是defineProps(['list']),添加类型限制后就写成defineProps<{list: Persons}>()。
7.4 限制是否必传
1、Vue2
vue2限制参数必传是通过设置required为true,它默认值是非必传的。
xml
<script>
export default {
props: {
list: {
type: Array,
required: true
}
}
}
</script>
2、Vue3
vue3分两种情况:第一种是没有限制类型,把数组传入到defineProps里,比如defineProps(['list']),那么它默认是非必传的;第二种是使用泛型限制参数类型,比如defineProps<{list: Persons}>(),则它默认是必传的。如果想设置它为非必传,则在限制类型的冒号:前加一个?,写成?:,这也是ts的一种语法。
(1)第一种情况:不限制类型
xml
<script lang="ts" setup>
defineProps(['list'])
</script>
(2)第二种情况:使用泛型限制类型
xml
<script lang="ts" setup>
import {type Persons} from '@/types'
const propParam = defineProps<{list: Persons}>()
</script>
我们通过?:即可设置成非必传属性。
xml
<script lang="ts" setup>
import {type Persons} from '@/types'
const propParam = defineProps<{list?: Persons}>()
</script>
7.5 设置默认值
1、Vue2
Vue2的默认值是通过default进行设置的,它同样有两种情况,一种是基本类型,一种是引用类型。基本类型直接写入默认值,而引用类型需要通过函数返回的形式设置默认值。
xml
<script>
export default {
props: {
// 基本类型
num: {
type: Number,
default: 123
},
// 对象类型
obj: {
type: Object,
default: () => {
return {id: 123, name: 'test'}
}
},
// 数组类型
list: {
type: Array,
default: () => [{id: 123, name: 'test'}]
},
// 函数类型
fn: {
type: Function,
default: () => {
console.log(123)
}
}
}
}
</script>
2、Vue3
Vue3的默认值需要依赖withDefaults函数,withDefaults函数需要传入两个参数,第一个参数把整个defineProps的内容传进去,第二个参数用来设置默认值,它是一个对象,通过键值对的方式对每个属性进行设置。
注意:Vue3跟Vue2对基本类型和引用类型的设置是一样的,基本类型可以直接设置,引用类型需要包裹一个函数返回,像上述代码没有包裹函数则提示警告,只需要添加函数返回即可。
xml
<script lang="ts" setup name="Person">
import {type Persons} from '@/types'
const propParam = withDefaults(defineProps<{list?:Persons}>(), {
list: () => [{id:'ausydgyu01',name:'康师傅·王麻子·特仑苏',age:19}]
})
</script>
父组件Person.vue:
xml
<template>
<div class="person">
<Child></Child>
</div>
</template>
7.6 示例代码
文件目录:src_07_props