2022-04-11——vue组件传值(8种方法)----props、$emit()、手动封装事件订阅observer、事件总线(Eventbus)、vuex、亲兄弟传值、provide/inj...

1、父传子

传递:当子组件中在父组件中当做标签使用的时候,给子组件绑定一个自定义属性,值为需要传递的数据
接收:在子组件内部通过props进行接收,props接收的方式有2种:
①通过数组进行接收 props:["属性"]
②通过对象进行接收
props:{
(1)type:限制数据的类型
(2)default:默认值
(3)required:布尔值,和default二选一
}
步骤:
①在父组件中给子组件标签上添加自定义属性:<son :custom="100"></son>
②子组件中通过props接收:props:["custom"]
③接收到的custom可以直接在标签中使用 {{custom}}
注意:今后只要看到props就要想到这个属性是用来接收外部数据的。

2、子传父

①接收:当子组件在父组件中当做标签使用的时候,给当前子组件绑定一个自定义事件,值为需要接收值的函数,这个函数不允许加 ()
②传递的过程:在子组件内部通过this.$emit("自定义事件名称",需要传递的参数)来进行数据的传递

步骤:
①父组件中给需要接收参数的子组件绑定自定义事件,值为需要接收值的函数:

<son @handler="handlerMsg"></son>


methods:{
   handlerMsg(value){
       console.log(value)// 这个值是通过this.$emit()触发传来的
   }
}

3、非父子传递

第一种方法:通过给vue原型上添加一个公共的vue实例对象(vue实例对象上有on()和emit()),需要传递的一方调用emit(),需要接收的一方调用on()。

步骤:
①main.js中:Vue.prototype.$observer=new Vue();

②需要传递的组件中:this.observer.emit("handler",100);

③需要接收的组件中:
this.observer.on("handler",(value)=>{
console.log(value)
});

注意:在挂载前(created)进行$on()绑定,先绑定好,再触发。

第二种方法:手动封装事件订阅observer

步骤:
①src下新建observer.js:

const eventList = {};

const $on = function(eventName, callback) {
    if (!eventList[eventName]) {
        eventList[eventName] = [];
    }
    eventList[eventName].push(callback);
}

const $emit = function(eventName, params) {
    if (eventList[eventName]) {
        let arr = eventList[eventName];
        arr.forEach((cb) => {
            cb(params);
        });
    }
}

const $off = function(eventName, callback) {
    if (eventList[eventName]) {
        if (callback) {
            let index = eventList[eventName].indexOf(callback);
            eventList[eventName].splice(index, 1);
        } else {
            eventList[eventName].length = 0;
        }
    }
}

export default {
    $on,
    $emit,
    $off
}

②main.js中用手动封装的observer替代new Vue()
import observer from "./observer.js";
Vue.prototype.observer=observer; ③在需要传递的组件中用this.observer.emit()触发自定义事件: this.observer.emit("customHandler","需要传递的值"); ④在需要接收的组件中用this.observer.on()绑定自定义事件: this.observer.$on("customHandler",this.toggle);
⑤清除自定义事件

beforeDestroy() {
    this.$observer.$off('customHandler')
},

第三种方法:事件总线(Eventbus)

步骤:
①先创建一个空实例:
let bus=new Vue();
②通过bus.on()绑定自定义事件: bus.on("customHandler",要触发的函数);
③通过bus.emit()来触发自定义事件: bus.emit("customHandler");

第四种方法:vuex

注:如果是亲兄弟:(父传子和子传父)

步骤:
①父组件中声明data数据 state:true ,将state通过props传给其中一个子组件:

<two :show="state"></two>
props:show

此时show的值随着state的变化而变化

②再通过另一个子组件去改变父组件的state:
标签上绑定自定义事件:
<one @customHandler="toggle"></one>
再在子组件内部通过emit()触发customHandler事件: this.emit("customHandler");

provide / inject(提供/注入)跨组件传值,其实就是父传子

provide / inject:依赖注入。可以实现跨组件传值,数据的流向只能是向下传递,就是大范围有效的props
provide:这个配置项必须要在父级进行使用,用来定义后代组件所需要的一些属性和方法。

provide(){
    return{
    
    }
}

inject:这个配置项必须在后代组件中使用,用来获取根组件定义的跨组件传值的数据。

 inject:{
    key:{
        from:"父组件名称",
        default:默认值
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容