vue
父组件与子组件通信
父组件
<template>
<div>
<div>父组件</div>
<child :message="parentMsg"></child>
</div>
</template>
<script>
// 引入child组件
import child from './child'
export default {
data () {
return {
// 父组件要传入子组件的值
parentMsg: 'a message from parent'
}
},
// 注册子组件
components: {
child
}
}
</script>
子组件
<template>
<div>
<div>{{message}}(子组件)</div>
</div>
</template>
<script>
export default {
// 方式一 无校验
props: ['message'],
// 方式二 校验类型
props: {
message: String
},
// 方式三 校验多个类型
props: {
message: [String, Number]
},
// 方式四 校验默认值
props: {
message: {
type: String,
default: 'hello world'
}
},
// 方式五 校验必传
props: {
message: {
type: String,
required: true
}
},
// 方式六 校验对象类型且设置默认值
props: {
message: {
type: Object,
default: function () {
return { msg: 'hello world' }
}
}
},
// 方式七 自定义校验
props: {
message: {
validator: function (value) {
return value < 100;
}
}
}
}
</script>
使用情况
- 当渲染列表时,假如每项共用同一个开关变量,此时就会出现操作某一项,各个项都出现相同的行为动作,不符合实际的需求,此时需要每项拥有各自独有的开关变量,将列表项提取为一个组件,循环渲染组件即可解决问题。
注意事项
props验证类型
String Number Boolean Symbol Object Function Array
props命名规范
1、在html文件中的父组件,属性名需要使用中划线写法
原因:HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。
在vue文件中的父组件,属性名使用中划线或者小驼峰都可以
<template>
<div>
<div>父组件</div>
<child :child-message="parentMsg"></child>
</div>
</template>
<template>
<div>
<div>父组件</div>
<child :childMessage="parentMsg"></child>
</div>
</template>
2、子组件props属性声明时,可以使用小驼峰或者中划线写法。
<template>
<div>
<div>{{childMessage}}(子组件)</div>
</div>
</template>
<script>
export default {
// 方式一
props: ['child-message'],
props: ['childMessage'],
// 方式二
props: {
'child-message': String
},
props: {
childMessage: String
}
}
</script>
3、子组件使用props属性时,只能使用小驼峰写法。
<template>
<div>
<div>{{childMessage}}(子组件)</div>
</div>
</template>
综上所述,建议父组件属性使用中划线,子组件props使用小驼峰。
单向数据流
prop是单向绑定的,当父组件的属性变化时,将传递给子组件;子组件属性变化时,父组件属性不变,且浏览器提示警告。
改变props数据
1、子组件将props数据作为局部数据来使用
// 定义一个局部变量,并用 prop 数据进行初始化
props: {
love: Boolean
},
data () {
return {
isLove: this.love
}
}
2、子组件将props数据处理后输出
props: ['name'],
computed: {
lowerName: function () {
return this.name.toLowerCase()
}
}
3、使用props初始化data中的数据变量,使用watch监听props数据变化并更新
props: {
love: Boolean
},
data () {
return {
isLove: this.love
}
}
watch: {
love () {
this.isLove = this.love
}
}
子组件与父组件通信
方式一
父组件
<template>
<div>
<div>父组件</div>
<child @refreshList="getList"></child>
</div>
</template>
<script>
// 引入child组件
import child from './child'
export default {
// 注册子组件
components: {
child
},
methods: {
getList: function (str) {
console.log(str)
}
}
}
</script>
子组件
<template>
<div>
<div @click="changeSomeThing(9)">子组件</div>
</div>
</template>
<script>
export default {
methods: {
changeSomeThing: function (id) {
this.$emit('refreshList', id)
}
}
}
</script>
方式二
父组件
<template>
<div>
<div>父组件</div>
<child :refreshList="getList"></child>
</div>
</template>
<script>
// 引入child组件
import child from './child'
export default {
// 注册子组件
components: {
child
},
methods: {
getList: function (str) {
console.log(str)
}
}
}
</script>
子组件
<template>
<div>
<div @click="changeSomeThing(9)">子组件</div>
</div>
</template>
<script>
export default {
props: {
refreshList: {
type: Function,
default: null
}
},
methods: {
changeSomeThing: function (id) {
if (this.refreshList) {
this.refreshList(id)
}
}
}
}
</script>
使用情况
1、当子组件的操作改变了父组件展示的数据后,需要重新调用父组件的方法,刷新页面。
但是不建议如此做,原因如下:
1>假如只改变组件的局部数据后,没必要刷新父组件整个页面,只刷新组件的局部数据即可。
2>刷新父组件的数据会导致响应速度特别慢,十分影响用户体验。
3>耦合度太高,不符合组件化的思想,应将父组件的数据传递为子组件的数据,再由子组件去控制这些数据。
解决办法:
1》将调用父组件的接口改为调用子组件局部数据的接口,将数据作为子组件的局部数据。
2》假如数据的改变可预测,可以不调用接口,直接将数据进行相应的变化并展示,响应速度会更快。