Vue—05—组件高级之slot、子组件标签可定义的东西;


一、slot插槽

1、简单使用

可以在子组件模板中定义一个《slot》标签,作为插槽;

这样在父组件模板调用子组件模板时,可以在《cpn》《/cpn》中写入东西,比如

<cpn><p>我是一个p元素</p></cpn>

这个时候,

<p>我是一个p元素</p>

就会重写插槽内的默认值;

Vue—05—组件高级之slot、子组件标签可定义的东西;

 2、具名插槽

就是给每个插槽都加一个那么属性作为key,然后父组件模板在使用的时侯,必须也加上同名的属性标签,才可以插到插槽里面去;

 Vue—05—组件高级之slot、子组件标签可定义的东西;

 3.编译作用域

就是说父组件模板所使用的所有标签,包括<cpn>这种子组件标签, 在他们的标签属性绑定时, 如果父组件实例和子组件实例都有这个变量, 但是还会使用父组件实例的变量,这个才是父组件模板的作用域;

Vue—05—组件高级之slot、子组件标签可定义的东西;

4.插槽通信(作用域插槽)

父组件模板中, 用自己的样式替换子组件插槽的默认样式, 但是内容仍然由子组件模板的插槽提供;

具体来说, 就是某个父组件对子组件模板中的插槽展示的样式不满意, 想换一个样式去展示,  但是数据仍然由子组件提供, 如果使用子父组件通信的方式提供数据就麻烦, 有没有简单的插槽数据通信方式呢?有的, 就是作用域插槽;

<body>
    <!-- 父组件模板 -->
    <div id=app>
       <ccpn >
           <template slot-scope='abc'>
               <span v-for='item in abc.slotdata'>{{item}}*</span>
           </template>
       </ccpn>
       <ccpn >
        <template slot-scope='slot'>
            <span>{{slot.slotdata.join('-')}}</span>
        </template>
    </ccpn>
    </div>

    <!-- 子组件模板 -->
    <template id=ccpn>
        <div>
            <slot :slotData='myMessage'>
                <ul v-for='item in myMessage'>
                    <li>{{item}}</li>
                </ul>
            </slot>
        </div>
    </template>


    <script src=..\node_modules\vue\dist\vue.js></script>
    <script>
        //子组件实例
        const ccpn = {
            template:'#ccpn',
            data(){
                return {
                    myMessage:['haiwang','haierxiongdi','haizewang'],
                }
            },
        }

        //父组件(root组件)实例
        const app = new Vue({
            el:'#app',
            components:{
                ccpn,                    
            },

        })

    </script>   
</body>

注意:   有几个坑需要注意以下:

  • 1.调用作用于插槽时,   父组件模板需要在<cpn></cpn>中再加一个<template>标签,这个是固定写法; 
  • 2.在<template>添加属性slotscope,  随便起个名字, 上面的第一个名字起的abc, 第二个名字起的slot, 都可以使用; 使用方法    "slotscope名.子组件模板插槽标签属性名 ";  

这个插槽中,子父组件的通信,有没有插槽的父子组件通信,有的,

就是很简单的往子组件标签中加一个属性=数据值,这个属性是在子组件实例的props属性定义的,然后数据值就会传给子组件了;可是这和普通父子组件的通信是一样的。

 

 

二、子组件标签可定义的东西

我们可以给子组件标签定义很多东西,

 

我们可以通过v-on、v-bind、v-if、v-show、v-model去给子组件标签绑定很多东西;

这个时候子组件标签《ccpn》《/ccpn》和原生标签比如《div》区别不大;

 

但是还是有区别的,比如:

  1. 监听子组件时的一些事件比如像click这样原生事件需要加.native修饰符:我们需要写《cpn   @click.native="m1" 》《/cpn》;     但如果是监听子组件的非原生事件,则不需要,比如子父组件通信时,介绍子组件的通信内容《cpn   @acceptChildrenMsg="m1" 》《/cpn》
  2. 就是ref的用法,无论是子组件标签还是普通元素都可以加一个ref属性,然后通过this.$ref.ref名字即可获取这个组件,通过获取这个组件来获取组件的属性;就和我们在元素里写一个class=‘wrapper’或者id=‘wrapper’然后我们在css中可以通过.wrapper或者#wrapper获取到元素对象然后调整css样式一样,我们可以通过this.$ref.ref名字获取元素对象,然后在父组件实例中操作他们比如说betterscroll,就是需要获取组件对象的;;Vue—05—组件高级之slot、子组件标签可定义的东西;

     

     

 

父组件访问子组件

有两种方式,分别是this.$children或者this.$refs;

this.$children会放回一个数组,所以取某个子组件元素时需要用到下标比较麻烦,除非要取出所有的子组件元素,不然建议用第二个this.$refs,这个会在父组件模板中的每个<cpn>标签中加一个ref属性,比如

<cpn ref='aaa'></cpn>

 这样的话就可以在父组件实例中,使用this.$refs.关键名取调用这个专门的子组件;

 

上一篇:vue中使用slot


下一篇:Flink源码解析(四)——从Flink集群部署和任务提交模式看Flink任务的核心组件