今天的主题是vue组件间通信,闲话不多说,我们直接进入主题。
父 -> 子组件通信
父组件要传值给子组件的话,假设示例(options API)中的父组件是App.vue,子组件是List.vue
- 首先,在父组件中子组件标签上v-bind绑定一个属性用于传值
<template>
<List :lists="list" /> // v-bind绑定属性lists用于传值,值是数据源中的list
</template>
<script>
import List from './components/List.vue';
export default {
components: {
List,
},
data() {
return {
list: []
}
},
}
</script>
- 然后,在子组件中通过props接收这个属性
<script>
export default {
props: ['lists']
}
</script>
这样就完成了父组件传值给子组件,注意我们无法修改props中的值,数据流是单向的。
子 -> 父组件通信
话不多说,直接上例子,实例中父组件是App.vue,子组件是Add.vue
- 首先,在子组件通过
this.$emit('事件名',参数)方法生成一个事件
<template>
<div class="head">
<input type="text" v-model="message">
<button @click="add">添加</button>
</div>
</template>
<script>
export default {
data() {
return {
message: '',
}
},
methods: {
add() {
this.$emit('add', this.message); // 生成一个add事件,并将message作为参数传入
this.put = '';
}
}
}
</script>
- 然后,父组件通过v-on监听这个事件,当事件触发时,其中的参数会传给父组件
<template>
<Add @add="handle" /> // 父组件通过v-on监听这个事件
</template>
<script>
import Add from './components/Add.vue';
export default {
components: {
Add
},
methods: {
handle(data) { 触发时,参数传入
console.log(data);
this.list.push(data);
}
}
}
</script>
任意组件通信
要想实现任意组件的通信,最好的方法就是引入一个仓库,大家都把数据放入仓库,需要的时候都去向仓库取数据,这样就可以实现任意组件的通信了。这里我们将接收一个新的东西-vuex,它可以帮我们创建一个仓库。
仓库的创建
- 首先,我们在终端输入:
npm install vuex@next --save或yarn add vuex@next --save下载依赖(官方文档可以找到) - 然后我们在vue项目的src文件夹下创建一个文件夹,在这个文件夹中创建一个js文件用于创建仓库
import { createStore } from 'vuex'
const store = createStore({
})
export default store
- 在main.js中导入并使用
import store from './store'
createApp(App).use(store).mount('#app')
仓库的使用
假设仓库已经有了这么一些数据
import { createStore } from 'vuex'
const store = createStore({
state: {
lists: ['html', 'css']
},
mutations: {
add(state, val) {
state.lists.push(val)
}
}
})
export default store
- 我们可以在组件中导入mapState方法来获取仓库的数据
<script>
import { mapState } from 'vuex'; // 导入mapState
export default {
computed: {
...mapState(['lists']) // 调用mapState,获取仓库中的lists数组
}
}
</script>
- 同样,我们在组件中导入并使用mapMutations来将组件的数据存入仓库
<script>
import { mapMutations } from 'vuex' // 导入mapMutations
export default {
data() {
return {
message: '',
}
},
methods: {
...mapMutations(['add']), // 将 'add' mutation 映射为组件的一个方法
submit() {
this.$store.commit('add', this.message) // 提交状态变更
}
}
}
</script>
// 也就是把组件中的message的值放入仓库当中,这里具体来说是放入仓库中的lists数组中。
小结
使用props可以将数据从父组件传递给子组件,而emit可以在子组件中触发事件,并将数据传递给父组件。通过Vuex可以创建一个仓库来存储共享数据,组件可以通过mapState获取仓库中的数据,通过mapMutations提交状态变更。这样就可以实现灵活而高效的组件通信。