Vue组件间通信的七种方式

302 阅读1分钟

Vue组件通信的七种方式

1. provide与inject(祖先给后代通信)

    //父组件中,定义需要传递的值:(与data同级)
    provide(){
      return{
         name:'Tom',
      }
	}
	//子组件中,用inject(与data同级)接收,接收了之后可以与data一样使用
    inject:['name']
无论子组件有多深,只要在之前的祖先组件中provide过就能使用inject注入使用

2.props(父传子)

父组件中通过:数据名='数据'的形式传给子组件
<template>
  <div>
      <Child :title='title'></Child>
  </div>
</template>
<script>
  import Child from './Child'
  
  export default{
      data(){
          return {
              title:'我是父组件的数据'
          }
      },
      components:{
          Child
      }
  }
</script>
子组件中使用props接收,与data一样使用
//有三钟接收方式,数组,对象,对象+规则,此处是对象+规则
props:{
  title:{
      type:String,//类型检测
      default:'',//设置为传入时的默认值
      required:true,//是否必须传入,默认false
      //用于处理复杂的验证
      validator:funciont(value){
      	return value.length > 6
      }
  }
}
//数组方式
props:['title']
//对象方式
props:{
  title:'String'
}

3.$emit(子传父)

 子组件中使用$emit传出事件
//这里例如是通过点击事件触发子传父操作
methods:{
    onClick(){
        //第一个参数是父组件接收事件的名字,后面的是负载的参数
        this.$emit('titleChange',this.title)
    }
}
  父组件使用@事件名使用
<Child @titleChange='titleChange'></Child>
...
methods:{
    //参数就是子组件传过来的参数
    titleChange(title){
        this.title = title;
    }
}

4.$ref(父调用或访问子的方法与数据)

  子组件中无需其他操作,正常写入即可
// Child.vue

<template>
<div class="child">
</div>
</template>

<script>
export default {
name: 'Child',
data () {
  return {
    title: '我是子组件的内容'
  }
},
methods: {
  childAlert () {
    window.alert('我是子组件里面的弹窗!')
  }
}
}
</script>

<style scoped>
</style>
父组件需要ref=

▲如果ref是在普通DOM元素上使用,指向的就是DOM元素,如果是子组件,就是组件实例

// App.vue

<template>
  <div id="app">
      //这里使用ref,名字可以任意
    <Child ref="childRef"/>
  </div>
</template>

<script>
import Child from './components/Child'

export default {
  name: 'App',
  data () {
    return {
    }
  },
  components: {
    Child
  },
  mounted () {
    // 访问子组件的 title
    console.log(this.$refs.childRef.title)  // 输出‘我是子组件的内容’
    // 调用子组件的 childAlert 方法
    this.$refs.childRef.childAlert()
  }
}
</script>

<style>
</style>

5.事件总线 $bus

方式一:通过一个空的vue实例作为总线
//bus.js
import Vue from 'vue';
const bus = new Vue();
//导出一个名为bus的Vue实例对象
export default bus;
//A组件
<template>
  <div>
    <h1>俺是第A组件</h1>
    <el-button @click="clickEve">传给B</el-button>
  </div>
</template>

<script>
  //先引入bus.js
  import bus from "../../bus/bus";
  export default {
    name: "BusTest",
    data(){
      return{
        message:'A组件'
      }
    },
    methods:{
      clickEve(){
          //这里就是$emit
        bus.$emit('getMessage',this.message)
      }
    }
  }
</script>
//B组件
<template>
  <div>
    <h2>俺是B组件</h2>
    <div>我能和{{message}}通信</div>
  </div>
</template>

<script>
//引入bus.js
  import bus from "../../bus/bus";
  export default {
    name: "BusTest2",
    data(){
      return{
        message:'',
      }
    },
    mounted() {
        //使用$on方法调用bus里的方法
      bus.$on('getMessage', data=>{
        // console.log(data)
        this.message = data
      })
    },
    //用完需要销毁
    beforDestory(){
        this.$off('getMessage')
    }
  }
</script>
方式二:把$bus定义在vue的prototype上,全局都可使用
//mian.js
onst bus = new Vue()
Vue.prototype.$bus = bus
//其他组件需要传入数据时直接$bus.***,使用也是
方式三:使用插件vue-bus
//安装
npm install vue-bus --save
//main.js
import VueBus from 'vue-bus';//中央事件总线
Vue.use(VueBus)

6.$parent(子访父)

//在子组件中可以使用$parent访问父组件的数据,方法等
mounted(){
	//获取父组件的数据
    this.msg = this.$parent.msg
    //调用父组件的方法
    this.$paren.meth()
}

7.Observable

//strore.js
//状态数据
export let store = Vue.observable({
    count:0,
})
//处理方法
export let mutations={
    setCount(count){
        store.count = count
    }
}
//使用者只需要导入即可
import {mutations,store} from './store.js'

8.Vuex