vue的组件通信
vue组件通信有以下几种方式
组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系:
1. 父组件传子组件
使用props来实现
在父组件的子组件标签上绑定一个自定义属性,用于绑定要传递的值,在子组件中使用prop属性进行数据的接受,可以直接使用,绑定的属性名和prop定义的名字必须一致,否则无法接受数据
父组件如下:
<template>
<div class="section">
<com-article :articles="articleList"></com-article>
</div>
</template>
<script>
import comArticle from './test/article.vue'
export default {
name: 'HelloWorld',
components: { comArticle },
data() {
return {
articleList: ['红楼梦', '西游记', '三国演义']
}
}
}
</script>
子组件如下:
<template>
<div>
<span v-for="(item, index) in articles" :key="index">{{item}}</span>
</div>
</template>
<script>
export default {
props: ['articles']
}
</script>
2. 子组件传父组件
通过自定义事件来实现
在子组件元素中绑定一个事件,点击触发事件,事件中使用
e
m
i
t
(
自
定
义
事
件
,
传
递
的
值
)
,
向
父
组
件
发
布
信
息
,
在
父
组
件
的
子
组
件
元
素
上
绑
定
一
个
自
定
义
事
件
,
事
件
名
必
须
是
emit(自定义事件,传递的值),向父组件发布信息,在父组件的子组件元素上绑定一个自定义事件,事件名必须是
emit(自定义事件,传递的值),向父组件发布信息,在父组件的子组件元素上绑定一个自定义事件,事件名必须是emit中的事件名,自定义事件调用父组件自己定义的函数
父组件如下:
<template>
<div class="section">
<com-article :articles="articleList" @onEmitIndex="onEmitIndex"></com-article>
<p>{{currentIndex}}</p>
</div>
</template>
<script>
import comArticle from './test/article.vue'
export default {
name: 'HelloWorld',
components: { comArticle },
data() {
return {
currentIndex: -1,
articleList: ['红楼梦', '西游记', '三国演义']
}
},
methods: {
onEmitIndex(idx) {
this.currentIndex = idx
}
}
}
</script>
子组件如下:
<template>
<div>
<div v-for="(item, index) in articles" :key="index" @click="emitIndex(index)">{{item}}</div>
</div>
</template>
<script>
export default {
props: ['articles'],
methods: {
emitIndex(index) {
this.$emit('onEmitIndex', index)
}
}
}
</script>
3. 兄弟组件传值
定义一个eventBus.js文件,导出一个空的vue对象,在兄弟组件中引入bus.js的文件,在A组件通过bus.
e
m
i
t
(
)
传
递
,
在
B
组
件
中
的
c
r
e
a
t
e
d
函
数
中
,
使
用
b
u
s
.
emit()传递,在B组件中的created函数中,使用bus.
emit()传递,在B组件中的created函数中,使用bus.on接受
根组件如下:
<template>
<div id="app">
<ChildA/>
<ChildB/>
</div>
</template>
<script>
import ChildA from './components/ChildA' // 导入A组件
import ChildB from './components/ChildB' // 导入B组件
export default {
name: 'App',
components: {ChildA, ChildB} // 注册A、B组件
}
</script>
兄弟A组件如下
<template>
<div id="childA">
<h1>我是A组件</h1>
<button @click="transform">点我让B组件接收到数据</button>
<p>因为你点了B,所以我的信息发生了变化:{{BMessage}}</p>
</div>
</template>
<script>
export default {
data() {
return {
AMessage: 'Hello,B组件,我是A组件'
}
},
computed: {
BMessage() {
// 这里存储从store里获取的B组件的数据
return this.$store.state.BMsg
}
},
methods: {
transform() {
// 触发receiveAMsg,将A组件的数据存放到store里去
this.$store.commit('receiveAMsg', {
AMsg: this.AMessage
})
}
}
}
</script>
兄弟B组件如下
<template>
<div id="childB">
<h1>我是B组件</h1>
<button @click="transform">点我让A组件接收到数据</button>
<p>因为你点了A,所以我的信息发生了变化:{{AMessage}}</p>
</div>
</template>
<script>
export default {
data() {
return {
BMessage: 'Hello,A组件,我是B组件'
}
},
computed: {
AMessage() {
// 这里存储从store里获取的A组件的数据
return this.$store.state.AMsg
}
},
methods: {
transform() {
// 触发receiveBMsg,将B组件的数据存放到store里去
this.$store.commit('receiveBMsg', {
BMsg: this.BMessage
})
}
}
}
</script>
4. 通过vuex来实现组件传值
首先通过 npm install vuex --save 安装vuex
然后在src中新建一个store文件夹,在文件夹中新建一个 index.js 文件
index.js中的内容如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
// 初始化A和B组件的数据,等待获取
AMsg: '',
BMsg: ''
}
const mutations = {
receiveAMsg(state, payload) {
// 将A组件的数据存放于state
state.AMsg = payload.AMsg
},
receiveBMsg(state, payload) {
// 将B组件的数据存放于state
state.BMsg = payload.BMsg
}
}
export default new Vuex.Store({
state,
mutations
})