vue - 父子组件通信、插槽

目录

组件

父子组件

组件的语法糖注册方法

组件使用数据

父子通信

 props的大小写

子父通信

父组件访问子组件

子组件访问父组件/访问根组件

插槽

具名插槽 

作用域插槽


组件

组件的定义——实现应用中局部功能代码和资源的集合;

  • 全局组件 Vue.component('标签名' , { })  可以在多个vue实例中使用;
  • 局部组件 components:{'标签名' : { } } 只能在在注册的vue实例中使用;
  1. 创建组件构造器; 传入一个配置对象; 这个对象除了el配置项,其他的都有;
  2. 注册组件; 两个参数, '组件标签' 和 构造器名字
  3. 使用组件; 在挂载点中使用;

    

注意:

  • 调用Vue.extend()方法 - 创建组件构造器
  • 调用Vue.component()方法 - 注册组件
  • 在Vue实例的作用范围内 - 使用组件
  • 组件构造器中的template中可以用引号(不能换行),用反引号(字符串模板可以换行);要有一个根标签
    包裹;
  • 在vue实例的配置项,components:{ } 注册局部组件 ;
  • 对象的key值,可以加引号(当做字符串),也可以不加(变量)
  • 对象字面量的增强写法:  函数名: funtion() 可以省略:function ;
  • 对象的字面量增强写法: 对象的属性名和属性值一样,是个变量可以省略一个;

父子组件

子组件在父组件中注册,在父组件中使用;

在父组件的构造器对象的配置项: coponents:{ } 中注册子组件,;在template模板中使用组件;


    

组件的语法糖注册方法

省略Vue.extend()书写,直接把配置对象{ }写到注册组件中去(替换了构造器名字);

构造器名字,直接写成一个对象;这个对象就是之前构造器传入的配置对象;

但Vue会仍会自动的将此对象给Vue.extend()

// 内部会自动调用Vue.extend()

    

组件构造器的配置对象中的template模板的抽离写法: 

template模板写:  '选择器';

template便签内写:  选择器; 需要有个根标签

包裹;
内写需要的模板;

template标签不会被渲染,


    

组件使用数据

子组件不能直接使用父组件中的数据;

vue实例也是一个父组件,root根组件;

组件可以使用自己组件内的data配置项中的数据;

组件的data属性,必须是一个函数,且返回一个对象;

组件也有自己的data属性(在vue.extend()的配置对象中),必须是一个函数,且返回一个对象;


  

父子通信

通过props实现父子通信;

把父组件的数据传递给子组件;子组件来使用;

vue - 父子组件通信、插槽_第1张图片

父组件通过props向子组件传递数据 [props=> property 属性]

方法一:   props:[ ]

  • 在子组件的配置对象中的添加props配置项,是一个数组;
  • 数组中的字符串是变量, 用来接受父组件传递过来的数组;
  • 使用子组件时,用v-bind属性绑定, 用props中的变量接受父组件中的数据;
  • 在子组件的模板中使用这些props[ ]中的变量;

  

方法二:  props:{ }

  • props是一个对象时, 可以对props中的变量(key)进行类型限制;
  • 这些变量是用来接受父组件传递过来的数据的;
  • 这些变量是key,可以加引号,也可以不加;
  • 这些变量对应的value可以是一个对象,对这个变量进行限制;
  • required: true 表示这个变量必传;
  • default 是当没有数据接收时,显示默认值;
  • 当数据类型是数组或对象时, 默认值必须是一个函数,且return 默认值;
   props: {
    cmsg:String, //字符串类型
     cbooks: {
      type:[ Array, Object ]// 数组或对象类型
      // 当数据类型是对象或数组时, default必须是一个函数,且返回默认值
      //default是没有接受数据时,才会显示默认值,与required一起添加到同一个对象上有点冲突;
       default() {
         return ['大闹天宫']
         //return { }
         },
      // 必须要传的值 
       required: true
             }
       }

props的数据类型验证:

vue - 父子组件通信、插槽_第2张图片

 props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)

    propA: Number,// 要求这个变量的数据类型是Number;

    // 多个可能的类型
    propB: [String, Number],//数据类型是字符串或数字类型;

    // 必填的字符串
    propC: {
      type: String, // 数据类型是字符串类型,且这个变量必须使用;
      required: true
    },

    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100  // 默认值,当没有接受数据时,默认值显示
    },

    // 带有默认值的对象或数组
    propE: {
      type:[Object,Array],
      // 当数据类型是对象或数组时, 默认值必须函数获取且 return 默认值;
      default: function () {
        return { message: 'hello' }
        //return [ ]
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }

 props的大小写

  • camelCase (驼峰命名法)   myName;
  • kebab-case (短横线分隔命名)  my-name;

  1.    在props里 接收数据的变量定义时, 用驼峰命名; 
  2.    但接收父组件的数据时(v-bin:) 要用短横线分割法命名;
  3.     在template模板中,使用变量时 用驼峰命名

    

子父通信

通过自定义事件,进行子父通信;

把子组件中的数据传递给父组件,父组件来使用;

  • 在子组件的methods{ }中,子组件的事件处理函数中,通过 this.$emit('自定义事件' ,参数 ) 把自定义事件发射出去;
  • 在父组件的标签中,接收这个自定义事件,并通过v-on进行事件监听这个自定义事件, 把自定义事件 赋值给父组件,让父组件来处理这个自定义事件;
  • 在父组件的methods{ } 中, 处理父组件的处理函数;
  • 子组件传递过去的参数,默认父组件的处理函数可以直接使用;

vue - 父子组件通信、插槽_第3张图片


    

父组件访问子组件

父组件可以直接访问子组件的数据,调用子组件的方法等;

  • $refs ( 子组件中 ref='标记')     =>访问指定的子组件
  • $children  => 访问所有子组件
  • 父组件通过$children访问子组件;
  • 会得到一个数组,通过数组的下标访问,不推荐这种方式,因为可能插入新的组件,导致下标错位;
  • vue组件数组  [VueComponent]
  • 
        
  • 父组件通过$refs访问子组件 (推荐)
  • 得到的, 默认是一个空的对象
  • 需要在组件上添加 ref='标记',这个属性; 这个对象不为空,'标记'作为对象的key;
  • {a: VueComponent}
  • 这个'标记'会作为对象的key,通过点语法来访问,得到value;
  • 父组件通过这个方法访子组件更准确,拿到指定的子组件;

  

子组件访问父组件/访问根组件

子组件可以访问父组件,直接使用父组件的数据,或调用父组件的方法

  • this.$parent 访问上一级父组件
  • this.$root 访问根组件

  

插槽

vue - 父子组件通信、插槽_第4张图片

vue - 父子组件通信、插槽_第5张图片

  • 具名插槽
  • 匿名插槽
  • 作用域插槽
  • 预留插槽就是预留一个空间,插槽内放东西,让组件具有更强的扩展性;
  • 插槽写在组件的template模板中;
  • 的位置即组件标签的位置;
  • 插槽就是 把组件标签内容的显示;
  • 插槽的三种情况如下:
  • 1.组件标签内无内容, 内放内容, 显示里的内容,插槽的默认值;
  • 2.组件标签内有内容,内无内容,显示组件标签的内容;
  • 3.组件标签内和内都有那内容, 组件里的内容会替换里的内容;
  • 3.组件标签内的内容会作为一个整体  替换插槽内所有的内容

vue - 父子组件通信、插槽_第6张图片

vue - 父子组件通信、插槽_第7张图片

    

你好

hello


具名插槽 

 具名插槽 : 有名字的插槽;



  • 组件标签内的 元素添加slot属性
  • 插槽slot标签 添加 name 属性
  • 这两个属性值相同,即可更改对应的内容;
  • 组件标签内的内容会作为一个整体  替换插槽内所有的内容
  

编译作用域

父组件模板的所有东西都会在父级作用域内编译;

子组件模板的所有东西都会在子级作用域内编译。

作用域插槽

父组件替换插槽的标签,但是内容由子组件来提供。

  • 在子组件模板的使用插槽, 这个插槽通过v-bind属性绑定, 把子组件的数据赋值给标签B;  v-bind:bbb="books"
  • 使用子组件标签时,使用