前言
在Vue.js中,组件通信是指在不同的Vue组件之间传递数据或触发事件的过程。Vue提供了多种方式来实现组件之间的通信,主要包括以下几种:
父子组件通信
通过props传递数据
- 通过在子组件的标签上定义属性,父组件可以将数据传递给子组件。
- 在子组件中使用
props
选项接收父组件传递的数据。
如下面的例子:
1. App2.vue
template部分:
<template>
<div class="head">
<!-- 输入框绑定到 message 数据 -->
<input type="text" v-model="message" />
<!-- 点击按钮触发 submit 方法 -->
<button @click="submit">确定</button>
</div>
<!-- 引用 List 组件并通过属性传递 lists 数据 -->
<List :lists="lists" />
</template>
script部分:
<script>
import List from "./components/body2/list.vue";
export default {
components: {
List,
},
data() {
return {
lists: ["html", "css"],
message: "",
};
},
methods: {
submit() {
// 当点击确定按钮时,将输入框的内容添加到 lists 数组中
if (this.message) {
this.lists.push(this.message);
this.message = "";
}
},
},
};
</script>
在App2.vue
组件中,通过使用v-model
将输入框和message
数据进行双向绑定。当用户在输入框中输入内容时,message
数据会同步更新。当点击确定按钮时,通过调用submit
方法,将message
的内容添加到lists
数组中。
2. list.vue
template部分:
<template>
<div class="body">
<ul>
<!-- 使用 v-for 遍历 lists 数组,动态生成列表项 -->
<li v-for="item in lists" :key="item">{{ item }}</li>
</ul>
</div>
</template>
script部分:
<script>
export default {
// 通过 props 接收父组件传递过来的 lists 数组
props: ['lists'],
};
</script>
在list.vue
组件中,通过使用props
属性接收父组件传递的lists
数组。这样,list.vue
组件就可以在自己的模板中使用这个来自父组件的数据,实现了组件之间的传值。
在上述代码中,是通过在父组件中使用props
将数据传递给子组件,以及在子组件中使用v-model
实现双向数据绑定,实现了组件之间的传值。这样,App2.vue
中的输入框的内容能够更新到list.vue
中的列表中。但需要注意的是:因为props属性是单向数据流,只能从父组件流向子组件,不能反过来。注意不要去尝试修改props属性的值,即使改了也不会影响到父组件的值。
既然有了父子组件传值,那么自然也就有子父组件传值了
子父组件传值(也可以称为自定义事件): $emit
- 子组件可以通过
$emit
方法触发自定义事件,并传递数据给父组件。 - 在父组件中使用
v-on
(也就是@
)监听子组件的自定义事件。
如下面的例子:
1. App3.vue
template部分:
<template>
<!-- 引用 Header 组件并通过监听 add 事件调用 handle 方法 -->
<Header @add="handle" />
<div class="body">
<ul>
<!-- 使用 v-for 遍历 lists 数组,动态生成列表项 -->
<li v-for="(item, index) in lists" :key="(item, index)">{{ item }}</li>
</ul>
</div>
</template>
script部分:
<script>
import Header from './components/body3/header.vue';
export default {
components: {
Header
},
data() {
return {
lists: ["html", "css"],
message: "",
};
},
methods: {
handle(val) {
// 接收来自 Header 组件触发的 add 事件,将数据添加到 lists 数组中
console.log(val);
this.lists.push(val);
}
}
};
</script>
在App3.vue
组件中,通过在Header
组件的标签上监听自定义事件add
,并调用handle
方法来接收来自Header
组件的数据。这样,就实现了子组件(Header
)向父组件(App3.vue
)传递数据的功能。
2. header.vue
template部分:
<template>
<div class="head">
<!-- 输入框绑定到 message 数据 -->
<input type="text" v-model="message">
<!-- 点击按钮触发 submit 方法 -->
<button @click="submit">确定</button>
</div>
</template>
script部分:
<script>
export default {
data() {
return {
message: ''
}
},
methods: {
submit() {
// 触发自定义事件 add,将 message 数据传递给父组件
this.$emit('add', this.message);
this.message = ''; // 清空输入框内容
}
}
}
</script>
在header.vue
组件中,当用户点击确定按钮时,通过this.$emit
触发了自定义事件add
,并传递了message
数据给父组件。这样,header.vue
组件就向父组件(App3.vue
)传递了数据。
上述代码通过自定义事件实现了子组件(header.vue
)向父组件(App3.vue
)传递数据的功能。当在输入框中输入内容并点击确定按钮时,将数据传递给父组件,父组件接收到数据并将其添加到lists
数组中,实现了组件之间的传值。
兄弟组件通信
兄弟组件之间的通信通常通过它们共同的父组件来实现。兄弟组件通过将数据传递给父组件,再由父组件将数据传递给另一个兄弟组件来完成通信。在实现兄弟组件通信时,我们需要借助vuex
来实现。我们需要在终端中使用 npm install vuex --save
来下载vuex
的包。并在src
下创建一个命名为store
的文件夹来充当仓库的角色,借此来实现兄弟组件之间的通信。
vuex
- Vuex是Vue.js官方提供的状态管理库,用于在不同组件之间共享状态。
- 组件可以通过提交(mutations)或分发(actions)来改变共享状态。
state
用来存放共享变量的地方getter
,可以增加一个getter
派生状态,(相当于store
中的计算属性),用来获得共享变量的值mutations
用来存放修改state
的方法。actions
也是用来存放修改state的方法,不过action
是在mutations
的基础上进行。常用来做一些异步操作
如下面的例子:
1. App4.vue
template部分:
<template>
<div>
<!-- 引用 Header 组件 -->
<Header />
<!-- 引用 List 组件 -->
<List />
</div>
</template>
script部分:
<script>
import Header from './components/body4/header.vue'
import List from './components/body4/list.vue'
export default {
components: {
Header,
List
}
}
</script>
在App4.vue
组件中,引用了两个子组件 Header
和 List
。
2. header.vue 组件
template部分:
<template>
<div class="head">
<!-- 输入框绑定到 message 数据 -->
<input type="text" v-model="message" />
<!-- 点击按钮触发 submit 方法 -->
<button @click="submit">确定</button>
</div>
</template>
script部分:
<script>
import { mapMutations } from 'vuex'
export default {
data() {
return {
message: ''
};
},
methods: {
...mapMutations(['addLists']),
submit() {
// 将 message 存入 Vuex 仓库中
this.addLists(this.message);
}
}
};
</script>
在header.vue
组件中,使用 Vuex 的 mapMutations
辅助函数,映射了一个名为 addLists
的 mutation。当用户在输入框中输入内容并点击确定按钮时,通过调用 submit
方法触发 addLists
mutation 将 message
存入 Vuex 仓库。
3. list.vue 组件
template部分:
<template>
<div class="body">
<ul>
<!-- 使用 v-for 遍历 lists 数组,动态生成列表项 -->
<li v-for="(item, index) in lists" :key="(item, index)">{{ item }}</li>
</ul>
</div>
</template>
script部分:
<script>
import { mapState } from "vuex";
export default {
computed: {
...mapState(['lists']),
}
};
</script>
在list.vue
组件中,使用 Vuex 的 mapState
辅助函数,映射了一个名为 lists
的状态。这样,list.vue
组件就可以在自己的模板中使用 lists
状态,实现了组件之间的传值。lists
数组来自 Vuex 仓库,它会在仓库中随着 addLists
中的 mutation
的执行而更新。
通过上述例子,我们使用 Vuex
实现了 (header.vue
) 组件将数据存入仓库,(list.vue
) 组件从仓库中获取数据的过程,实现了组件之间的传值。
结语
父子关系的组件数据传递可以选择 props
与 $emit
进行传递
兄弟组件则可以选择使用vuex
来实现数据的传递。
但实际上组件之间的通信都可以使用vuex
来实现,但是在实际应用中还是要根据项目的需求和架构来选择合适的组件通信方式。