- ##我们知道vue组件通信有很多种,这里我把自己所知道12种vue组件通信总结出来
1:父子组件通信 ,(v-bind和props实现父子传值)
<template>
<div class="parent">
<Child name="张三"/>
</div>
</template>
<template>
<div class="child">
<h1> 接收父组件传递过来的值 {{name}}<h1/>
</div>
</template>
<script>
export default {
props: {
name: {
type: String,
}
},
data() {
return {
}
}
}
</script>
-当然在父组件中找到子组件标签,传递一个函数过去,在子组件接收这个函数,然后可以实现所谓的父子通信
2:子父组件通信
<template>
<div class="parent">
<Child @getMessage="getMessage"/>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
getMessage(e) {
console.log("e====",e)
}
}
}
</script>
<template>
<div class="parent">
<button @click="sendMessage"></button>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
sendMessage() {
this.$emit("getMessage",{id:1,name:"张三"})
}
}
}
</script>
<template>
<div>
<h1>hello A</h1>
<B v-model:obj="value"></B>
{{value}}
</div>
</template>
<script>
import B from './B'
export default {
props:{},
components:{B},
data() {
return {
value: "我是A组件的数据"
}
},
methods: {},
mounted() {}
}
</script>
<template>
<div>
Hello b
<input type="text" :value="obj" @input="mutationText">
</div>
</template>
<script>
export default {
props:{
obj: {
type: [String],
}
},
model: {
event:'updateValue'
},
components:{},
data() {
return {}
},
methods: {
mutationText(e) {
this.$emit("updateValue",e.target.value)
}
},
mounted() {}
}
</script>
<style scoped>
</style>
<template>
<div>
<h1>hello A</h1>
<B v-model:obj="value"></B>
{{value}}
</div>
</template>
<script>
import B from './B'
export default {
props:{},
components:{B},
data() {
return {
value: "我是A组件的数据"
}
},
methods: {},
mounted() {}
}
</script>
<template>
<div>
Hello b
<input type="text" :value="obj" @input="mutationText">
</div>
</template>
<script>
export default {
props:{
obj: {
type: [String],
}
},
components:{},
data() {
return {}
},
methods: {
mutationText(e) {
this.$emit("input",e.target.value)
}
},
mounted() {}
}
</script>
<style scoped>
</style>
<template>
<div>
<h1>hello A</h1>
<B v-model:obj="value"></B>
{{value}}
</div>
</template>
<script>
import B from './B'
export default {
props:{},
components:{B},
data() {
return {
value: "我是A组件的数据"
}
},
methods: {},
mounted() {}
}
</script>
<template>
<div>
Hello b
<input type="text" :v-model ="obj1"@input="mutationText">
</div>
</template>
<script>
export default {
props:{
obj: {
type: [String],
}
},
components:{},
data() {
return {
obj1: this.obj
}
},
methods: {
mutationText(e) {
this.$emit("input",this.obj1)
}
},
mounted() {}
}
</script>
<style scoped>
</style>
<template>
<div>
<h1>hello A</h1>
<!-- <B @val="e => value = e"></B> -->
<!-- <B @update:val="v => value = v"></B> -->
<!-- 简写 -->
<!-- <B :val.sync="value"></B> -->
{{value}}
</div>
</template>
<script>
import B from './B'
export default {
props:{},
components:{B},
data() {
return {
value: "我是A组件的数据"
}
},
methods: {},
mounted() {}
}
</script>
<style scoped>
</style>
<template>
<div>
Hello b
<input type="text" :value="obj" @input="mutationText">
</div>
</template>
<script>
export default {
props:["obj"],
components:{},
data() {
return {}
},
methods: {
mutationText(e) {
this.$emit("update:val",e.target.value)
}
},
mounted() {}
}
</script>
<style scoped>
</style>
3:非父子组件通信(实例bus,发布订阅模式)
vue.proptotype.$bus = new Vue()
<template>
<div class="grandpa">
<button @click="sendMessage"></button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
sendMessage() {
this.$bus.$emit("getMessage",{id:1,name:"张三"})
}
}
}
</script>
<template>
<div class="grandson">
<Child/>
</div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
this.$bus.$on("getMessage",(e) => {
console.log("e====",e)
})
}
}
</script>
4:跨级组件传值(provide和inject)
<template>
<div class="grandpa">
<button ></button>
</div>
</template>
<script>
export default {
data() {
return {
name: "张三"
}
},
provide() {
return {
app: this
}
}
}
</script>
<template>
<div class="grandson">
<h1>{{app.name}}</h1>
</div>
</template>
<script>
export default {
data() {
return {}
},
inject: ["app"]
}
</script>
5:跨级组件传值(
a
t
t
r
s
,
借
助
v
−
b
i
n
d
=
"
attrs,借助v-bind="
attrs,借助v−bind="attrs",后代组件并不会继承传递的props属性)
<template>
<div class="grandpa">
<father name="张三" age="18" gender="男"/>
</div>
</template>
<script>
export default {
data() {
return {}
},
}
</script>
<template>
<div class="father">
<grandson v-bind="$attrs"/>
</div>
</template>
<script>
export default {
data() {
return {}
},
}
</script>
<template>
<div class="grandson">
<h1> 姓名:{{$attrs.name}}-----年龄: {{$attrs.age}} ---- 性别: {{$attrs.gender}}</h1>
</div>
</template>
<script>
export default {
inheritAttrs: false, (默认为true)
data() {
return {}
},
}
</script>
6:跨级组件传值(
l
i
s
t
e
n
e
r
s
,
借
助
v
−
o
n
=
"
listeners,借助v-on="
listeners,借助v−on="listeners",它是一个对象,里面包含了作用在这个组件上的所有监听器,不包括.native事件)
<template>
<div class="grandpa">
<father @getMessage="getMessage"/>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
getMessage(e) {
console.log("接收孙子组件传递过来的参数",e)
}
}
}
</script>
<template>
<div class="father">
<!-- 在孙子组件上 绑定这个监听器 -->
<grandson v-on="$listeners"/>
</div>
</template>
<script>
export default {
data() {
return {}
},
}
</script>
<template>
<div class="grandson">
<button @click="sendMessage"> Button </button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods:{
sendMessage() {
console.log("发送")
this.$emit("getMessage","你好爷爷")
}
}
}
</script>
7:父子组件通信
p
a
r
e
n
t
和
parent和
parent和children(一般不建议使用
c
h
i
l
d
e
n
和
childen和
childen和parent,耦合度过高)
<template>
<div class="father">
<grandson/>
<h1>子组件修改父组件的名字: {{name}}</h1>
<button @click="mutateHandler"> Button </button>
</div>
</template>
<script>
export default {
data() {
return {
name: '张三'
}
},
methods: {
getMessage(e) {
this.name = e;
},
mutateHandler() {
this.$children[0].mutateName("张四")
}
}
}
</script>
<template>
<div class="grandson">
<button @click="sendMessage"> Button </button>
<h1>父组件修改子组件的名字: {{name}}</h1>
</div>
</template>
<script>
export default {
data() {
return {
name: "张四"
}
},
methods:{
sendMessage() {
this.$parents.getMessage("李四")
},
mutateName(e) {
this.name = e
}
}
}
</script>
8:refs(可以获取组件对象,也可以获取dom对象)
<template>
<div class="father">
<grandson refs="son"/>
<button @click="mutateHandler">修改值</button>
</div>
</template>
<script>
export default {
data() {
return {
name: '张三'
}
},
methods: {
mutateHandler() {
this.$refs.son.mutateName("张四")
}
}
}
</script>
<template>
<div class="grandson">
<h1>父组件修改子组件的名字: {{name}}</h1>
</div>
</template>
<script>
export default {
data() {
return {
name: "张三"
}
},
methods:{
mutateName(e) {
this.name = e
}
}
}
</script>
9:作用域插槽传值 (借助 v-slot:default=“value” 实现所谓的子父传值)
<template>
<div class="father">
<grandson>
<!-- 可以使用 v-slot:grandson ="{}" 是#grandson的语法糖,slot-scoped="{}" 在vue 2.6.0 起被废弃,所以我就不写了 -->
<template #grandson="{name}">
{{name}}
</template>
</grandson>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {}
}
</script>
<template>
<div class="grandson">
<slot name="grandson" :name="name"></slot>
<button @click="mutateHandler">修改父组件值</button>
</div>
</template>
<script>
export default {
data() {
return {
name: "张三"
}
},
methods:{
mutateHandler() {
this.name = "李四"
}
}
}
</script>
10:本地缓存(localStorage或者sessionStorage,本文我就以localStorage为例)
<template>
<div class="father">
<grandson></grandson>
<h1>{{name}}</h1>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {},
mounted() {
this.name = localStorage.getItem("name")
}
}
</script>
<template>
<div class="grandson">
<slot name="grandson" :name="name"></slot>
<button @click="mutateHandler">修改父组件值</button>
</div>
</template>
<script>
export default {
data() {
return {
name: "张三"
}
},
methods:{
mutateHandler() {
this.name = "李四
localStorage.setItem("name",this.name)
}
}
}
</script>
11:vuex (一般我们就是dispatch这个actions名字,然后action提交mutations这个名字,然后getters获取这个state(getters类似于vue中的computed),这里我使用的vuex的辅助函数)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
name: '张三'
},
mutations: {
setName(state,name) {
state.name = name
}
},
actions: {
actionName({commit}) {
commit("setName",name)
}
},
getters: {
name(state) {
return state.state
}
},
modules: {
}
})
import Vue from 'vue'
import App from './App.vue'
import store from './store'
new Vue({
store,
render: h => h(App)
}).$mount("#app")
<template>
<div class="father">
<grandson></grandson>
<h1>{{name}}</h1>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {}
},
computed: mapGetters(["name"]),
}
</script>
<template>
<div class="grandson">
<button @click="actionName(name)">修改父组件值</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data() {
return {
name: "张三"
}
},
methods:{
...mapActions(["actionName"]),
}
}
</script>
12: redux(这里我就不写了,原理类似于vuex)