说明
我上一篇文章中基本对vue所有的数据通信方法进行了一个整理归纳。
其实我并没有像传统的那样去罗列,比如父传子有props,ref,子传父为emit,兄弟用$bus等等。
因为在我的实际练习和业务开发中,props,emit,ref等可以实现父子数据互传,这里就涉及一个比较重要的编程思维,函数式编程。
当我们使用props传递一个函数呢,那么子组件调用这个函数时,将参数传入这个函数的调用,那么在父组件中定义的函数不就可以直接获取到了子组件中数据了吗。
其余的两个也是同理,记住,传参有两种,一种是常规变量,一种是函数,传递什么决定了你的功能。
看代码:
props实现父子双向传参:
父组件
<template>
<div>
<p>父组件数字值1:{{ numValue1 }} <el-button @click="addNum">增加</el-button></p>
<p>获取子组件的值:{{ numValue2 }}</el-button></p>
<hr />
<PropsChild :numValue1="numValue1" :numValue2="getChildValue"></PropsChild>
</div>
</template>
<script>
import PropsChild from './child.vue'
export default {
name: 'propsTest',
components: {
PropsChild
},
data() {
return {
numValue1: 0,
numValue2: '父组件默认的值'
}
},
methods: {
addNum() {
this.numValue1++
},
getChildValue(childValue) {
console.log(childValue, '???子组件的数值')
this.numValue2 = childValue
},
getChildValueFun() {
}
}
}
</script>
<style lang="less"></style>
子组件
<template>
<div>
<p>子组件数值:{{ numValue1 }}</p>
<el-input v-model="value" @input="numValue2" class="inputBox"></el-input>
</div>
</template>
<script>
export default {
name: 'propsChild',
props: {
numValue1: {
type: Number,
require: true,
default: 0
},
numValue2:{
type:Function,
default:()=>{}
}
},
data(){
return{
value:'子组件本身的值'
}
}
}
</script>
<style lang="less">
.inputBox{
width:300px;
margin-top:16px;
}
</style>
$emit实现父子双向传参
父组件
<template>
<div>
父组件
<el-input v-model="value" @input="changeInput"></el-input>
<hr>
<EmitChild @getChildValue="getChildValue"></EmitChild>
</div>
</template>
<script>
import EmitChild from './child.vue'
export default{
name:'emitTest',
data(){
return{
value:'父组件默认的值',
childFun:()=>{}
}
},
components:{
EmitChild
},
mounted(){
},
methods:{
getChildValue(childValue){
if(typeof childValue === 'function'){
this.childFun = childValue
}else{
this.value = childValue
}
},
changeInput(value){
this.childFun(value)
}
}
}
</script>
<style lang="less">
</style>
子组件
<template>
<div>
子组件
<el-input v-model="value" @input="changeValue"></el-input>
</div>
</template>
<script>
export default{
name:'emitChild',
data(){
return{
value:'子组件默认的值'
}
},
mounted(){
this.$emit('getChildValue',this.emitFun)
},
methods:{
changeValue(){
this.$emit('getChildValue',this.value)
},
emitFun(value){
this.value = value
}
}
}
</script>
<style lang="less">
</style>
$ref实现父子双向传参
父组件
<template>
<div>
<p>父组件的值:{{ value }} <el-button @click="addNum">增加</el-button> </p>
<hr>
<Child ref="child"></Child>
</div>
</template>
<script>
import Child from './child.vue'
export default{
name:'refTest',
components:{
Child
},
data(){
return{
value:0
}
},
mounted(){
this.$refs.child.getFun(this.funHandler)
},
methods:{
addNum(){
this.value++
this.$refs.child.getValue(this.value)
},
funHandler(value){
this.value = value
}
}
}
</script>
子组件
<template>
<div>
子组件的值{{ value }}
<el-button @click="add">增加</el-button>
</div>
</template>
<script>
export default{
name:'refTest',
data(){
return{
value:0,
funHandler:()=>{}
}
},
methods:{
getValue(val){
this.value = val
},
getFun(funHandler){
this.funHandler = funHandler
},
add(){
this.value ++
this.funHandler(this.value)
}
}
}
</script>
结束语
虽然在开发中,大部分人都会按照既定思维,props和ref父传子,emit子传父,但是我们是开发者,需要有更多的思维在里面,你可以不用,但是你需要去思考,去尝试。
vue和react等框架本身就大量使用了函数式编程的思想,作为使用者的我们,也要同样的将这种思想运用进去,才会有更多优质的代码,才回提升自己。