Vue组件传值:父传子、子传父、兄弟组件间的传值

父组件向子组件传值

 1.在子组件的 props 中以数组形式接收父组件传递过来的值

2.父组件在使用组件时在组件属性中使用 v-bind 指令动态传值给子组件。示例如下:

<body>
    <div id="app">
        <div>{{tip}}</div>
        <!-- 调用 tab-bar 组件并传值,注意动态传值要给属性名添加上 v-bind 指令 -->
        <tab-bar :tip="tip" :pnum="12" :pflag="true" :parr="arr" :pobj="obj"></tab-bar>
        <!-- 注:pnum 如果不加 : 的修饰符则 "12" 就是字符串类型了
            如果 pflag 不加 : 的修饰符则 "true" 也是一个字符串类型,不是布尔值了
            所以如果传递的值是数值或布尔型的值,: 的修饰符是可以改变数值的数据类型的,这点很重要
        -->
    </div>

    <script>

        // 定义一个全局组件
        Vue.component('tab-bar', {
            // 在 props 中以数组形式接收父组件传递过来的值
            props: ['tip', "pnum", "pflag", "parr", "pobj"],
            data() {
                return {
                    msg: '这是子组件中的内容'
                }
            },
            // 注意:模板组件中最外层必须是一个单元素
            template: `<div>
            <div>{{msg + "----" + tip}}</div>
            <div>{{12 + pnum}}</div>
            <div>{{pflag}}</div>
            <div>
                <li :key="index" v-for="(item, index) in parr">{{item}}</li>    
            </div>
            <div>{{pobj.name}}</div>
            <div>{{pobj.age}}</div>
            <div>{{pobj.gerder}}</div>
            </div>
            `
        })
        var vm = new Vue({
            el: '#app',
            data: {
                tip: '这是父组件中的内容',
                arr: ['apple', 'orange', 'banana'],
                obj: {
                    name: 'lisi',
                    age: 20,
                    gerder: 'male'
                }
            },
            methods: {}
        });
    </script>
</body>

注:父组件可以向子组件传递任意类型的值,但是如果要动态传递值则必须使用 v-bind (语法糖为 :)的方式,不然传递的值就是字符串类型了。

子组件向父组件传值

1.在子组件中通过 $emit() 来触发父组件中的自定义事件并传值,参数1为自定义事件名,参数2为要传递给父组件的值。

2.父组件在使用子组件时通过 v-on (语法糖为 @)来定义自定义事件并监听该事件的响应,通过 $event 作为事件响应参数来接收子组件传递过来的值

<body>
    <div id="app">
        <!-- 动态的为 div 中的字体大小赋值 -->
        <div :style="{fontSize: fontSize + 'px'}">这是父组件中的文字,其字体大小由子组件决定</div>
        <!-- 使用子组件并监听自定义事件将之绑定到 getFontSize 上 -->
        <!-- 通过 $event 来接收子组件传递过来的值 -->
        <!-- <container v-on:font-size="getFontSize($event)"></container> -->
        <container @font-size="getFontSize"></container>
        <!-- 注:以上两行的写法都是可以的,效果完全相同 -->
    </div>

    <script>
        var container = {
            data() {
                return {
                    // 定义一个变量,这个值最终会传递给父组件
                    fontSize: 30
                }
            },
            created() {
                // 在 created 生命周期函数中调用向父组件传值的函数
                this.setFontSize()
            },
            methods: {
                // 此函数用于通过 $emit 自定义事件向父组件传值
                setFontSize() {
                    // 通过 font-size 自定义事件传递一个组件中定义的 fontSize 值
                    this.$emit('font-size', this.fontSize)
                }
            },
            template: `<p>这是子组件中的内容,其定义了一个 font-size={{this.fontSize}}px 的量传递给了父组件</p>`,
        }
        var vm = new Vue({
            el: '#app',
            data: {
                // 定义一个变量用于接收子组件传递过来的值
                fontSize: 0
            },
            methods: {
                // 监听子组件通过自定义事件传值的事件
                getFontSize(e) {
                    // 将接收到的值赋值给自己的 fontSize 变量
                    console.log(e);     // 30
                    this.fontSize = e
                }
            },
            components: {
                // 将 container 组件注册为 app 组件的子组件
                container
            }
        });
    </script>
</body>

非父子组件间传值(如兄弟组件)

1.非父子组件间的互相传值相当于发布订阅模式

2.通过 $emit()触发别的组件的自定义事件,并将组件中的值作为第二个参数传递出去

3.通过 $on()监听自定义事件的触发通过第二个参数来接收组件传递的值

<body>
    <div id="app">
        <tab-addtow></tab-addtow>
        <tab-addone></tab-addone>
    </div>

    <script>
        // 提供事件中心
        var hub = new Vue()

        // 全局组件 A
        Vue.component('tab-addtow', {
            data: function () {
                return {
                    num: 0
                }
            },
            template: `
            <div>
                <div>组件A:{{num}}</div>
                <button @click="addTow">点击组件A的按钮</button>
            </div>
            `,
            methods: {
                // 监听自己的按钮点击事件
                addTow: function () {
                    // 通过 $emit 来触发别的组件自定义的 add-tow 事件并传递一个值 2
                    hub.$emit('add-tow', 2)
                }
            },
            // 在 mounted 生命周期函数中监听组件中的自定义事件
            mounted: function () {
                // 监听自定义事件 add-one 并使用 val 来接收传递的值
                hub.$on('add-one', (val) => {
                    console.log(val);   // 1
                    this.num += val
                })
            }
        })

        // 全局组件 B
        Vue.component('tab-addone', {
            data: function () {
                return {
                    num: 0
                }
            },
            template: `
            <div>
                <div>组件B:{{num}}</div>
                <button @click="addOne">点击组件B的按钮</button>
            </div>
            `,
            methods: {
                // 监听自己的按钮点击事件
                addOne: function () {
                    // 通过 $emit 来触发别的组件中定义的 add-one 事件并传递一个值 1
                    hub.$emit('add-one', 1)
                }
            },
            // 在 mounted 生命周期函数中监听组件中的自定义事件
            mounted: function () {
                // 监听自定义事件 add-tow 并使用 val 来接收传递过来的值
                hub.$on('add-tow', (val) => {
                    console.log(val);   // 2
                    this.num += val
                })
            }
        })

        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {}
        });
    </script>
</body>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值