一丶父传子通过传属性
1.父组件给子组件间传值,只需给子组件传一个属性。子组件需要在props中接收。接收之后就可以正常使用。
父组件:
<template>
<div>
parent
<!-- 传一个myname属性给child组件值为字符串'parent' -->
<child myname="parent"></child>
</div>
</template>
<script>
import child from './Child.vue';
export default {
components:{
child
}
}
</script>
子组件:
<template>
<div>
child
{{myname}}
</div>
</template>
<script>
export default {
// 子组件接收props可以是数组形式,不能明确需要接收的属性的类型
// props:['myname'],
// 对象形式可以明确接收属性的类型,如果父组件传的不是该类型就会报错。
// default父组件不传值时的默认值
props:{
myname:{
type:String,
default:''
}
}
}
</script>
二丶子传父通过事件
1.子组件给父组件传值,需要给该子组件绑定好自定义事件,当子组件触发该事件的时候,即可给父组件传值。
父组件:
<template>
<div>
<!-- 给子组件绑好自定义事件event,当子组件需要给父组件传值时,触发该事件就行 -->
<child @event="handleEvent"></child>
<child2 v-show="isShow"></child2>
</div>
</template>
<script>
import child from './Child.vue'
import child2 from './Child2.vue';
export default {
data(){
return {
isShow:true
}
},
methods:{
handleEvent(data){
// data里就是子组件传过来的数据
console.log(data) // "传的数据"
this.isShow=!this.isShow
}
},
components:{
child,
child2
}
}
</script>
子组件:
<template>
<div>
child
<button @click="handleShow">点击让child2显示隐藏</button>
</div>
</template>
<script>
export default {
methods:{
handleShow(){
// 触发该事件,即可传值给父组件
this.$emit("event","传的数据")
}
}
}
</script>
三丶中间人模式
1.中间人模式适用于亲兄弟组件之间通信
2.兄弟组件之间传值通过中间人模式,子组件1先通过事件把值传给父组件之后,父组件再通过属性把值传给子组件2。
父组件:
<template>
<div>
parent
<!-- 给子组件绑好自定义事件event,当子组件需要给父组件传值时,触发该事件就行 -->
<child @event="handleEvent"></child>
// 通过属性把接收到的值传给child2
<child2 :mytext="text"></child2>
</div>
</template>
<script>
import child from './Child.vue'
import child2 from './Child2.vue';
export default {
data(){
return {
text:''
}
},
methods:{
handleEvent(data){
console.log(data) // 传过来的数据
// 把child传过来的值赋值给text状态,然后通过属性传给child2
this.text=data
}
},
components:{
child,
child2
}
}
</script>
child组件(传数据):
<template>
<div>
child
<button @click="handleClick">点击给child2传值</button>
</div>
</template>
<script>
export default {
methods:{
handleClick(){
// 触发该事件,即可传值给父组件
this.$emit("event","传的数据aashdhsdbhhhh")
}
}
}
</script>
child2组件(接收数据):
<template>
<div>
child2
<div>
{{mytext}}
</div>
</div>
</template>
<script>
export default {
// props接收父组件传来的属性即可
props:["mytext"]
}
</script>
四丶bus中央事件总线(vue3无)
1.on订阅,emit发布
2.适用于各种组件之间通信。
父组件:
<template>
<div>
parent
<child></child>
<child2></child2>
</div>
</template>
<script>
import Vue from 'vue'
import child from './Child.vue'
import child2 from './Child2.vue'
export default {
beforeCreate(){
// 根组件创建之前初始化
Vue.prototype.$bus=this
},
components:{
child,
child2
}
}
</script>
child组件(发布者):
<template>
<div>
child
<button @click="handleClick">点击给child2传值</button>
</div>
</template>
<script>
export default {
methods:{
handleClick(){
// 触发该事件(发布),即直接传值给监听好getdata事件的组件。第二个参数是传的值
this.$bus.$emit("getData","ahdsjahdksa")
}
}
}
</script>
child2组件(订阅者):
<template>
<div>
child2
<div>
{{mydata}}
</div>
</div>
</template>
<script>
export default {
mounted(){
// 组件创建完成上树之后就监听好getdata事件(订阅)等待触发
this.$bus.$on("getData",(data)=>{
// 发布着触发该事件走回该调,data中就是传过来的数据
console.log(data)
this.mydata=data
})
},
data(){
return {
mydata:''
}
}
}
</script>
五丶vuex状态统一管理
1.在store中state里的所有状态所有组件都是可以访问到并且修改的。
@/store/index.js:
import { createStore } from 'vuex'
export default createStore({
state: {
title:"Vue3"
},
mutations: {
changeTitle(state,newvalue){
state.title=newvalue
}
}
})
组件1:
<template>
<div>
<button @click="handleClick">点击改变公共状态的值</button>
</div>
</template>
<script>
export default {
methods:{
handleClick(){
// 在js中用this.$store.state.属性来访问公共的状态
console.log(this.$store.state.title)
// 修改的时候可以直接修改,但是不知道是哪个组件修改了,不好统一管理
// 所以用this.$store.commit来通知mutation触发函数来修改,这样方便管理,
// 可以通过开发者工具监测到,找bug的时候好找
this.$store.commit('changeTitle',"大家好")
}
}
}
</script>
组件2:
<template>
<div>
<!-- 在child组件中修改了title之后这里访问到的就是修改后的 -->
parent---{{$store.state.title}}
<child></child>
<child2></child2>
</div>
</template>
<script>
import child from './Child.vue'
import child2 from './Child2.vue';
export default {
mounted(){
console.log(this.$store.state.title) // "大家好"
},
components:{
child,
child2
}
}
</script>
六丶provide和inject(依赖注入)
1.在vue-composition-api中的新功能provide丶inject依赖注入功能。
根组件共享自己的状态,它的子组件注入之后就可以直接访问和修改。缺点就是子组件都可以访问都可以修改出错了不知道出在哪里。
App根组件:
<template>
<div>
<h1>hello-vue3-{{mytext}}</h1>
</div>
</template>
<script>
import { provide, ref } from 'vue'
export default {
setup(){
const mytext = ref("aaaaaa")
// 共享自己的状态
provide("kerwin",mytext)
return {
mytext
}
}
}
</script>
子组件:
<template>
<div>
detail-{{mytext}}
</div>
</template>
<script>
import { inject, onMounted } from 'vue';
export default {
setup(){
onMounted(()=>{
// 子组件注入,注入之后就可以访问和修改
const mytext = inject("kerwin")
console.log("mytext",mytext) //"aaaaaa"
mytext.value="bbbbbbbbb"
})
return {
mytext
}
}
}
</script>
修改之后: