关于vue.js:vue-组件传参

一、父子组件通信

1、props和$emit/$on

(1) 父组件向子组件传参

在父组件应用v-bind 传值,子组件中应用props接管参数

(2) 子组件给父组件传递数据——自定义事件

子组件通过$emit办法,触发父组件v-on的事件

  • 长处

应用简略,是父子组件最根底的传参办法。

props提供了类型查看反对

$emit不会批改到别的组件的同名事件,它只会触发父级事件,这里和event-bus不同

  • 毛病

多层组件须要逐层传递

不能解决多个组件依赖同一个状态的问题

2、$refs,$parent, $children

(1)子组件能够应用$parent 拜访父组件实例,父组件能够通过$children对子组件进行操作。

毛病:一个组件的子组件可能不是惟一的,返回值是一个数组。所以无奈确定子组件的程序。

(2)ref如果作用在DOM元素上,援用指向的是DOM元素;如果作用在子组件上,援用指向的是子组件实例,能够间接拜访子组件的数据和调研子组件的办法。

3、.sync 修饰符

开发过程中,咱们个别应用props/emit 实现双向绑定,为了不便起见,在2.3.0版本中提供了一个语法糖.sync修饰符。

<text-document v-bind:title.sync=”doc.title”></text-document>

二、兄弟组件通信

1、eventBus(地方事件总线)

evnetBus的原理是新建一个新的Vue实例,而后通过bus.$emit触发事件,bus.$on监听触发的事件,实现通信和参数的传递。

初始化bus

    Vue.prototype.$EventBus = new Vue()

或:

import Vue from 'vue' 
export default  Bus = new Vue()

父组件:

<template>   
<div>     
    <p>bus 实例父组件: {{msg}}</p>     
    <span @click="fatherBus">按钮</span>    
    <busChild />   
</div>
</template> 
<script> 
import Bus from '../assets/js/bus'
import busChild from './busChild' 
export default {
    data() {     
        return {       
            msg: 'bus demo'     
        }   
    },   
    components: {    
        busChild   
    },   
    methods:{
        fatherBus(){
            Bus.$emit('BusTo', this.msg)
        }   
        } 
    } 
</script>

子组件:

<template>   
    <div>     
        <p>Bus 实例子组件: {{child}}</p>   
    </div> 
</template>
<script> 
    import Bus from '../assets/js/bus.js' 
    export default {   
        data(){     
            return {       
                child: ''     
            }   
        },   
        mounted (){     
            Bus.$on('BusTo', (data)=>{       
                this.child= data     
            })   
        } 
    } 
</script>`

毛病:(1)页面刷新时,与之相干的eventBus会被销毁。

(2)因为应用一个Vue实例,定义同一个事件名,并没有用off销毁。

长处: 解决多层组件之间繁琐的事件流传

三、隔代组件通信

1、provide 和inject

provide和inject成对应用。作用是容许一个先人组件向其所有子孙后代注入一个依赖。

实用于先人组件和后辈组件之间的通信,无论组件的档次有多深,其上下游关系始终失效。

provide选项应该是一个对象或者返回对象的函数。

inject选项应该是字符串数组或对象。

<template>   
    <div class="provide">    
        <p>provide 实例父组件: </p>
        <span @click="clickHandler">按钮+1</span> 
        <injectTest />   
    </div>
</template> 
<script> 
import injectTest from './injectTest'
export default {   
    components: {     
        injectTest   
    },   
    provide (){     
        return {       
            test: this     
        }   
    },   
    data (){     
        return {       
            testData: 1     
        }    
    },   
    methods: {     
        clickHandler (){       
            ++ this.testData       
            console.log(this.testData)     
        }   
    } 
} 
</script>

子组件:

<template>   
    <div>     
        <p>inject 子组件实例:</p>     
        <span>{{test.testData}}</span>   
    </div> 
</template>
<script> 
    export default {   
        inject: ['test'],   
        mounted () {     
            console.log('this.test', this.test)   
        } 
    } 
</script>

毛病: 子组件获取父组件属的状态,父组件无奈获取子组件的状态。

2、$attrs 和$listeners

$attrs:蕴含了父组件在子组件上设置的属性,不蕴含prop传递的属性和class、style。

$listeners:蕴含了父作用域中的(不含.native润饰器)v-on事件监听器。即通过$listeners能够将先人组件中的事件,传递到后辈组件。

先人组件index:

<template>
<child1 :attr1="attr1" :attr2="attr2" @changeInfo="changeInfo"/> 
</template> 

<script>
import child1 from './components/child1'
export default {
    data () {     
        return {              
        attr1: 'hi, attr',       
        attr2: 'hello, attr'     
        }   
    }, 
    methods: {     
        changeInfo(){       
            console.log('attr and')     
        }
    } 
} 
</script>

子组件child1:

<template> 
    <p>父组件传值attr1: {{attr1}}</p> 
    //通过$attrs将先人组件的属性传递到后辈组件child2中,通过$listeners将先人组件中的事件传递到child2中 //从而child2能够拜访先人组件的属性和事件 
    <child2 v-bind="$attrs" v-on="$listeners"/> 
</template> 
<script> 
import child2 from './child2' 
export default {   
    components: {     
        child2   
    },   
    props: ['attr1'], 
    mounted (){     
    console.log('父组件中this.$attrs', this.$attrs)
    console.log('父组件中this.$listeners', this.$listeners)   
    }
} 
</script>

子组件child2:

<template>   
    <div>     
    <p>先人组件传参: {{$attrs}}</p>   
    </div> 
</template>
<script> 
export default {   
    name: 'attrDemo',   
    inheritAttrs: false, 
    mounted (){     
        console.log('父组件中this.$attrs', this.$attrs) console.log('父组件中this.$listeners', this.$listeners)
        this.$emit('changeInfo')   
    }
} 
</script>

补充:

新增属性inheritAttrs,默认状况下父作用域的不被认作props的attribute绑定将会“回退”且作为一般的HTML属性利用在子组件根元素上。

如果不心愿组件的根元素继承个性,能够设置inheriAttrs:false。

3、vuex

vuex是vue提供的状态管理模式。它采纳集中存储管理所用组件的状态。实用于多个组件状态共享,我的项目比拟大的状况。

优缺点:

  • 长处

解决了多层组件依赖同一个状态的问题

单向数据流

  • 毛病

页面从新加载时,数据须要从新写入

减少额定的代码体积,不实用在简略业务需要

参考文档:

$atttr 和$listener:

https://www.jianshu.com/p/4649d317adfe

https://blog.csdn.net/songxiugongwang/article/details/84001967

https://www.jianshu.com/p/a388d38f8c69

https://segmentfault.com/a/1190000022708579

eventBus:
https://segmentfault.com/a/1190000021707081

https://zhuanlan.zhihu.com/p/72777951

https://juejin.im/post/6844904167597686791#heading-2

https://juejin.im/post/6856359634039963656

https://juejin.im/post/6844903977100804103#heading-7

https://juejin.im/post/6844904048118726663#heading-21

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理