Vue-组件之间的的数据传递

目录

组件的使用 

注册全局组件

props组件

组件之间样式冲突问题

父-子关系传递

子-父关系传递

兄弟之间的传递

ref引用 


什么是组件 只要是.vue后缀的文件都是一个组件

而组件之间是独立的,相互之间没有关系

当在使用组件的时候,根据彼此嵌套的关系就分为了 父子、兄弟关系

组件都是放在components文件夹中

组件的使用 

<div class="box">
    <!--以标签的形式使用注册好的组件 -->
    <Component></Component>
</div>


//1.导入需要用到的组件
import Component from '@/components/Component.vue'
components: {
    Component
}

注册全局组件

在项目中的main.js中,通过Vue.component()方法,进行全局注册

//导入需要全局注册的组件
import Component from '@/components/Component.vue'

// 参数1:字符串格式,表示组件的“注册名称”
// 参数2:需要被全局注册的那个组件
Vue.component('MyComponent',Component )

props组件

用于在父组件中向子组件传递数据

props 是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值

自定义属性的名字,是封装者自定义的 (只要名称合法即可)

props 中的数据,可以直接在模板结构中被使用

props是只读的,不能直接去修改它的值,否则报错

修改props的值就要把值转存到data中

// 父组件 Parent.vue
<template>
    <div class="child-container">
        <h3>Parent组件</h3>
        <hr />
        <!--引入了Count并给了初始值 5 如果没给则会用default初始的值-->
        <MyCount :message="message" :count="5"></MyCount>
    </div>
</template>

//引入子组件
import MyCount from '...'
export default{
    data() {
        return{
            count: 0,
            message: '你好啊!我的孩子。'
        }
    },
    components:{
        MyCount
    }
}

// 子组件
<div>
    <h3>MyCount组件</h3>
    <p>message的值是:{{message}}</p>
    <p>count的值是:{{count}}</p>
    <button @click="count++">点击+1</button>
</div>

export default{
     props:{
        //自定义属性a:{配置选项}
        count:{
            //定义初始值
            default: 0,
            //定义传值类型
            type: Number,
            //定义这是必填项,否则报错
            required: true
        },
        //定义message只能是String
        message: String  
    },
    data() {
        return{
            count: this.init,
        }
    }

}

上面父组件 通过 :message="message" 和:count="5" 的方式将这两个数据作为Props传递给子组件MyCount,子组件通过poros 选项声明需要接收的Props,既 message 和 count

组件之间样式冲突问题

默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题

导致组件之间样式冲突的根本原因是:

单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现

每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素

当使用第三方组件库的时候,如果有修改的第三方组件默认样式的需求,需要用到 /deep/

用法:

        /deep/  h5{}

父-子关系传递

父组件向子组件共享数据使用 自定义属性

<!-- Parent.vue 父组件 -->
<template>
    <div class="parent-container">
        <!-- @customEvent 来自 ChildA 传递的数据-->
        <ChildA :msg="message" @customEvent="handleCustomEvent"></ChildA>
        <ChildB v-model="dataFromChildB"></ChildB>
    </div>
</template>

//导入子组件ChildA和B
import ...A
import ...B

export default{
    components:{
        ChildA,
        ChildB 
    },
    data(){
        return{
            message: 'hello vue',
            dataFromChildB: ''
        }
    },
    methods:{
        handleCustomEvent(payload){
            //处理来自ChildA的事件
            log(payload)   
        }
    }
}

子-父关系传递

子组件向父组件共享数据使用 自定义事件

使用$emit进行传值

<!-- ChildA.vue 子组件 -->
<template>
    <div class="parent-container">
        <h3>子组件ChildA</h3>
        <p>{{message}}</p>
        <button @click="emitEvent">Emit Event</button>
    </div>
</template>

exprot default{
    props:['message'],
    methods:{
        emitEvent(){
            //this.$emit('自定义事件名',要传的值)
            this.$emit('customEvent','这是来自ChildA的消息')
        }
    }
}

 上面是父组件通过 props 将 message 传递给 childA子组件,并通过事件 customEvent 监听ChildA的按钮点击事件。

<!-- ChildB.vue 子组件 -->
<template>
    <div class="parent-container">
        <h3>子组件ChildB</h3> 
        <input v-model="inputData" />
    </div>
</template>

exprot default{
    props:['value'],
    data(){
        reurn{
            inputData: ''
        }
    },
    watch:{
        inputData(newVal){
            this.$emit('input',newVal);
        }
    }
    mounted(){
        //接收父组件的初始值
        this.inputData = this.Value 
    }
}

ChildB通过v-modle 接收父组件传递的值,并在输入框中修改后通过 $emit('input',newVal)将新值发送给父组件。

兄弟之间的传递

方案是EventBus 事件总线

EventBus的使用步骤

创建eventBusjs 模块,并向外共享一个 Vue 的实例对象

在数据发送方,调用 bus.$emit(事件名称,要发送的数据)方法触发自定义事件

在数据接收方,调用 bus.$on(事件名称,事件处理函数)方法注册一个自定义事件

//EventBus.js 
//创建eventBusjs 模块,并向外共享一个 Vue 的实例对象
import Vue from 'vue'
export default new Vue();

//ChildA
//在数据发送方,调用 bus.$emit(事件名称,要发送的数据)方法触发自定义事件
import bus from '@/EventBus'
export default{
    methods:{
        sendData(){
            bus.$emit('customEvent' '数据来自ChildA')
        }    
    }
}

//ChildB
//在数据接收方,调用 bus.$on(事件名称,事件处理函数)方法注册一个自定义事件
import bus from '@/EventBus'
export default{
    mounted:{
         bus.$on('customEvent' payload => {
               //处理来自ChildA的事件
               console,log(payload)
         })   
    }
}

ref引用 

用于在组件中获取对DOM元素或子组件的引用

通过 ref 可以在组件内部访问和操作所引用的元素或组件

//1、获取DOM元素的引用
//使用 ref属性 设置一个唯一的名称 然后通过 this.$refs.myButton获取Dom元素
<button ref="myButton"> ref 获取</button >

export default{
     mounted(){
          count button = this.$refs.myButton
          //进行操作
    }
}

//2、获取子组件的引用
<ChildA ref="myChild"></ChildA>

export default{
    components:{
        Child
    },
     mounted(){
      count myChild = this.$refs.myChild
      //调用子组件的方法或访问子组件的属性
    }
}

需要注意的是, ref 属性可以用在普通HTML元素上,也可以用在组件上。

但是在父组件使用ref获取子组件的引用时,子组件必须通过 components 选项进行注册

在 mounted 生命周期钩子中使用  this.$refs  访问 ref 引用是因为此时的子组件已经被挂载,在其它生命周期或方法中使用时,需要确保子组件挂载完成,然后才能访问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

朝夕相伴で

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

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

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

打赏作者

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

抵扣说明:

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

余额充值