Vue中组件之间的传值

先简单说一下Vue中的组件,Vue中的组件为了能够在模板中使用,必须要先注册以便Vue能够识别到这个组件.组件注册分为两种类型:全局注册和局部注册.

有了组件,就会有或者涉及到组件之间的传值.总的来说,Vue组件之间的传值,主要分为3种类型或情况下的传值:

  1. 简单的父子组件之间的传值
  2. 同属于同一个父组件之间兄弟组件之间的传值
  3. 好不相关的组件之间的传值

简单的父子组件传值和同属于同一个父组件的兄弟组件之间的传值,Vue提供了方法可以直接进行传值,不需要Vuex.

简单父子组件之间的传值

为了看起来简单,文中的demo都写的非常简单,就是为了看起来简单,就是篇幅长了些.

父组件向子组件传值

父组件cmp.vue

<template>
    <div class="parent">
        {{msg}}
        <ComponentChild :parentToChildData="parentData"></ComponentChild>
    </div>
</template>

<script>
import ComponentChild from './cmpc'
export default {
    name:"componentP",
    components:{
        ComponentChild
    },
    data() {
        return {
            msg:"Hello, ComponentP",
            parentData:"我是来自父组件的数据"
        }
    }
}
</script>

子组件cmpc .vue

<template>
    <div class="componentA">
        <div>{{parentToChildData}}</div>
        <div>{{msg}}</div>
    </div>
</template>
<script>
export default {
    name:"componentA",
    data() {
        return {
            msg: "我是子组件的数据"
        }
    },
    props:["parentToChildData"]
}
</script>

我们先看父组件文件cmp.vue.

父组件中引入并注册了子组件ComponentChild,并通过props的方式向子组件传递了一个值:parentToChildData.然后子组件通过props方式接收到了从父组件传递过来的值.页面数据的渲染效果如下:

子组件向父组件传值

父组件cmp.vue

<template>
    <div class="parent">
        <p>{{msg}}</p>
        <p>{{data1}}</p>
        <!--
            @dataFromParent:父组件中定一的事件,可以简单的理解为就是和click、hover一样的事件,只不过不是内置的事件类型,而是一个自定义的事件名称;目的:在子组件中调用该方法,实现从子组件向父组件的值的传递
            dataFromChildToParent:事件响应函数,会在当前的组件中有具体实现
        -->
        <ComponentChild :parentToChildData="parentData" @dataFromParent="dataFromChildToParent"></ComponentChild>
    </div>
</template>

<script>
import ComponentChild from './cmpc'
export default {
    name:"componentP",
    components:{
        ComponentChild
    },
    data() {
        return {
            msg:"Hello, ComponentP",
            parentData:"我是来自父组件的数据",
            data1:""
        }
    },
    methods: {
        dataFromChildToParent(data){ //从子组件传递过来的数据
            this.data1 = data;
        }
    },
}
</script>

子组件cmpc.vue

<template>
    <div class="componentA">
        <h3>我是子组件</h3>
        <div>{{parentToChildData}}</div>
        <div>{{msg}}</div>
        <button @click="dataToParent">向父组件传递数据</button>

    </div>
</template>
<script>
export default {
    name:"componentA",
    data() {
        return {
            msg: "我是子组件的数据",
            childFromData:"新来的子组件数据"
        }
    },
    props:["parentToChildData"],
    methods: {
        dataToParent(){
            this.$emit("dataFromParent",this.childFromData);//dataFromParent:父组件中的方法;this.childFromData这个参数为子组件要向父组件传递的数据
        }
    },
}
</script>

这里就不演示效果了,如果有读者比较期待效果,可以直接将上面的代码复制到自己的项目中,然后建个路由就可以看效果了.

父组件通过props向子组件传递数据.我们需要注意,组件中数据共有3种形式的数据,即组件模板中的数据的来源有3个:data、props、computed.

data:就是组件初始化时的data函数了;

props:父组件传递过来的数据

compoted:模板中一些数据的展示依赖于data中一些属性的变化自动计算的值,来源时通过compoted计算的来的,本质上还是data.

对于这3点解释,是个人的一点见解,没有什么官方的说法,这就仁者见仁智者见智了.看怎么好理解就怎么理解了.

这个时候我们也许会想,我们直不把子组件中的数据上传给父组件了,而直接把子组件中的数据渲染到页面元素中不也可以吗?因为我把数据传递给了父组件,父组件也是会再通过props将这些数据通过子组件的元素来展示.从道理上来说是可以直接将自元素的新数据不传递给父组件,而仅在子组件本身处理这些数据,但这里又会涉及到一个问题,就是数据的整合问题,包括数据的遍历、循环等,会把数据的处理搞的很复杂,不如直接将子组件数据传递给父组件再通过props传递回来处理简单.

同属于一个父组件的兄弟节点之间的传值

其实这个比较好理解,及时在一个模板文件中,同时引用了多个子组件,那么这子组件中的一个有数值的变化了,其他子组件也会有相关的值的变化.这里并没有技术难点,就是把前面我们介绍过的父子组件之间的传值综合利用了起来.先将子组件A的值传递给父组件,然后父组件再通过props将从组件A获取到的数据传递给子组件B,这样实现了兄弟组件之间值的传递.

看个例子:

父组件componentP.vue

<template>
    <div>
        <div class="cmp1">
            {{msg}}
            <ComponentA @cmpAToParent="cmpASendDataToParent" :cmaData="cmadata"></ComponentA>
        </div>
        <div class="cmp2">
            <ComponentB :msgfromP="msg"></ComponentB>
        </div>
    </div>
</template>

<script>
import ComponentA from './componentA'
import ComponentB from './componentB'
export default {
    name: "ComponentBrother",
    data() {
        return {
            msg:"",
            cmadata:"父组件传递给组件A测试数据"
        }
    },
    components: {
        ComponentA, ComponentB
    },
    methods: {
        cmpASendDataToParent(data) {
            this.msg = data;
        }
    },
}
</script>

子组件A:componentA.vue

<template>
    <div class="cmp-a">
        <p>{{msg}}</p>
        <p>{{cmaData}}</p>
        <input type="text" class="ipt" v-model="username">
        <button class="btn" @click="comASendDataToParent">组件A向父组件传递数据</button>
    </div>
</template>
<script>
export default {
    name:'ComponentA',
    data(){
        return {
            msg:"组件A",
            username:""
        }
    },
    props:["cmaData"],
    methods: {
        comASendDataToParent(){
            this.$emit("cmpAToParent",this.username);
        }
    },
}
</script>

子组件B:componentB.vue

<template>
    <div>
        <p>{{msg}}</p>
        <p>A组件的变化,引起的B的变化:{{msgfromP}}</p>
        <button class="btn" @click="sentDataToParent">sendDataToParent</button>
    </div>
</template>

<script>
export default {
    name:'ComponentB',
    data(){
        return {
            msg:"组件B"
        }
    },
    props:["msgfromP"],
    methods: {
        sentDataToParent(){
            console.log("组件B中点击一下按钮");
        }
    },
}
</script>

demo中只实现了子组件A向子组件B的传值,没有做子组件B向子组件A传值的实现,道理是一样的.

兄弟节点之间的传值,除了上面的先子组件传递给父组件然后父组件再传递给子组件外,还有另外一种通过程序化的事件侦听器(也叫中央事件总线)来监听.

到此为止,有规律的组件之间的传值已经介绍完了,还有一种无规定关系组件之间的传值了.这种关系的组件之间的传值就不能通过上面介绍的方式来实现了,可以借助vuex来实现.

不相关组件之间的值的传递

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值