vue组件之间通信方式

本文最后更新于:2022年3月10日 上午

ref和$refs

  • ref挂载在普通 HTML 组件上访问它得到 DOM

  • ref挂载在 VUE 组件上访问它得到组件实例

<base-input ref="usernameInput"><base-input></base-input></base-input>
this.$refs.usernameInput

// composition API
const usernameInput = ref(null)
onMounted(){
    // ref
    usernameInput.value
}

// setup中没有this
defineExpose({
    a,
    b
})
// 定义暴露到组件实例上的属性

$emitprop

  • 子组件props接收父组件传递的数据
  • 动态数据加冒号:
  • 子组件可对收到的props设置校验
  • 子组件定义$emit自定义方法
    this.$emit('childToParentMsg',this.childInfo,this.type)
  • 父组件就可以v-on监听该方法
  • 该方法绑定父组件的methods
  • 获得方法中传递的参数
defineEmits(["emit1", "emit2"]);
defineProps({
	foo: "bar",
});

$parent$children

  • $parent 得到 对象
  • $children 得到子组件实例对象 数组
// Composition API
getCurrentInstance();

provideinject

  • 父组件向任意深度子组件传值

  • 父组件中通过provide来提供变量

  • 子组件中通过inject来注入变量

  • 不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。只要在父组件的生命周期内,子组件都可以调用。

    Vue.component("parent", {
    	provide: {
    		// 提供了for变量
    		for: "test",
    	},
    });
    Vue.component("child", {
    	//
    	inject: ["foo"],
    	// 将for变量插入本实例
    	data() {
    		return {
    			mymessage: this.foo,
    		};
    	},
    });
    // Composition API
    import {inject,provide} from 'vue'
    inject(_name)
    provide(_name,_reactive_value)

$attrs && $listeners

  • $attrs包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外),通过v-bind="$attrs" 传入内部组件

  • $listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件

    // A->B->C
    
    // 二级子组件C
    Vue.component("C", {
    	template: `
                  <div>
                      <input type="text" v-model="$attrs.messagec" @input="passCData($attrs.messagec)"> </div>
              `,
    
    	methods: {
    		passCData(val) {
    			//触发父组件A中的事件
    			this.$emit("getCData", val);
    		},
    	},
    });
    
    // 一级子组件B
    Vue.component("B", {
    	data() {
    		return {
    			mymessage: this.message,
    		};
    	},
    	template: `
              <div>
                  <input type="text" v-model="mymessage" @input="passData(mymessage)"> 
                  <C v-bind="$attrs" v-on="$listeners"></C>
              </div>
          `,
    	props: ["message"], //props中取走了A传下来的一个attr
    	// 另外一个使用:bind="$attrs"继续向下传递给C
    	methods: {
    		passData(val) {
    			//触发父组件中的事件
    			this.$emit("getChildData", val);
    		},
    	},
    });
    
    // 父组件A
    Vue.component("A", {
    	template: `
              <div>
                  <p>this is parent compoent!</p>
                  <B :messagec="messagec" :message="message" v-on:getCData="getCData" v-on:getChildData="getChildData(message)"></B>
              </div>
          `,
    	data() {
    		return {
    			message: "hello",
    			messagec: "hello c", //传递给c组件的数据
    		};
    	},
    	methods: {
    		getChildData(val) {
    			console.log("这是来自B组件的数据");
    		},
    		//执行C子组件触发的事件
    		getCData(val) {
    			console.log("这是来自C组件的数据:" + val);
    		},
    	},
    });
  • Vue3中

    • listener合并到 attrs
    • attrs中还包含classstyle

EventBus

一个空Vue实例

// eventBus.js
import Vue from 'vue'
export default const EventBus  = new Vue()
// componentA
import EventBus from 'eventBus.js'
methods:{
    someFunc(){
        EventBus.$emit('funcName',{
            //props
        })
    }
}
// componentsB
mounted(){
    EventBus.$on('funcName',param => {
        //params取得传过来的参数
    })
}

Vuex


vue组件之间通信方式
http://yoursite.com/2022/02/24/vue组件通信/
作者
tatekii
发布于
2022年2月24日
许可协议