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>

1.3、ref和$refs

此方法是父组件调用子组件的方法,但是不建议常用,因为这个是DOM操作

// 父组件 
<div>
      <button @click="changeName">修改姓名</button>
      <child-b ref="chirld"/>
</div>
<script>
    ......
    data() {
        return {
            name: "Jack"
        };
    },
    provide() {
        return {
            parentObj: this //提供祖先组件的实例
        };
    },
    methods: {
        changeName() {
            this.$refs.chirld.changeName('Lily')
        }
    }
</script>
//子组件
<template>
  <div class="border2">
    <P>姓名:{{name}}</P>
  </div>
</template>
<script>
  export default {
  data(){
  	  return {
  	        name:'lili''
	  }
  }
    methods: {
        //子组件的事件
        changeName: function(name) {
            this.name = name
        }
    }
}
</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一样

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 父组件向子组件传值,使用 props 属性 父组件: ``` <template> <div> <child-component :message="message"></child-component> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { message: 'Hello, World!' } } } </script> ``` 子组件: ``` <template> <div> <p>{{ message }}</p> </div> </template> <script> export default { props: ['message'] } </script> ``` 2. 子组件向父组件传值,使用 $emit 方法组件: ``` <template> <div> <child-component @send-message="handleMessage"></child-component> <p>{{ receivedMessage }}</p> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { receivedMessage: '' } }, methods: { handleMessage(message) { this.receivedMessage = message; } } } </script> ``` 子组件: ``` <template> <div> <button @click="sendMessage">Send Message</button> </div> </template> <script> export default { methods: { sendMessage() { this.$emit('send-message', 'Hello, World!'); } } } </script> ``` 3. 使用 provide/inject 传递数据 父组件: ``` <template> <div> <child-component></child-component> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, provide() { return { message: 'Hello, World!' } } } </script> ``` 子组件: ``` <template> <div> <p>{{ message }}</p> </div> </template> <script> export default { inject: ['message'] } </script> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值