vue组件通信的方式

2024-01-07 22:33:36

父组件向子组件通信

概念:父组件通过props向子组件传递数据,子组件通过props接收数据;

父组件

<template>
  <div id="app">
    // 传递num/val的值
    <Child :num="num" :val="val" />
  </div>
</template>

<script>
// 引入组件子组件
import Child from './views/child.vue'

export default {
// 注册
  components:{
    Child
  },
  data() {
    return {
      num:0,
      val:'我是从父组件传递过来的东西'
    }
  }
}
</script>

<style lang="scss"></style>

子组件

<template>
    <div>
        <h1>{{ num }}</h1>
        <h2>{{ val }}</h2>
    </div>
</template>

<script>
export default {
    // 接收数据指定它的类型
    props:{
        num:{
            // 类型可以是 Number | String | Boolean | Array | Object | Date | Symbol | Function
            type:Number,
            // 是否为必填项
            // required:true
        },
        val:{
            type:String,
            required:true
        }
    }
}
</script>

<style lang="scss"></style>

子组件向父组件通信

概念:子组件通过$emit触发一个自定义事件,父组件通过v-on监听该自定义事件,并在相应的方法中处理事件传递的数据。

父组件

<template>
  <div id="app">
    <Child @addnum="addnum" />
  </div>
</template>

<script>
import Child from './views/child.vue'
export default {
  components: {
    Child
  },
  data() {
    return {
      num: 0,
    }
  },
  methods: {
    addnum(val) {
      this.num += val
    }
  }
}
</script>

<style lang="scss"></style>

子组件

<template>
    <div>
        <button @click="addnum">点击我</button>
        {{ num }}
    </div>
</template>

<script>
export default {
    props: {
        num: {
            type: Number,
            // required: true
        }
    },
    methods: {
        addnum() {
            this.$emit('addnum', 5)
        }
    }
}
</script>

<style lang="scss"></style>

兄弟组件通信

eventBus事件总线适用于父子组件、非父子组件等之间的通信

概念:使用 eventBus ,其实就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。它的本质是通过创建一个空的 Vue 实例来作为消息传递的对象,通信的组件引入这个实例,通信的组件通过在这个实例上监听和触发事件,来实现消息的传递。

在main.js中配置eventBus

// eventBus
Vue.prototype.eventBus=new Vue()

左组件

<template>
  <div class="home">
    <h1>这里是左组件</h1>
    <button @click="send">点击试试看</button>
  </div>
</template>

<script>
export default {
  methods: {
    send() {
      this.eventBus.$emit('send', '这是来自左组件的数据')
    }
  }
}
</script>

<style lang="scss"></style>

右组件

<template>
  <div>
    <h1>这里是右组件</h1>
    {{ val }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      val: ''
    }
  },
  mounted() {
    this.eventBus.$on('send', val => {
      this.val = val
    })
  }
}

</script>

<style lang="scss"></style>

v-model

概念:通过v-model指令可以实现双向绑定,父组件可以通过v-model传递 数据给子组件,并且子组件可以通过修改v-model绑定的值来通知父组件

父组件

<template>
  <div id="app">
    <Child v-model="num"/>
  </div>
</template>

<script>
import Child from './views/child.vue'
export default {
  components: {
    Child
  },
  data() {
    return {
      num: 0,
    }
  },
  methods: {
  }
}
</script>

<style lang="scss"></style>

子组件

<template>
    <div>
        <button @click="addnum2">点击我</button>
        {{ value }}
    </div>
</template>

<script>
export default {
    props: {
        // 在 vue2 中如果通过 v-model 进行组件传值,那么在子组件中只能通过 value 属性来进行接收
        value:{
            type:Number
        }
    },
    methods: {
        addnum2(){
            this.$emit('input',5)
        }
    }
}
</script>

<style lang="scss"></style>

.sync

概念:通过.sync修饰符可以简化子组件向父组件传递数据的过程

父组件

<template>
  <div id="app">
    <Child :num.sync="num" @click="addnum3" />
  </div>
</template>

<script>
import Child from './views/child.vue'
export default {
  components: {
    Child
  },
  data() {
    return {
      num: 0,
    }
  },
  methods: {
 
  }
}
</script>

<style lang="scss"></style>

子组件

<template>
    <div>
        <button @click="addnum3">点击我</button>
        {{ num }}
    </div>
</template>

<script>
export default {
    components: {

    },
    props: {
        num: {
            type: Number,
            // required: true
        }
    },
    methods: 
        addnum3(){
            this.$emit('update:num',10)
        }
    }
}
</script>

<style lang="scss"></style>

文章来源:https://blog.csdn.net/m0_74060440/article/details/135400675
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。