<template id="child1">
    <div>
        <h3>{{ firstChildComponentName }}</h3>
    </div>
</template>

<template id="child2">
    <div>
        <button @click="changeFirstChildComponentName">点击我</button>
    </div>
</template>

<div id="app">
    <h2>{{ parentComponentName }}</h2>
    <first-child :first-child-component-name="firstChildComponentName"></first-child>
    <second-child :change-first-child-component-name="changeFirstChildComponentName"></second-child>
</div>
body {
  background-color: #777;
  background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAQAAABuBnYAAAAAU0lEQVQIHQXBwRGDIBAAwO2/AMcCDHAcPjIRxjJ8Je1kl1uqUgphsWu6w0sIG6npLpcUBql4e/wsVRKabrkNTacIYbMrwsF06rqUhsnXVKVT+Hj+Ue4rPSONk4kAAAAASUVORK5CYII=);
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

#app {
  text-align: center;
  border: 1px solid #ccc;
  padding: 3vh 5vw;
  border-radius: 5px;
  position: relative;
  color: #fff;
  text-shadow: 1px 1px 1px rgba(0,0,0,.3);
  
  &:before {
    content: '父组件';
    position: absolute;
    left: -64px;
    top: 50%;
    transform: translateY(-50%);
    white-space: nowrap;
    padding: 5px;
    color: #fff;
    background-color: rgba(0,0,0,.8);
    border-radius:3px;
  }
  &:after {
    content: '';
    position: absolute;
    left: -6px;
    top: 50%;
    transform: translateY(-50%);
    border: 6px solid rgba(0,0,0,.8);
    border-color: transparent transparent transparent rgba(0,0,0,.8);
  }
  
  div {
    padding: 3vh 5vw;
    border: 1px solid darken(#678, 20%);
    border-radius: 3px;
    position: relative;
    margin: 2vw 0;
    
    &:before {
    content: '子组件';
    position: absolute;
    right: -71px;
    top: 50%;
    transform: translateY(-50%);
    white-space: nowrap;
    padding: 5px;
    color: #fff;
    background-color: rgba(0,0,0,.8);
    border-radius:3px;
  }
  &:after {
    content: '';
    position: absolute;
    right: -6px;
    top: 50%;
    transform: translateY(-50%);
    border: 6px solid rgba(0,0,0,.8);
    border-color: transparent rgba(0,0,0,.8) transparent transparent;
  }
    &:nth-of-type(1):before{
      content: '子组件1'
    }
    &:nth-of-type(2):before{
      content: '子组件2';
      right: -74px;
    }
  }
}

button {
  border: none;
  background: #123456;
  color: #FFFFFF;
  cursor: pointer;
  padding: 10px;
  border-radius: 4px;
  display: inline-block;
  outline: none;
  min-width: 60px;
}
View Compiled
let app = new Vue({
    el: '#app',
    data () {
        return {
          parentComponentName: 'W3cplus',
          firstChildComponentName: '大漠'
        }
    },
    methods: {
        changeFirstChildComponentName: function () {
            this.firstChildComponentName = 'Airen'
        }
    },
    components: {
        'firstChild': {
            template: '#child1',
            props: {
                firstChildComponentName: {
                    type: String,
                    default: ''
                }
            }
        },
        'secondChild': {
            template: '#child2',
            props: {
                changeFirstChildComponentName: {
                    type: Function,
                    default: () => {}
                }
            }
        }
    }
})
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js