props配置项
创建一个学生组件(Student.vue)
<template>
<div>
<h2>学生信息:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
</template>
<script>
export default{
name: 'Student',
data(){
return{
name: '张三',
sex: '男',
age: 21
}
}
}
</script>
<style>
</style>
App.vue
<template>
<div>
<Student></Student>
</div>
</template>
<script>
import Student from './components/Student.vue'
export default{
name: 'App',
components:{Student},
data(){
return{
}
},
}
</script>
<style>
</style>
我们明确一个事:如果你的这个组件使用了多次是什么样的效果呢?
<template>
<div>
<Student></Student>
<hr />
<Student/>
<hr />
<Student/>
</div>
</template>
你要注意,这三个组件是三个VueComponent,三个是互不影响的
有一天有人相中我这个组件了,想拿过来用或展示这些信息名称,但是我的信息跟你不一样;什么都一样就是里面数据不一样,别人也用我的组件,但是怎么把数据传进来?
你得让别人把他的数据从外部带给你的Student组件
那怎么传递数据?
首先你必须在你的
Student组件里做一个准备工作:(1)你不要写name、sex、age的值,不然就敲定死了
<template>
<div>
<h1 v-text="msg"></h1>
<h2>学生信息:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
</template>
<script>
export default{
name: 'Student',
data(){
return{
msg: '我是一个B站用户'
}
}
}
</script>
<style>
</style>
肯定会报错:name、sex、age没有;然后找到组件标签(App.vue里)
App.vue
<template>
<div>
<Student name="李四" sex = "女" age="19"/>
</div>
</template>
还是报错:没有name、sex、age
不仅得传值,你还得在组件里面(Student.vue)‘说一声’:传的东西我要用。怎么说?
就得用
props
简单声明接收
props:['name','sex','age']//简单声明接收
顺序无所谓,只要能对上
这样子可玩性就大了:
- 我有组件
- 我有结构(
template) - 我有样式(
style) - 我有交互(
script、props)
<template>
<div>
<Student name="李四" sex = "女" age="19"/>
<Student name="王老五" sex="男" age="20"/>
</div>
</template>
组件在复用,数据是动态的
但是这里面有坑
我提出一个需求:就是李四,真实的年龄确实是19,但要求是在展示的时候,不让李四是19而是要比真实年龄大一岁是20;穿的就是18展示的偏要是19
如果是:
<h2>学生年龄:{{age+1}}</h2>
结果:
学生年龄:191
有一个问题:
props:['name','age','sex'],
这个的值收哪去了(哪里帮我存着)?
其实是在这个组件的
VueComponent身上存着
之前有一句话:模板里面的可以自动的看到Vue实例实例对象(vm)中的属性;现在写的不是vm而是组件了
如果没有就报错,因为在你的VueComponent里面没有name、age、sex只有msg,如果添加了上面一条语句你会神奇的发现在你的VueComponent里面就出现了name,age和sex,因为是靠props进来的所以你的_data里面还是只有msg,Vue的开发者工具会帮你区分开props配置的和data配置的
为什么你的19+1不是20
因为你传的19是字符串类型的19
- 你可以
强制类型转换:
<h2>学生年龄:{{age*1+1}}</h2>
但这不是最标准的
- 最标准的就是字符类型的19
<Student name="李四" sex = "女" :age="19"/>
:就能解决问题,原理:
::就是v-bind缩写形式。age的值是运行""里面的js表达式执行的结果
如果别人写忘了:能不能限制一下
我们打比喻
<Student name="李四" sex = "女" :age="19"/>
是付款方
props:['name','age','sex']//简单声明接收
这个是收款方
最好的处理就是收款方在收东西的时候,您别啥都收,符合条件的你再收,不符合条件你就(1)该收收,告诉你传的定西不对(2)不收,所以不能这么写
接收的同时对数据进行类型限制
//接收的同时对数据进行类型限制
props:{
name:String,
age: Number,
sex: String,
},
这么写含义就是:我确实要受到name、age、sex但是我还要对它们的类型进行限制(就是写js里面已经存在的内置的构造函数)
还有一种配置形式:
接收的同时对数据进行类型限制+默认值的指定+必要性的限制
//接收的同时对数据进行类型限制+默认值的指定+必要性的限制
props:{
name:{
type: String,//属性的类型 这里String是字符串
required: true//必要的 true表示这个属性是必须传的
},
age:{
type: Number,
default: 99//默认值。不传就直接赋值为99
},
sex:{
type: String,
required: true
}
}
三个元素:
- type: 配置类型
- required: 配置这个属性是否是必须的
- default: 如果你不传我给你一个默认值
一般来说required和default不会同时出现
props和prop:
prop直译过来有属性的意思
props是接收你传过来的属性(prop)
开发中第一种这种形式用的多
但是跟钱相关的组件和一些必要的场景你最好一五一十的将它配置好(接收的同时对数据进行类型限制+默认值的指定+必要性的限制)
另外一个问题
如果我瞎声明,比如:
props:['name','age','sex','phone']
你没配置phon没有报错,但是你VueComponent里面也有phone但值是undefined
还有一个细节是:
接收到的props是不能改的
验证:
<button @click="updateAge">
尝试修改年龄
</button>
methods: {
updateAge(){
this.age = 22
}
},
结果:能改但是最好不要去改
[Vue warn]: Avoid mutating a prop directly
如果一定要修改值:
注意:data里数据的名称不要跟props里面的属性重名,不然会冲突,以外部传进来的为主(优先级props要比data的优先级更高),可以利用优先级
export default{
name: 'Student',
data(){
console.log(this)
return{
msg: '我是一个B站用户',
MyName:this.name
}
},
props:['name','age','sex'],//简单声明接收
}
同理:
data(){
return{
...
MyAge: this.age
}
}
props里的数据是优先被接收的,优先被放在VueComponent上的所以你才可以在data里面读这个age
那要修改:
<template>
<div>
<h1 v-text="msg"></h1>
<h2>学生信息:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{MyAge}}</h2>
<button @click="updateAge">尝试修改Age</button>
</div>
</template>
<script>
export default{
name: 'Student',
data(){
console.log(this)
return{
msg: '我是一个B站用户',
MyAge:this.age
}
},
methods: {
updateAge(){
this.MyAge++
}
},
props:['name','age','sex'],//简单声明接收
}
</script>
<style>
</style>
还有一点就是: 不是什么都可以传
比如说'key'
还有一个默认值问题(default)
验证:
App.vue
<template>
<div>
<Student name="李四" sex = "女" />
<!-- <Student name="王老五" sex="男" age="20"/> -->
</div>
</template>
<script>
//引入School组件
import School from './components/School.vue'
import Student from './components/Student.vue'
export default{
name: 'App',
components:{School,Student},
data(){
return{
msg: '欢迎学习Vue',
}
},
}
</script>
<style>
</style>
Student.vue
<template>
<div>
<h1 v-text="msg"></h1>
<h2>学生信息:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{MyAge}}</h2>
<button @click="updateAge">尝试修改Age</button>
</div>
</template>
<script>
export default{
name: 'Student',
data(){
console.log(this)
return{
msg: '我是一个B站用户',
MyAge:this.age
}
},
methods: {
updateAge(){
this.MyAge++;
}
},
//props:['name','age','sex'],//简单声明接收
//接收的同时对数据进行类型限制
/* props:{
name:String,
age: Number,
sex: String,
}, */
//接收的同时对数据进行类型限制+默认值的指定+必要性的限制
props:{
name:{
type: String,//属性的类型 这里String是字符串
required: true//必要的 true表示这个属性是必须传的
},
age:{
type: Number,
default: 99//默认值。不传就直接赋值为99
},
sex:{
type: String,
required: true
}
}
}
</script>
<style>
</style>
总结
配置props
功能:让组件接收外部传过来的数据
(1).传递数据:
<Demo name="xxx"/>
(2).接收数据:
第一种方法(只接收):
props:[‘name’]
第二种方法(限制类型):
props:{name:String}
第三张方法(限制类型、限制必要性、指定默认值):
props:{name:{type:String,//类型
required:true,//必要性
default:‘老王’//默认值
}
}
备注:props是只读的,Vue底层会检测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后修改data中的数据。
