VUE工作生活

浅谈Vue父子组件传值

2019-07-03  本文已影响37人  前端艾希

demo代码

看了vue文档后写了个小demo来验证,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Counter</title>
    <script src="https://cdn.bootcss.com/vue/2.5.22/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <counter :num="0" @change="handelChange"></counter>
        <counter :num="0" @change="handelChange"></counter>
        <div>sum:{{total}}</div>
    </div>

    <script>
        Vue.component('counter', {
            props:{
                num: {
                    type: Number,
                    required: true,
                    validator: function (value) {
                        return (value < 1)
                    }
                }
            },
            template: '<div @click="handelClick">counter:{{number}}</div>',
            data() {
                return {
                    number: this.num
                }
            },
            methods: {
                handelClick: function() {
                    this.number += 1;
                    this.$emit('change', 1)
                }
            }
        })

        var vm = new Vue({
            el: '#app',
            data: {
                total: 0
            },
            methods: {
                handelChange(step) {
                    this.total += step
                }
            }
        })
    </script>
</body>
</html>

运行结果:


QQ20190703-154833-HD.gif

一、父组件向子组件传值(props传值)

1. 单向数据流概念

父组件通过props向子组件传值后,传给子组件值不允许被子组件修改,被称之为单向数据流

因为JavaScript中,复杂类型的值是引用类型的,即如果父组件向子组件传入了一个对象,如果子组件直接修改了这个对象,那么会直接导致其他引用了该对象的组件发生改变,产生难以预料的后果,所以如果子组件需要对传入的数据进行一定的处理,那么我们需要copy后再使用。

2. props数据验证

props应该是properties的简称,即属性,我们在组件中定义props对象,其中的元素即我们要传入的数据,我们可以直接这样写:

props:['num']

这样的话就是告诉父组件你只需要传入num就行了,并未对num做验证,有时子组件会对父组件传入的值做一定的要求,这时候就需要props数据验证了.

props:{
    num: {
        type: Number,  // 传入数据的类型
        required: true,  // 此处为true表示如果使用该组件就必须要传入该属性,false反之
        validator: function (value) {  // 自定义数据验证,这里要求传入的数据小于1
            return (value < 1)
        },
        default: 0  // 定义缺省值,如果未传数据,num的值就是缺省值
    }
}

3. props特性与非props特性

如果在组件中定义了props接受num传值,那么我们在使用该组件时,尽管我们在组件标签里写了 :num="0",但是这并不会显示到真实的dom节点中。

但是如果我们没有在props中声明num,那么如果我们写了 :num="0",这段代码会直接显示在dom节点的标签里,比如我们想给组件自定义样式,我们肯定会在组件标签中写 class="mystyle",class被称之为非props属性,是不会被传入到子组件中。

4. 传值属性的写法

在父组件的标签里面我们可以这么写:num="0",也可以这样写num="0",这两种写法有什么不一样呢?

:num="0"这样写采用了vue的模板语法v-bind,所以 = 后面的 " "里面是一个js表达式,即传入的值为一个js表达式

num="0"这样写的话,传入的值就是 = 后面的字符串。

二、子组件向父组件传值

1. emit发布消息

先看一下前面的代码:

handelClick: function() {
    this.number += 1;
    this.$emit('change', 1)  // 发布消息
}

我们在子组件中绑定了点击事件,点击事件的处理函数为handelClick,这段代码的意思是点击后除了number自增外,还会通过emit发布一个change消息,然后我们看一下父组件:

<counter :num="0" @change="handelChange"></counter>

我们在父组件中订阅了change消息,并给它绑定了handelChange函数。

上一篇 下一篇

猜你喜欢

热点阅读