代码中的p-8
,mt-8
等,都是自己写的工具类,复制代码的同学,可以自行删掉。
复习一下组件间通信
父传子:props
子传父:$emit
父获取子数据或者调用子方法:this.$refs.child
,this.$children
子获取父属性或者调用父方法:this.$parent
祖先传后代:provide
,inject
任意组件:Vuex
,$bus
一、通过自定义事件
this.$emit("event", value)
这里因为大家经常使用,我就直接用对象类型的props做演示了。
- 父组件
<template>
<div class="test p-8">
<div class="header p-8">
<el-button type="primary" @click="myValue.age++">增加</el-button>
{{ myValue }}
</div>
<div class="container mt-8">
<inner-comp
:myValue="myValue"
@handleChange="handleChange"
/>
</div>
</div>
</template>
<script>
import InnerComp from "./innerComp";
export default {
name: "test",
components: {InnerComp},
data() {
return {
myValue: {
name: "花生",
age: 18
}
}
},
methods: {
handleChange(val) {
this.myValue = val
}
}
}
- 子组件
<template>
<div class="innerComp p-8">
<el-button type="danger" @click="changeAge">减少</el-button>
<el-button type="danger" @click="changeName">修改名字</el-button>
{{ value }}
</div>
</template>
<script>
export default {
name: "innerComp",
props: {
myValue: {
require: true,
}
},
data() {
return {
value: this.myValue,
callback: () => {
this.$emit("handleChange", this.value)
}
}
},
methods: {
changeAge() {
this.value.age--
this.callback()
},
changeName() {
this.value.name += '~'
this.callback()
}
}
}
</script>
- 结果
二、通过v-model
单个props
- 父组件
<template>
<div class="test p-8">
<div class="header p-8">
<el-button type="primary" @click="myValue++">增加</el-button>
{{myValue}}
</div>
<div class="container mt-8">
<inner-comp
v-model="myValue"/>
</div>
</div>
</template>
<script>
import InnerComp from "./innerComp";
export default {
name: "test",
components: {InnerComp},
data() {
return {
myValue: 10
}
}
}
- 子组件
<template>
<div class="innerComp p-8">
<el-button type="danger" @click="value--">减少</el-button>
{{ value }}
</div>
</template>
<script>
export default {
name: "innerComp",
model: {
prop: "myValue",
event: "change"
},
props: {
myValue: {
require: true,
type: Number,
default: 11
}
},
computed: {
value: {
get() {
return this.myValue
},
set(val) {
this.$emit("change", val)
}
}
},
}
对象类型的props
- 父组件
<template>
<div class="test p-8">
<div class="header p-8">
<el-button type="primary" @click="myValue.age++">增加</el-button>
{{ myValue }}
</div>
<div class="container mt-8">
<inner-comp
v-model="myValue"/>
</div>
</div>
</template>
<script>
import InnerComp from "./innerComp";
export default {
name: "test",
components: {InnerComp},
data() {
return {
myValue: {
name: "花生",
age: 18
}
}
}
}
</script>
- 子组件
<template>
<div class="innerComp p-8">
<el-button type="danger" @click="value.age--">减少</el-button>
<el-button type="danger" @click="value.name +='~'">修改名字</el-button>
{{ value }}
</div>
</template>
<script>
export default {
name: "innerComp",
model: {
prop: "myValue",
event: "change"
},
props: {
myValue: {
require: true,
}
},
computed: {
value: {
get() {
return this.myValue
},
set(val) {
this.$emit("change", val)
}
}
},
}
</script>
- 结果
三、通过.sync修饰符
- 父组件
<template>
<div class="test p-8">
<div class="header p-8">
<el-button type="primary" @click="myValue.age++">增加</el-button>
{{ myValue }}
</div>
<div class="container mt-8">
<inner-comp
:myValue.sync="myValue"
/>
</div>
</div>
</template>
<script>
import InnerComp from "./innerComp";
export default {
name: "test",
components: {InnerComp},
data() {
return {
myValue: {
name: "花生",
age: 18
}
}
},
}
</script>
- 子组件
<template>
<div class="innerComp p-8">
<el-button type="danger" @click="changeAge">减少</el-button>
<el-button type="danger" @click="changeName">修改名字</el-button>
{{ value }}
</div>
</template>
<script>
export default {
name: "innerComp",
props: {
myValue: {
require: true,
}
},
data() {
return {
value: this.myValue,
}
},
methods: {
changeAge() {
this.value.age--
this.$emit('update:myValue',this.value)
},
changeName() {
this.value.name += '~'
this.$emit('update:myValue',this.value)
}
}
}
</script>
官方提示:
四、provide和inject
官⽹上说provide 和 inject 绑定并不是可响应的。这是刻意为之的。然⽽,如果你传⼊了⼀个可监听的对象,那么其对象的属性还是可响应的。
- 父组件
<template>
<div class="test p-8">
<div class="header p-8">
<el-button type="primary" @click="myValue.age++">增加</el-button>
{{ myValue }}
</div>
<div class="container mt-8">
<inner-comp/>
</div>
</div>
</template>
<script>
import InnerComp from "./innerComp";
export default {
name: "test",
components: {InnerComp},
data() {
return {
myValue: {
name: "花生",
age: 18
}
}
},
provide(){
return{
info:this.myValue
}
}
}
</script>
- 孙子组件
<template>
<div class="childComp p-8">
<el-button type="danger" @click="changeAge">减少</el-button>
<el-button type="danger" @click="changeName">修改名字</el-button>
{{ value }}
</div>
</template>
<script>
export default {
name: "childComp",
data() {
return {
value: this.info,
}
},
methods: {
changeAge() {
this.value.age--
},
changeName() {
this.value.name += '~'
}
},
inject:["info"]
}
</script>