vue中实现组件通信的4中方法
第一种传递方式:父组件向子组件传递数据:
父组件APP
<template>
<div id="app">
将数据Data中的数据school传给子组件HelloWorld;在HelloWorld中使用props属性接收
<HelloWorld :schoolData = "school"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
data(){
return {
school:[
{id:1,name:"张三",sex:"男",age:20,done:false,},
{id:2,name:"李四",sex:"男",age:18,done:false,},
{id:3,name:"王麻子",sex:"男",age:15,done:false,},
{id:4,name:"小猪佩奇",sex:"男",age:23,done:false,}
]
}
},
components: {
HelloWorld
}
}
</script>
<style>
</style>
子组件HelloWorld:
子组件HelloWorld
<template>
<div class="hello">
<ul style="list-style-type:none">
//在展示props接收到的数据
<li v-for="item in schoolData" :key="item.id">
<span>学生ID:{{item.id}}</span>
<span>学生名:{{item.name}}</span>
<span>性别:{{item.sex}}</span>
<span>年龄:{{item.age}}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
//使用pops接收父组件传递过来的数据
props: {
schoolData: Array
}
}
</script>
<style scoped>
</style>
这是上面的输出结果:
第二种传递方式:子组件向父组件传递数据:这了我们采用回调函数的形式传递;这种传数据的方式也适用孙子向爷爷传参
父组件APP
<template>
<div id="app">
<HelloWorld :schoolData = "school" : deleteData = " deleteData"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
data(){
return {
school:[
{id:1,name:"张三",sex:"男",age:20,done:false,},
{id:2,name:"李四",sex:"男",age:18,done:false,},
{id:3,name:"王麻子",sex:"男",age:15,done:false,},
{id:4,name:"小猪佩奇",sex:"男",age:23,done:false,}
]
}
},
components: {
HelloWorld
}
methods:{
//在父组件APP的methods属性中提前定义好一个函数;然后通过数据绑定的方式将次函数传递给子组件;子组件用props接收
//删除数据中的一条数据:
deleteData(id){
//这里采用的是数组的过滤器方法;将id相同的元素删除掉
this.school = this.school.filter(item =>{
return item.id !== id
})
}
}
}
</script>
<style>
</style>
子组件HelloWorld 现在在子组件中使用props接收父组件传来的函数
子组件HelloWorld
<template>
<div class="hello">
<ul style="list-style-type:none">
<li v-for="item in schoolData" :key="item.id">
<span>学生ID:{{item.id}}</span>
<span>学生名:{{item.name}}</span>
<span>性别:{{item.sex}}</span>
<span>年龄:{{item.age}}</span>
<button @click = "deleteItem(id)">删除</button>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: [schoolData,deleteData]
methods:{
deleteItem(id){
//在这里调用父组件传来的函数并将要删除的元素ID通过函数deleteData传递给父组件
this.deleteData(id)
}
}
}
</script>
<style scoped>
</style>
点击按钮删张三
删除后
第三种传参方式:采用了自定义事件的方式;请看代码:
父组件
<template>
<div id="app">
//自定义事件v-on:remove = "removeData";有人一旦触发remove事件;则会执行函数removeData
<HelloWorld v-on:remove = "removeData" :deleteItem = "deleteItem" :schoolData = "school"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
data(){
return {
school:[
{id:1,name:"张三",sex:"男",age:20,done:false,},
{id:2,name:"李四",sex:"男",age:18,done:false,},
{id:3,name:"王麻子",sex:"男",age:15,done:false,},
{id:4,name:"小猪佩奇",sex:"男",age:23,done:false,}
]
}
},
components: {
HelloWorld
},
methods:{
//第一种删除方式:回调函数
deleteItem(id){
this.school = this.school.filter(item =>{
return item.id !== id
})
},
//第二种删除方式:自定义事件
removeData(id){
this.school = this.school.filter(item =>{
return item.id !== id
})
}
}
}
</script>
<style>
</style>
子组件HelloWorde
<template>
<div class="hello">
<ul style="list-style-type:none">
<li v-for="item in schoolData" :key="item.id">
<span>学生ID:{{item.id}}</span>
<span>学生名:{{item.name}}</span>
<span>性别:{{item.sex}}</span>
<span>年龄:{{item.age}}</span>
<button @click="deleteData(item.id)">删除按钮</button>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: ["schoolData","deleteItem"],
methods:{
deleteData(id){
//第一种删除方式的回调函数
this.deleteItem(id)
//第二种删除方式自定义事件
this.$emit("remove",id)
}
}
}
</script>
<style scoped>
button{
margin-left:20px;
}
</style>
注意:以上的组件之间的通信方式都是建立在父子之间的通信
第四种组件之间的通信方式:这次我们采用事件总线的
要想深入了解事件总线;就得了解vue的原型链;这里不多说;只在代码中展示事件总线的实现
有两种方式:
第一种:
vue的入口文件main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
//对vue熟悉的可能能看懂下面的这段代码;
const vueComponent = Vue.extend({})//利用vue创建一个组件对象
const vc = new vueComponent()//在用组件对象创建一个组件实例
Vue.prototype.$bus = vc //事件总线创建成功
new Vue({
render: h => h(App),
}).$mount('#app')
上面我们已经在vue的入口文件创建好了事件总线$bus
下面我们来用事件总线实现兄弟组件的通信:请看代码:
兄弟_01
<template>
<div>
<h1>{{name}}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data(){
return {
name:"小猪佩奇"
}
},
mounted(){
当setName被触发时,会执行后面的回调函数
this.$bus.$on("setName",()=>{
//在兄弟_02中点击按钮将小猪佩奇改称大头儿子
this.name = "大头儿子"
})
}
}
</script>
<style scoped>
button{
margin-left:20px;
}
</style>
兄弟_02
<template>
<div>
<button @click = "setName">点击按钮</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data(){
return {
name:"小猪佩奇"
}
},
methods:{
setName(){
this.$bus.$emit("setName")
}
}
}
</script>
<style scoped>
button{
margin-left:20px;
}
</style>
事件总线的第二种方式:
vue入口文件main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
//借助vue的生命周期函数 beforeCreate;至于为什么要使用beforeCreate这个生命周期函数;请阅读vue开发文档发
//这里this指向vm;至于vm是什么请阅读vue开发文档发;至于为什么要赋值vm;请了解vue的原型链
beforeCreate(){
Vue.prototype.$bus = this
}
}).$mount('#app')
第五种实现组件之间通信的方式;那就是发布与订阅;
借助第三方库:npm install pubsub-js
在需要实现通信的组件中引入即可