props配置

看个school.vue 学校的组件:

<template>
<div class="demo">
<h1>{{msg}}</h1>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<h2>办学时长:{{year}}</h2>
</div>
</template>

<script>
export default{
name:'schoolInfo',
data(){
return{
msg:'欢迎学习Vue',
schoolName:'51cto',
address:'北京',
year:20
}
}
}
</script>

要想复用 school.vue 组件,可以在 app.vue 中多写几个 school 组件标签:

<template>
<div>
<school/>
<school/>
</div>
</template>

<script>
//引入组件
import school from './components/school.vue'

export default{
name:'app',
components:{school}
}
</script>

在  app.vue 中复用了一次:

Vue2(笔记28) - 脚手架 - props配置_Vue

现在有个需求:即复用 school.vue ,还可以改变输出的内容?


props 简单声明接收

这就可以引入  props 配置了,具体改动两个地方:

app.vue 组件中:

<template>
<div>
<school schoolName="51cto" address="北京" year="21"/>
<school schoolName="baidu" address="上海" year="25"/>
</div>
</template>

提示:在 app.vue 组件中,给 school 标签添加数据,就像是在传参;

在 school.vue 组件中:

<template>
<div class="demo">
<h1>{{msg}}</h1>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<h2>办学时长:{{year}}</h2>
</div>
</template>

<script>
export default{
name:'schoolInfo',
data(){
return{
msg:'欢迎学习Vue',
}
},
props:['schoolName','address','year'] // 简单声明接收
}
</script>

引入 props 的数组写法,把各数据放到数组里面;

看效果:

Vue2(笔记28) - 脚手架 - props配置_props_02

这样即实现了组件的复用,还实现了不同数据的呈现;

看下 Vue Devtools :分别查看两个 school 组件的数据; 

Vue2(笔记28) - 脚手架 - props配置_Vue_03

Vue2(笔记28) - 脚手架 - props配置_props_04

使用 Vue Devtools 是不能修改这里的属性值的;


props 限制数据类型

除了数组形式的简单接收,还有一种对象式限制数据类型的方式;

再改下 school.vue 组件:

<template>
<div class="demo">
<h1>{{msg}}</h1>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<h2>办学时长:{{year}}</h2>
</div>
</template>

<script>
export default{
name:'schoolInfo',
data(){
return{
msg:'欢迎学习Vue',
}
},

// props:['schoolName','address','year']
// 限制数据类型
props:{
schoolName:String,
address:String,
year:Number // 限制数据类型
}
}
</script>

提示:这里把 year 的数据类型改为 Number ,这就要求  app.vue 传来的 year 数据类型是 Number,否则会报错:

Vue2(笔记28) - 脚手架 - props配置_Vue_05

Vue 报错了,无效属性:属性"year"的类型检查失败;预期是 Number 类型的值 21,得到的却是字符串类型的 "21"。

解决办法,在传数据的 app.vue 中,加一个 "v-bind" 指令:

<template>
<div>
<school schoolName="51cto" address="北京" v-bind:year="21"/>
<school schoolName="baidu" address="上海" :year="25"/>
</div>
</template>

v-bind:​​ 也可以简写成 ​:​,效果一样;

加了绑定指令后,属性值将变成表达式,传递过去的类型也变成了 Number,效果也就正常了。


props 完整写法

props 还有个完整的写法:设置类型、必要性和默认值;

<template>
<div class="demo">
<h1>{{ msg }}</h1>
<h2>学校名称:{{ schoolName }}</h2>
<h2>学校地址:{{ address }}</h2>
<h2>办学时长:{{ year }}</h2>
</div>
</template>

<script>
export default {
name: "schoolInfo",
data() {
console.log(this);
return {
msg: "欢迎学习Vue",
};
},
// props:['schoolName','address','year']
// props:{
// schoolName:String,
// address:String,
// year:String
// }
// props 完整写法,带3个配置项
props: {
schoolName: {
type: String, // name 类型限制了字符串
required: true, // name 是必要的
},
year: {
type: Number,
default: 20, // 默认值
},
address: {
type: String,
required: false,
}
},
};

提示:完整写法,可以配置数据类型、必传项和默认值三个选项;

数据类型:如果不相符,会报错;

必传项:为 true 为必传数据,为 false 是可传可不传;

默认值:如果没有传数据,则数据为默认值;

required 和 default 两个选项,只写一个就行:意思是,如果是必传项了,就没必要再有默认值了,如果不是必传项的,就设置个默认值;

如果数据类型不对:数据类型跟限制的不相符,会报错;

Vue2(笔记28) - 脚手架 - props配置_Vue_06

报错,属性"year"的类型检查失败;预期是 Number 类型的值 21,得到的却是字符串类型的 "21"。

如果必传项没有数据:该传的不传,会收到报错;

Vue2(笔记28) - 脚手架 - props配置_Vue_07

报错,缺少必要的属性;

如果是有默认值的:即使不传数据,也会被赋为默认值;

props 传值属性一致性

是说在 app.vue 组件中,传递来的属性,在 school.vue 组件中接收时,要能对应的上;

避免出现传来的属性中, pops 没有声明或者声明了更多不存在的数属性:

props:['schoolName','address','year','leader','count']

比如:app.vue 中传来的只有前三个属性的话,后面的两个属性就不要再添加了,否则,可能导致 Vue 的混乱;


props 属性不能使用关键字

部分Vue的关键字,是不能使用的,比如: key 、 ref 都是被 Vue征用的;

<template>
<div>
<school schoolName="51cto" address="北京" year="20" key="1"/>
<school schoolName="baidu" address="上海" year="25" ref="school" />
</div>
</template>

这种是不行的;


操作传来属性值

props 声明的属性,接收到传来的值,是不能被修改的,上面也已经提到;

如果业务需求是需要操作这些属性值的话,该怎么处理呢? 

可以在 data 中声明一个属性,再使用 methods 方法操作 props 属性值,并给 data 中的新属性就可以了;

先改下 app.vue 组件:

<template>
<div>
<school schoolName="51cto" address="北京" :year="20"/>
<school schoolName="baidu" address="上海" :year="25"/>
</div>
</template>

提示:组件的 script 一直没动,所以不写了,只绑定 year 属性,让传递的值变为表达式,参与累加计算;

再改下 school.vue 组件:

<template>
<div class="demo">
<h1>{{ msg }}</h1>
<h2>学校名称:{{ schoolName }}</h2>
<h2>学校地址:{{ address }}</h2>
<h2>办学时长:{{ count }}</h2>
<button @click="addCount">点击按钮累加办学时长</button>
</div>
</template>

<script>
export default {
name: "schoolInfo",
data() {
return {
msg: "欢迎学习Vue",
count: this.year
};
},
methods:{
addCount(){
this.count++
}
},
props:['schoolName','address','year']
};
</script>

提示1:使用了简易声明的 props ;

提示2:在 data 中新建了 count 来接收传来的属性值,同时模板插值中也要把 year 改成新属性 count;

提示3:新建 methods 方法,通过 addCount() 方法来实现累加;

看下效果:

Vue2(笔记28) - 脚手架 - props配置_props_08

这样就实现了,组件的复用,传递不同的数据,还能操作这些数据了;


【props 总结】

功能:让组件接收外部传过来的数据;

1) 传递数据 :   ​<Demo name="xxx" />

2) 接收数据:

1、第一种方式(只接收):

props:['name']

2、第二种方式(限制类型):

props:{
name:String,
}

3、第三种方式(限制类型、限制必要性、指定默认值)

props:{
name:{
type:String, // 类型
required:true, // 必要性
default:'jack' // 默认值
}
}

备注:props 是只读的,Vue 底层会监测你对 props 修改,如果进行了修改,就会发出警告,若业务需要确实需要修改,那么请复制 props 的内容到 data 中一份,然后再修改 data 中的数据 ;