vue组件传值,非父子有五种

前言

Vue的两大核心特性:
1、组件系统
2、数据驱动
因此组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。重点是可复用。
那么组件间传值有哪些呢?
常见就三类情况,父传子,子传父,非父子组件传值三种

1、父组件向子组件传值

1.1、props

即父组件通过属性的方式向子组件传值,子组件通过 props 来接收。

// 父组件
<son-component :toNumber="Number" />
    
export default {
    
    
    components: {
    
    
        SonComponent
    }
    ......
}

在子组件中使用props(可以是数组也可以是对象)接收即可。可以传多个属性。

// 子组件
export default {
    
    
    props: ['toNumber']
}

props有多种写法

//1、指定传入的类型,如果类型不对会警告
props: {
    
     toNumber: Number}
//2、多个可能的类型
props: {
    
     toNumber: [String, Number] }
//3、必填的数字
prosp: {
    
     toNumber: {
    
     type: Number, requires: true } }
//4、带有默认值
prosp: {
    
     toNumber: {
    
     type: Number, value: 1} }
//5、default指定默认值
props: {
    
     
    toNumber: {
    
     
        type: Number, 
        default: () => [] 
    }
} 

子组件接收的父组件的值分为引用类型和普通类型两种
普通类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)
引用类型:数组(Array)、对象(Object)

1.2、provide / inject

适用于祖孙,父子通信

// 父组件 
<div>
      <button @click="changeName">修改姓名</button>
      <child-b />
</div>
<script>
    ......
    data() {
    
    
        return {
    
    
            name: "Jack"
        };
    },
    provide() {
    
    
        return {
    
    
            parentObj: this //提供祖先组件的实例
        };
    },
    methods: {
    
    
        changeName() {
    
    
            this.name = 'Lily'
        }
    }
</script>
//后代组件
<template>
  <div class="border2">
    <P>姓名:{
    
    {
    
    parentObj.name}}</P>
  </div>
</template>
<script>
  export default {
    
    
    inject: {
    
    
      parentObj: {
    
    
        default: () => ({
    
    })
      }
    } // 或者inject: ['parentObj']
  };
</script>

2、子组件向父组件传值

2.1、 this.$emit()

子组件绑定一个事件,通过 this.$emit() 来触发

// 子组件
<button @click="changeParentName">改变父组件的name</button>export default {
    
    
    methods: {
    
    
        //子组件的事件
        changeParentName: function() {
    
    
            this.$emit('handleChange', 'ShuFeng') // 触发父组件中handleChange事件并传参ShuFeng
            // 注:此处事件名称与父组件中绑定的事件名称要一致
        }
    }
}
// 父组件
<child @handleChange="changeName"></child>
​
methods: {
    
    
    changeName(name) {
    
      // name形参是子组件中传入的值ShuFeng
        this.name = name
    }
}

2.2、 通过 callback 函数

// 父组件
<child :callback="callback"></child>
​
methods: {
    
    
    callback: function(name) {
    
    
        this.name = name
    }
}
// 子组件
<button @click="callback('shuFeng')">改变父组件的name</button>
​
props: {
    
    
    callback: Function,
}

2.3、通过 $parent / $children 或 $refs 访问组件实例

// 子组件
export default {
    
    
  data () {
    
    
    return {
    
    
      title: '子组件'
    }
  },
  methods: {
    
    
    sayHello () {
    
    
        console.log('Hello');
    }
  }
}
// 父组件
<template>
  <child ref="childRef" />
</template><script>
  export default {
    
    
    created () {
    
    
      // 通过 $ref 来访问子组件
      console.log(this.$refs.childRef.title);  // 子组件
      this.$refs.childRef.sayHello(); // Hello
      
      // 通过 $children 来调用子组件的方法
      this.$children.sayHello(); // Hello 
    }
  }
</script>

2.4、 $attrs / $listeners

$attrs / $listeners ,通常配合 inheritAttrs 一起使用。

//父组件
<template>
   <child :name="name" :age="age" :infoObj="infoObj" @updateInfo="updateInfo" @delInfo="delInfo" />
</template>
<script>
    import Child from '../components/child.vue'

    export default {
    
    
        name: 'father',
        components: {
    
     Child },
        data () {
    
    
            return {
    
    
                name: 'Lily',
                age: 22,
                infoObj: {
    
    
                    from: '上海',
                    job: 'policeman',
                    hobby: ['reading', 'writing', 'skating']
                }
            }
        },
        methods: {
    
    
            updateInfo() {
    
    
                console.log('update info');
            },
            delInfo() {
    
    
                console.log('delete info');
            }
        }
    }
</script>
//子组件
<template>
    <grand-son :height="height" :weight="weight" @addInfo="addInfo" v-bind="$attrs" v-on="$listeners"  />
    // 通过 $listeners 将父作用域中的事件,传入 grandSon 组件,使其可以获取到 father 中的事件
</template>
<script>
    import GrandSon from '../components/grandSon.vue'
    export default {
    
    
        name: 'child',
        components: {
    
     GrandSon },
        props: ['name'],
        data() {
    
    
          return {
    
    
              height: '180cm',
              weight: '70kg'
          };
        },
        created() {
    
    
            console.log(this.$attrs); 
       // 结果:age, infoObj, 因为父组件共传来name, age, infoObj三个值,由于name被 props接收了,所以只有age, infoObj属性
            console.log(this.$listeners); // updateInfo: f, delInfo: f
        },
        methods: {
    
    
            addInfo () {
    
    
                console.log('add info')
            }
        }
    }
</script>
//grandSon.vue 组件:
<template>
    <div>
        {
    
    {
    
     $attrs }} --- {
    
    {
    
     $listeners }}
    <div>
</template>
<script>
    export default {
    
    
        ... ... 
        props: ['weight'],
        created() {
    
    
            console.log(this.$attrs); // age, infoObj, height 
            console.log(this.$listeners) // updateInfo: f, delInfo: f, addInfo: f
            this.$emit('updateInfo') // 可以触发 father 组件中的updateInfo函数
        }
    }
</script>

3、非父子组件之间传值

3.1、$emit 和 props

适用于兄弟组件
在A兄使用$emit传值给到父组件,父组件在通过props传值给B兄

3.2、Bus总线程通信

通过建立一个第三方bus来做中转站,然后借用$emit 发送参数和 $on 来接受参数
建立一个bus.js

import Vue from 'vue'
export default Vue.prototype.bus = new Vue()

在main.js引入

import bus from './util/bus'
//发送信息组件
<template>
  <button @click="changeBus()">bus</button>  
</template>
...
methods: {
    
    
    changeBus(){
    
    
      this.bus.$emit("change",'yjw');
    }
}
//接受信息组件
 mounted(){
    
    
    let self = this;
    this.bus.$on('change',function(msg){
    
    
      console.log(msg);
      self.msg = msg;
    })
  }

3.3、Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,他适用于所有组件的传值,统一管理数据

3.4、provide / inject

1.2一样

3.5、 $attrs / $listeners

2.4一样

猜你喜欢

转载自blog.csdn.net/weixin_43236062/article/details/110954305