目录
一、什么是Prop
1.1. Prop传递数据代码示例图
1.2. 演示代码App.vue
1.3. 演示代码UserInfo.vue
二、props 校验
2.1. props校验简单写法
2.1.1. 演示代码App.vue
2.1.2. 演示代码BaseProgress.vue
2.2. props校验完整写法
2.2.1. 演示代码BaseProgress.vue
2.2.2. 演示代码App.vue
三、prop & data、单向数据流
3.1. 单向数据流演示代码
一、什么是Prop
在上一个章节中,我们讲解了组件之间的关系以及组件之间父子通信的解决方案,其中就提到了props的概念,父子关系可以通过props进行通信。那么什么是Prop呢?Prop其实是组件上注册的一些自定义属性,它可以用来向子组件传递数据。
Prop的特点:
1. 可以传递任意数量的prop
2. 可以传递任意类型的prop
1.1. Prop传递数据代码示例图
1.2. 演示代码App.vue
<template>
<div id="app">
<UserInfo
:username="username"
:age="age"
:isSingle="isSingle"
:house="house"
:fav="fav"
></UserInfo>
</div>
</template>
<script>
import UserInfo from './components/UserInfo.vue'
export default {
data () {
return {
username: '王哲晓',
age: 31,
isSingle: true,
house: {
address: '杭州'
},
fav: ['骑行', '写代码', '国漫', '收纳']
}
},
components: {
UserInfo: UserInfo
}
}
</script>
<style>
</style>
1.3. 演示代码UserInfo.vue
<template>
<div class="userinfo">
<h3>我是个人信息组件</h3>
<div>姓名:{{ username }}</div>
<div>年纪:{{ age }}</div>
<div>是否单身:{{isSingle ? '是' : '否'}}</div>
<div>房产:{{house}}</div>
<div>
兴趣爱好:{{fav.join('、')}}
</div>
</div>
</template>
<script>
export default {
props: ['username', 'age', 'isSingle', 'house', 'fav']
}
</script>
<style>
.userinfo {
width: 300px;
border: 3px solid #000;
padding: 20px;
}
.userinfo > div {
margin: 20px 10px;
}
</style>
二、props 校验
props校验为组件的prop指定验证要求,不符合要求的话控制台就会有错误提示,以此帮助开发者快速发现错误。
语法:
① 类型校验:Number、String、Boolean、Array、Object、Function...
② 非空校验
③ 默认值
④ 自定义校验:通过Vue提供的validator校验器可以自定义各种校验逻辑。
2.1. props校验简单写法
2.1.1. 演示代码App.vue
<template>
<div class="app">
<BaseProgress :w="width"></BaseProgress>
</div>
</template>
<script>
import BaseProgress from './components/BaseProgress.vue'
export default {
data() {
return {
width: 50,
}
},
components: {
BaseProgress,
},
}
</script>
<style>
</style>
2.1.2. 演示代码BaseProgress.vue
<template>
<div class="base-progress">
<div class="inner" :style="{ width: w + '%' }">
<span>{{ w }}%</span>
</div>
</div>
</template>
<script>
export default {
props: {
w: Number,
},
}
</script>
<style scoped>
.base-progress {
height: 26px;
width: 400px;
border-radius: 15px;
background-color: #272425;
border: 3px solid #272425;
box-sizing: border-box;
margin-bottom: 30px;
}
.inner {
position: relative;
background: #379bff;
border-radius: 15px;
height: 25px;
box-sizing: border-box;
left: -3px;
top: -2px;
}
.inner span {
position: absolute;
right: 0;
top: 26px;
}
</style>
2.2. props校验完整写法
2.2.1. 演示代码BaseProgress.vue
<template>
<div class="base-progress">
<div class="inner" :style="{ width: w + '%' }">
<span>{{ w }}%</span>
</div>
</div>
</template>
<script>
export default {
props: {
w: {
type: Number,
require: true,
default: 0,
validator (value) {
if (value >= 0 && value <= 100) {
return true
} else {
console.error('传入的prop必须是0-100的数字')
return false
}
}
}
}
}
</script>
<style scoped>
.base-progress {
height: 26px;
width: 400px;
border-radius: 15px;
background-color: #272425;
border: 3px solid #272425;
box-sizing: border-box;
margin-bottom: 30px;
}
.inner {
position: relative;
background: #379bff;
border-radius: 15px;
height: 25px;
box-sizing: border-box;
left: -3px;
top: -2px;
}
.inner span {
position: absolute;
right: 0;
top: 26px;
}
</style>
2.2.2. 演示代码App.vue
<template>
<div class="app">
<BaseProgress :w="width"></BaseProgress>
</div>
</template>
<script>
import BaseProgress from './components/BaseProgress.vue'
export default {
data() {
return {
width: 70,
}
},
components: {
BaseProgress,
},
}
</script>
<style>
</style>
三、prop & data、单向数据流
prop和data共同点:都可以给组件提供数据。
prop和data区别:
data 的数据是自己的 → 随便改
prop 的数据是外部的 → 不能直接改,要遵循 单向数据流
单向数据流:父级 prop 的数据更新,会向下流动,影响子组件。这个数据流动是单向的。
3.1. 单向数据流演示代码
<template>
<div class="app">
<BaseCount :count="count" @changeCount="handleChange"></BaseCount>
</div>
</template>
<script>
import BaseCount from './components/BaseCount.vue'
export default {
components:{
BaseCount
},
data(){
return {
count:100
}
},
methods:{
handleChange(newVal){
// console.log(newVal);
this.count = newVal
}
}
}
</script>
<style>
</style>
<template>
<div class="base-count">
<button @click="handleSub">-</button>
<span>{{ count }}</span>
<button @click="handleAdd">+</button>
</div>
</template>
<script>
export default {
// 1.自己的数据随便修改 (谁的数据 谁负责)
// data () {
// return {
// count: 100,
// }
// },
// 2.外部传过来的数据 不能随便修改
props: {
count: {
type: Number,
},
},
methods: {
handleSub() {
this.$emit('changeCount', this.count - 1)
},
handleAdd() {
this.$emit('changeCount', this.count + 1)
},
},
}
</script>
<style>
.base-count {
margin: 20px;
}
</style>