引入组件
- 
全局引入
在main.js文件中引入并注册
import ChildrenDemo from '@/views/components/ChildrenDemo' Vue.component('ChildrenDemo',ChildrenDemo)// 第一个参数 全局组件的名字(字符串类型),第二个参数:引入的组件名(一般都与组件名保持一致)之后就可以全局使用组件了
 - 
局部引入
在父组件中引入
import ChildrenDemo from '@/views/components/ChildrenDemo' export default { components: { ChildrenDemo }, }之后就可以在父组件中使用组件了
<ChildrenDemo></ChildrenDemo> <!-- 或 --> <children-demo></children-demo> 
一、props属性绑定(父组件向子组件传递数据)
在子组件 prop 中可以注册一些自定义组件属性,父组件调用子组件时可以向 prop 中的自定义属性传值。
子组件代码:
<template>
  <div class="ChildrenDemo">
    <h1>{{title}}</h1>
  </div>
</template>
<script>
export default {
  name: 'ChildrenDemo',
  props:['title'],
  components: {
  },
  data () {
    return {
    }
  }
}
</script>
父组件代码
<template>
  <div class="parent">
    <ChildrenDemo title="向子组件传递的title值"></ChildrenDemo>
  </div>
</template>
prop 也可以通过 v-bind 动态赋值
<ChildrenDemo :title="xxx"></ChildrenDemo>
如果要将一个对象的所有 property 都作为 prop 传入,你可以使用不带参数的 v-bind
例如,对于一个给定的对象 post
post: {
  id: 1,
  title: 'My Journey with Vue'
}
传给子组件
<blog-post v-bind="post"></blog-post>
等价于:
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>
props的更多写法
- 
字符串数组形式
props: ['title', 'likes', 'isPublished', 'commentIds', 'author'] - 
指定prop值类型
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor } - 
指定 prop 的验证要求
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
props: { // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } },注意: prop 会在一个组件实例创建之前进行验证,所以实例的 property (如
data、computed等) 在default或validator函数中是不可用的。 
prop双向绑定
一般情况下,子组件不能直接修改从父组件接收的属性值,否则会报错,如果子组件需要接收值后处理再使用,可以将接收的值赋值给子组件本身的属性,如data中的属性或计算属性。
如果希望子组件prop父组件中的值改变时,将变化同步到父组件中,可使用事件监听或**.sync修饰符**
.sync修饰符
.sync修饰符是一个语法糖,本质上等同于事件监听的方法
参考:vue的.sync修饰符用法及原理详解_weixin_58206976的博客-CSDN博客_vuesync修饰符
父组件
<h1>父组件title值:{{ title }}</h1>
<ChildrenDemo :title.sync="title"></ChildrenDemo>
子组件
<template>
  <div class="ChildrenDemo">
    <h1>子组件</h1>
    <input type="text" v-model="childTitle" />
  </div>
</template>
<script>
export default {
  props: ["title"],
  data() {
    return {};
  },
  computed: {
    childTitle: {
      get() {
        return this.title;
      },
      set(val) {
        this.$emit("update:title", val);//更新父组件中的title
      },
    },
  }
};
</script>
效果:当子组件中input内容改变时,父组件中的title会同步改变

二、监听子组件事件(子组件向父组件传递数据,子组件触发父组件方法)
通过 vue 实例方法 vm.$emit子组件可以自定义一个事件提交给父组件,触发父组件的方法,父组件通过监听子组件的自定义事件可以接收子组件传递的数据。
子组件
<template>
  <div class="ChildrenDemo">
    <h1>子组件</h1>
    <button @click="changeParentTitle">点击更改父组件title</button>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {};
  },
  methods: {
    changeParentTitle() {
      this.$emit("childEvent", "子组件传给父组件的title")//第一个参数是提交的事件名,后面的参数可以是多个需要传递给父组件的参数
    }
  }
};
</script>
父组件
<template>
  <div class="home">
    <h1>父组件title值:{{ title }}</h1>
    <ChildrenDemo :title="title" @childEvent="changeTitle"></ChildrenDemo>
  </div>
</template>
<script>
import ChildrenDemo from "@/views/components/ChildrenDemo";
export default {
  components: {
    ChildrenDemo,
  },
  data() {
    return {
      title: "My Journey with Vue"
    };
  },
  methods: {
    changeTitle: function (str) {
      this.title = str
    },
  },
};
</script>
上例中的操作和传递的值都比较简单,也可以在事件处理函数中直接使用表达式,父组件通过 $event 访问被子组件抛出的值
子组件:
<button @click="$emit('childEvent', '子组件传给父组件的title')">点击更改父组件title</button>
父组件:
<ChildrenDemo :title="title" @childEvent="title = $event"></ChildrenDemo>
三、使用 $refs (父组件访问子组件的数据和方法)
父组件使用 $refs 可以访问子组件的数据和方法
使用时需在调用子组件时给子组件定义一个 ref 名
<ChildrenDemo ref="childrenDemo"></ChildrenDemo>
<button @click="getChildData">点击获取子组件数据</button>
getChildData: function () {
  let child = this.$refs.childrenDemo//获取子组件实例
  console.log(child.value);//访问子组件属性
  child.childFn() //调用子组件的childFn()方法
},
注意:
$refs只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问$refs。- 由于ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 
mounted(){}钩子中调用,或者在this.$nextTick(()=>{})中调用。 
四、使用$parent(子组件访问父组件的数据和方法)
$parent property 可以用来从一个子组件访问父组件的实例
子组件:
<button @click="getParentData">点击获取父组件数据</button>
getParentData(){
  let parent = this.$parent //获取父组件实例
  console.log(parent.parentValue) //访问父组件属性
  parent.parentFn() //调用父组件的方法parentFn()
}