Vue 的组件最核心的选项有以下几个: 
模板(template)
初始数据(data)
接受的外部参数(props)
方法(methods)
生命周期钩子函数(lifecycle hooks)
组件 props
组件中更重要的是组件间进行通信,选项props是组件中非常重要的一个选项,起到父子组件间桥梁的作用。
1.静态props
子组件使用父组件的数据
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <my-componet message="来至父组件的数据!!"></my-componet>
</div>
<script type="text/javascript">
    Vue.component('my-componet', {
        // 声明 props
        props: ['message'],
        // 就像 data 一样,prop 可以用在模板内
        // 同样也可以在 vm 实例中像 “this.message” 这样使用
        template: '<span>{{ message }}</span>'
    })
    new Vue({
        el:'#app'
    });
</script>
</body>
</html>
动态 props 
动态接收父组件数据到子组件

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model="parentMessage">
    <my-componet :message="parentMessage"></my-componet>
</div>
<script type="text/javascript">
    Vue.component('my-componet', {
        props: ['message'],
        template: '<span>{{ message }}</span>'
    })
    new Vue({
        el:'#app',
        data:{
            parentMessage:''
        }
    });
</script>
</body>
</html>
这里使用 v-model 绑定了父组件数据 parentMessage,当在输入框中输入数据时,子组件接收到的 props“'message'”也会实时响应,并更新组件模板。 
如果你在父组件中直接传递数字、布尔值、数组、对象时, 它所传递默认值字符串。如果想传递一个实际的数值,需要使用 v-bind ,从而让它的值被当作 JavaScript 表达式计算,代码如下:

<div id="app">
    <my-componet message="1+1"></my-componet><br>
    <my-componet :message="1+1"></my-componet>
</div>
<script type="text/javascript">
    Vue.component('my-componet', {
        props: ['message'],
        template: '<span>{{ message }}</span>'
    })
    new Vue({
        el:'#app'
    });
</script>
 props 验证
当组件给其他人使用时,推荐进行数据验证。
验证的type类型可以是:String、Number、Boolean、Function、Object、Array等。
如果传入子组件的 message 不是数字,则抛出警告

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example">
    <parent></parent>
</div>
<script>
    var childNode = {
        template: '<div>{{message}}</div>',
        props:{
            'message':Number
        }
    }
    var parentNode = {
            template:'<div class="parent"><child :message="msg"></child></div>',
            components: {
                'child': childNode
            },
            data(){
            return{
                msg: '123'
            }
    }
    };
    // 创建根实例
    new Vue({
        el: '#example',
        components: {
            'parent': parentNode
        }
    })
</script>
</body>
</html>
单项数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。之所以这样设计,是尽可能将父子组件解耦,避免子组件无意中修改了父组件的状态。

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example">
    <parent></parent>
</div>
<script>
    var childNode = {
            template:
        '<div class="child"><div><span>子组件数据</span>' +
                ' <input v-model="childMsg"> </div> <p>{{childMsg}}</p></div>' ,
        props:['childMsg']
    }
    var parentNode = {
            template:
        '<div class="parent"><div><span>父组件数据</span>' +
                ' <input v-model="msg"> </div> <p>{{msg}}</p> <child :child-msg="msg"></child></div>',
        components: {
            'child': childNode
        },
        data(){
        return {
            'msg':'match'
        }
    }
    };
    // 创建根实例
    new Vue({
        el: '#example',
        components: {
            'parent': parentNode
        }
    })
</script>
</body>
</html>
组件通信

组件关系有下面三种:父-->子、子-->父、非父子。

 

 

自定义事件
当子组件需要向父组件传递数据时,就要用到自定义事件。

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <my-component v-on:myclick="onClick"></my-component>
</div>
<script>
    Vue.component('my-component', {
        template:'<div>' +
            '<button type="button" @click="childClick">点击我触发自定义事件</button></div>' ,
        methods: {
            childClick () {
                this.$emit('myclick', '这是我暴露出去的数据', '这是我暴露出去的数据2')
            }
        }
    })
    new Vue({
        el: '#app',
        methods: {
            onClick () {
                console.log(arguments)
            }
        }
    })
</script>
</body>
</html>
$emit/$on
这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex

var Event=new Vue();
    Event.$emit(事件名,数据);
    Event.$on(事件名,data => {});
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <my-a></my-a>
    <my-b></my-b>
    <my-c></my-c>
</div>
<template id="a">
    <div>
        <h3>A组件:{{name}}</h3>
        <button @click="send">将数据发送给C组件</button>
    </div>
</template>
<template id="b">
    <div>
        <h3>B组件:{{age}}</h3>
        <button @click="send">将数组发送给C组件</button>
    </div>
</template>
<template id="c">
    <div>
        <h3>C组件:{{name}},{{age}}</h3>
    </div>
</template>
<script>
    var Event = new Vue();//定义一个空的Vue实例
    var A = {
        template: '#a',
        data() {
        return {
            name: 'beixi'
        }
    },
        methods: {
            send() {
                Event.$emit('data-a', this.name);
            }
        }
    }
    var B = {
        template: '#b',
        data() {
        return {
            age: 18
        }
    },
        methods: {
            send() {
                Event.$emit('data-b', this.age);
            }
        }
    }
    var C = {
        template: '#c',
        data() {
        return {
            name: '',
                age: ""
    }
    },
        mounted() {//在模板编译完成后执行
        Event.$on('data-a',name => {
            this.name = name;//箭头函数内部不会产生新的this,这边如果不用=>,this指代Event
        })
        Event.$on('data-b',age => {
            this.age = age;
        })
    }
    }
    var vm = new Vue({
        el: '#app',
        components: {
            'my-a': A,
            'my-b': B,
            'my-c': C
        }
    });
</script>
</body>
</html>