Vue之父子组件传值

单项数据流‘:父组件可以随意传数据给子组件,  父可以随意修改 , 子不能修改父的数据,会报错。

如果子组件修改了父组件的数据。那么会对其他的子组件也会有相应的影响。

处理方式:父组件的值,子组件接收够用一个变量接收。这样就变成子组件自用的了 (完美解决)

父组件向子组件传值:通过属性传值

父组件要传值给子组件,需要在子组件上绑定属性(用v-bind动态绑定,如果不用那就相当于传入固定值),子组件需要使用props来接收父组件传的数据。以下就是简单的父向子组件传值

首先在头便签引入vue

<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<div id="app">
    <my-div :number ="number"></my-div> 
</div>
<script>
    //定义子组件
    Vue.component("my-div", {
        props: ['number'], //接收父级数据
        template: `            
                    <div>
                        <h1>联系方式</h1>
                        <p>联系电话{{number}}</p>
                    </div>`
    })
    new Vue({
        el: "#app",
        data: {
            number: 7758258
        },
    })
</script>

当然,对于props我们可以在深入了解。他可以限定父级传的数据类型,只有符合的类型才接收 

对于props的简单了解可以直接搜索我的 prop文章

对于props的深入可以参考一下文章 https://www.cnblogs.com/xiaohuochai/p/7388866.html

比如我们规定父组件传过来的数据必须是Number类型的。(如果不是数据也会显示,但是控制台会抛出错误)

Vue.component("my-div", {
    props: {
        number:{
            type:Number
        }
    }, 
    template: `            
                <div>
                    <h1>联系方式</h1>
                    <p>联系电话{{number}}</p>
                </div>`
})
new Vue({
    el: "#app",
    data: {
        number: 7758258
    },
})

对于以上代码。如果我们子组件要改变父组件传的数据,就需要一个变量接收,克隆接收过来的副本。(小问题。因为是克隆出来的,当父组件数据变化时候,子组件的数据是不会变化的) 

以下代码就是把父组件传的数据用变量接收了,点击btn的时候只改变父组件的,改变不了子组件的

<div id="app">
    <div>{{number}}</div>
    <my-div :number="number"></my-div>
    <button @click="Clickbtn">点我</button>
</div>
<script>
    //定义子组件
    Vue.component("my-div", {
        props: {
            number: {
                type: Number
            }
        },
        data() {
            return {
                num: this.number
            }
        },
        template: `            
                  <div>
                    <h1>联系方式</h1>
                    <p>联系电话{{num}}</p>
                  </div>`
    })
    new Vue({
        el: "#app",
        data: {
            number: 7758258
        },
        methods: {
            Clickbtn() {
                this.number++
            }
        }
    })
</script>

父子组件的动态值:

因为是动态绑定数据。所以我们能在改变父组件的数据时同时也改变子组件。

<div id="app">
    <my-div :number="number"></my-div>
    <h1>父组件数据</h1>
    <div>{{number}}</div>
    <button @click="Clickbtn">点我</button>
</div>
<script>
    //定义子组件
    Vue.component("my-div", {
        props: {
            number: {
                type: Number
            }
        },
        data() {
            return {
                num: this.number
            }
        },
        template: `            
                <div>
                <h1>子组件数据</h1>
                <p>{{number}}</p>
                </div>`
    })
    new Vue({
        el: "#app",
        data: {
            number: 1
        },
        methods: {
            Clickbtn() {
                this.number++
            }
        }
    })
</script>

 子组件变量接收父组件数据后:

这时候我们改变父组件数据,子组件不不会变化。我们给子组件添加了点击事件。可以单项改变子组件的值。不影响到其他组件

<div id="app">
    <my-div :number="number"></my-div>
    <h1>父组件数据</h1>
    <div>{{number}}</div>
    <button @click="Clickbtn">点我</button>
</div>
<script>
    //定义子组件
    Vue.component("my-div", {
        props: {
            number: {
                type: Number
            }
        },
        data() {
            return {
                num: this.number
            }
        },
        methods: {
            Clickbtn() {
                this.num++
            }
        },
        template: `            
                <div>
                <h1>子组件数据</h1>
                <p>{{num}}</p>
                <button @click="Clickbtn">点我</button>
                </div>`
    })
    new Vue({
        el: "#app",
        data: {
            number: 1
        },
        methods: {
            Clickbtn() {
                this.number++
            }
        }
    })
</script>

子组件像父组件传值:通过事件传值

现在我们需要实现父组件和子组件的数据累加。这时候我们需要把子组件改变的数据传到父组件。我们可以使用事件将数据传递到父组件。

在组件定义一个$emit()事件。参数:第一个参数为自定义事件名(像下面的foo为对应的回调函数,写在父组件中,因为整个模板都是定义在父组件中,对应的函数就写在父组件中)。其他参数为子组件传给父组件的数据(参数不限)

自定义事件child 在子组件点击的时候被触发。在父组件定义foo函数。

每当子组件点击事件触发,父组件都会执行foo函数

 

下面我实现一个小功能:做一个累加器。数据一个来自子组件,一个来自父组件(代码有点冗余)。这里用计算属性来解决非常实用!自己实现咯~

思路:

父组件传值给子组件(属性传值)。子组件定义变量接收。然后可以私有化后修改。

通过点击事件修改数值。这时候触发自定义事件,将修改的值传给父组件。

父组件函数foo以参数形式接收子组件数据,

此时我们改变的值需要实时反馈到累加器上。我们就在foo函数中直接操作了父组件和子组件的数据相加。

但是这有一个问题:子组件修改我们能实时改变累加器。父组件数据修改不行。因为父组件定义点击函数中拿不到子组件的数值。(自己的折中办法就是父组件定义一个变量接收子组件的值,然后去实现改变。方法是可行的。应该还用更简单的操作办法)

代码如下:

<div id="app">
    <h1>合计{{add}}</h1>
    <my-div :number="number" @child="foo"></my-div>
    <p>父组件数据</p>
    <div>{{number}}</div>
    <button @click="Clickbtn">点我</button>
</div>
<script>
    //定义子组件
    Vue.component("my-div", {
        props: {
            number: {
                type: Number
            }
        },
        data() {
            return {
                num: this.number
            }
        },
        methods: {
            Clickbtn() {
                this.num++
                //点击事件触发自定义事件child
                this.$emit('child', this.num)
            }
        },
        template: `            
            <div>
            <p>子组件数据</p>
            <p>{{num}}</p>
            <button @click="Clickbtn">点我</button>
            </div>`
    })
    new Vue({
        el: "#app",
        data: {
            number: 1,
            childNum: '',
            add: ''
        },
        methods: {
            Clickbtn() {
                this.number++  
                this.add = this.childNum + this.number
            },
            foo(num) {
                this.childNum = num
                this.add = this.childNum + this.number
            }
        }
    })
</script>

优化后的代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <h1>合计:{{add}}</h1>
        <my-div :number="number" @child="foo"></my-div>
        <p>父组件数据</p>
        <div>{{number}}</div>
        <button @click="Clickbtn">点我</button>
    </div>
    <script>
        Vue.component("my-div", {
            props: {
                number: {
                    type: Number,
                    required: true  //必传
                }
            },
            data() {
                return {
                    num: this.number
                }
            },
            methods: {
                Clickbtn() {
                    this.num++
                    //点击事件触发自定义事件child
                    this.$emit('child', this.num)
                }
            },
            template: `            
                <div>
                <p>子组件数据</p>
                <p>{{num}}</p>
                <button @click="Clickbtn">点我</button>
                </div>`
        })
        new Vue({
            el: "#app",
            data: {
                number: 1,
                childNum: '',
            },
            methods: {
                Clickbtn() {
                    this.number++
                },
                foo(num) {
                    this.childNum = num
                },

            },
            computed: {
                add() {
                    return this.childNum + this.number
                }
            }
        })
    </script>
</body>

</html>

通过以上。我们能简单了解和学习父子组件的传值,以及对vue单项数据特点的认真。

以及关于非父子组件,vue更是给了vuex插件帮我们解决的这个难题(当数据量小的时候。我们也可以通过总线模式解决)

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值