一、slot插槽
1、简单使用
可以在子组件模板中定义一个《slot》标签,作为插槽;
这样在父组件模板调用子组件模板时,可以在《cpn》《/cpn》中写入东西,比如
<cpn><p>我是一个p元素</p></cpn>
这个时候,
<p>我是一个p元素</p>
就会重写插槽内的默认值;
2、具名插槽
就是给每个插槽都加一个那么属性作为key,然后父组件模板在使用的时侯,必须也加上同名的属性标签,才可以插到插槽里面去;
3.编译作用域
就是说父组件模板所使用的所有标签,包括<cpn>这种子组件标签, 在他们的标签属性绑定时, 如果父组件实例和子组件实例都有这个变量, 但是还会使用父组件实例的变量,这个才是父组件模板的作用域;
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》区别不大;
但是还是有区别的,比如:
- 监听子组件时的一些事件比如像click这样原生事件需要加.native修饰符:我们需要写《cpn @click.native="m1" 》《/cpn》; 但如果是监听子组件的非原生事件,则不需要,比如子父组件通信时,介绍子组件的通信内容《cpn @acceptChildrenMsg="m1" 》《/cpn》
- 就是ref的用法,无论是子组件标签还是普通元素都可以加一个ref属性,然后通过this.$ref.ref名字即可获取这个组件,通过获取这个组件来获取组件的属性;就和我们在元素里写一个class=‘wrapper’或者id=‘wrapper’然后我们在css中可以通过.wrapper或者#wrapper获取到元素对象然后调整css样式一样,我们可以通过this.$ref.ref名字获取元素对象,然后在父组件实例中操作他们比如说betterscroll,就是需要获取组件对象的;;
父组件访问子组件
有两种方式,分别是this.$children或者this.$refs;
this.$children会放回一个数组,所以取某个子组件元素时需要用到下标比较麻烦,除非要取出所有的子组件元素,不然建议用第二个this.$refs,这个会在父组件模板中的每个<cpn>标签中加一个ref属性,比如
<cpn ref='aaa'></cpn>
这样的话就可以在父组件实例中,使用this.$refs.关键名取调用这个专门的子组件;