vue3中组件的props类型
这篇文章详细介绍了 Vue 3 中的 props
类型定义,包括基本类型、高级类型、复杂数据结构以及常见的配置选项。以下是整理后的版本,主要突出 Vue 3 中 props
的类型定义方式、使用方法和相关注意事项:
# Vue 3 中各类型 props
的定义示例
# 1. 基本数据类型
# 1.1 String
- 字符串类型
<template>
<div>{{ myString }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
myString: {
type: String,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent myString="Hello, Vue 3!" />
# 1.2 Number
- 数字类型
<template>
<div>{{ myNumber }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
myNumber: {
type: Number,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :myNumber="123" />
# 1.3 Boolean
- 布尔类型
<template>
<div>{{ isActive }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
isActive: {
type: Boolean,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :isActive="true" />
# 1.4 Array
- 数组类型
<template>
<ul>
<li v-for="item in items" :key="item">{{ item }}</li>
</ul>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
items: {
type: Array,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
传递值:
<ChildComponent :items="['Item 1', 'Item 2', 'Item 3']" />
# 1.5 Object
- 对象类型
<template>
<div>{{ user.name }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
user: {
type: Object,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :user="{ name: 'John Doe', age: 30 }" />
# 1.6 Function
- 函数类型
<template>
<button @click="handleClick">Click me</button>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
handleClick: {
type: Function,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :handleClick="myFunction" />
在父组件中:
const myFunction = () => alert('Button clicked!');
# 1.7 Symbol
- 符号类型
<template>
<div>{{ symbolProp }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
symbolProp: {
type: Symbol,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :symbolProp="Symbol('unique')" />
# 2. 高级数据类型
# 2.1 oneOf
- 限定某个 prop 为固定值之一
<template>
<div>{{ status }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
status: {
type: String,
required: true,
validator(value) {
return ['success', 'error', 'pending'].includes(value)
}
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
传递值:
<ChildComponent status="success" />
# 2.2 oneOfType
- 限定某个 prop 为多种类型之一
<template>
<div>{{ value }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
value: {
type: [String, Number],
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :value="'A string value'" />
<ChildComponent :value="100" />
2
# 2.3 自定义验证(validator
)
<template>
<div>{{ age }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
age: {
type: Number,
required: true,
validator(value) {
return value >= 18 && value <= 100
}
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
传递值:
<ChildComponent :age="25" />
# 2.4 default
- 设置默认值
<template>
<div>{{ title }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
title: {
type: String,
default: 'Default Title'
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :title="'Custom Title'" />
<!-- 或者不传递 title 时会使用默认值 -->
<ChildComponent />
2
3
# 2.5 required
- 指定 prop 为必填项
<template>
<div>{{ username }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
username: {
type: String,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
传递值:
<ChildComponent :username="'john_doe'" />
# 3. 复杂类型和组合
# 3.1 数组中的复杂对象
<template>
<div>
<div v-for="user in users" :key="user.name">{{ user.name }} - {{ user.age }}</div>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
users: {
type: Array,
required: true
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
传递值:
<ChildComponent :users="[{ name: 'John', age: 30 }, { name: 'Jane', age: 28 }]" />
# 3.2 对象中的嵌套数据结构
<template>
<div>{{ product.name }} - {{ product.price }}</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
product: {
type: Object,
required: true,
validator(value) {
return value && typeof value.name === 'string' && typeof value.price === 'number'
}
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
传递值:
<ChildComponent :product="{ name: 'Laptop', price: 999.99 }" />
# 4. 传入的 prop
是只读的
props
是子组件的只读数据,不能直接修改。如果需要修改,可以通过本地副本或计算属性来实现。
<template>
<button @click="handleClick">Click me</button>
<div>{{ localUserNum }}</div>
</template>
<script setup>
import { ref, defineProps, defineEmits } from 'vue'
const props = defineProps({
userNum: {
type: Number,
required: true,
default: 10
}
})
const emit = defineEmits()
const localUserNum = ref(props.userNum)
const handleClick = () => {
localUserNum.value++
emit('change-num', localUserNum.value)
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 5. v-model
在 Vue 2 和 Vue 3 中的区别
- 在 Vue 2 中,
v-model
将父组件的数据传递给子组件作为value
,并通过input
事件更新父组件。 - 在 Vue 3 中,
v-model
的默认 prop 名称变为modelValue
,事件变为update:modelValue
。
# 总结
通过 Vue 3 中的 props
,可以定义多种类型的数据,并通过设置验证器、默认值等确保数据的有效性。在使用时,props
是只读的,不能直接修改。如果需要修改,应使用本地副本或者计算属性,确保数据流的单向性。事件也默认变为 update:modelValue
,这使得 v-model
的用法更加灵活和清晰。下面是 Vue 3 中 v-model
的一些典型使用示例:
事件也默认变为 update:modelValue
,这使得 v-model
的用法更加灵活和清晰。下面是 Vue 3 中 v-model
的一些典型使用示例:
# Vue 3 中 v-model
的使用
# 1. 基础使用
<!-- 父组件 -->
<template>
<ChildComponent v-model="userNum" />
</template>
<script setup>
import { ref } from 'vue'
const userNum = ref(10)
</script>
<!-- 子组件 -->
<template>
<button @click="increment">Increase</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
modelValue: {
type: Number,
required: true
}
})
const emit = defineEmits()
const increment = () => {
emit('update:modelValue', props.modelValue + 1) // 触发 update:modelValue 更新父组件的数据
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
在 Vue 3 中,父组件通过 v-model="userNum"
绑定到 ChildComponent
的 modelValue
prop 上,并且通过 update:modelValue
事件将更新后的值传递给父组件。
# 2. 自定义 v-model
的 prop
和 event
名称
Vue 3 允许自定义 v-model
的 prop
名称和事件名称。这可以通过 modelValue
外的其他属性名来实现。
<!-- 父组件 -->
<template>
<ChildComponent v-model:customValue="userNum" />
</template>
<script setup>
import { ref } from 'vue'
const userNum = ref(10)
</script>
<!-- 子组件 -->
<template>
<button @click="increment">Increase</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
customValue: {
type: Number,
required: true
}
})
const emit = defineEmits()
const increment = () => {
emit('update:customValue', props.customValue + 1) // 自定义事件名称
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
在这个例子中,父组件通过 v-model:customValue
来传递数据,而子组件接收 customValue
prop,并通过 update:customValue
事件更新父组件的值。
# 3. 使用 v-model
绑定布尔值
如果你需要通过 v-model
绑定布尔值,Vue 3 同样支持这种用法:
<!-- 父组件 -->
<template>
<ChildComponent v-model="isActive" />
</template>
<script setup>
import { ref } from 'vue'
const isActive = ref(false)
</script>
<!-- 子组件 -->
<template>
<button @click="toggleActive">Toggle</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
modelValue: {
type: Boolean,
required: true
}
})
const emit = defineEmits()
const toggleActive = () => {
emit('update:modelValue', !props.modelValue) // 更新布尔值
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
在这个例子中,父组件将布尔值 isActive
与子组件的 modelValue
绑定,子组件通过触发 update:modelValue
来改变该布尔值。
# 总结 Vue 2 和 Vue 3 中 v-model
的差异
- Vue 2:使用默认的
value
prop 和input
事件。 - Vue 3:默认使用
modelValue
作为 prop 名称,update:modelValue
作为事件名。这使得v-model
更加灵活,支持多个模型绑定。
Vue 3 提供了更强的自定义功能,可以灵活地设置不同的 prop 名称和事件名。对于复杂的组件和用例,Vue 3 的 v-model
使得数据传递更加清晰和易于管理。
# 使用 v-model
的注意事项
- 单向数据流:即使在使用
v-model
时,数据流仍然是单向的,子组件通过update:modelValue
事件向父组件传递更新,而父组件通过v-model
绑定数据。 - 默认值:父组件可以通过绑定
v-model
来传递默认值给子组件,但如果没有传递,子组件的modelValue
prop 会使用默认值(通过default
配置或其他方法)。 - 避免直接修改 props:和其他 props 一样,
modelValue
是只读的,不能直接修改。修改值应该通过事件通知父组件。
# 自定义 v-model
的高级场景
# 1. 处理多重 v-model
绑定
Vue 3 支持多个 v-model
绑定,允许你在同一个组件中处理多个 modelValue
。例如,处理一个表单中的多个字段:
<!-- 父组件 -->
<template>
<ChildComponent v-model:name="name" v-model:age="age" />
</template>
<script setup>
import { ref } from 'vue'
const name = ref('John')
const age = ref(30)
</script>
<!-- 子组件 -->
<template>
<input v-model="name" />
<input v-model="age" />
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
name: String,
age: Number
})
const emit = defineEmits()
// 更新 name 和 age 的方法
const updateName = (newValue) => {
emit('update:name', newValue)
}
const updateAge = (newValue) => {
emit('update:age', newValue)
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
在这个示例中,父组件通过 v-model:name
和 v-model:age
绑定了两个字段,子组件通过 update:name
和 update:age
事件分别更新这两个字段。
# 总结
Vue 3 中的 v-model
在 Vue 2 的基础上进行了增强,提供了更多的灵活性和自定义选项。通过使用 modelValue
和 update:modelValue
,以及支持多个 v-model
绑定,可以更方便地处理复杂的数据流和组件交互。