视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Vue.js特性Scoped Slots的浅析
2020-11-27 22:00:42 责编:小采
文档


上面是官方的定义。

作用域插槽(Scoped Slots)是vue.js中一个非常有用的特性,它可以使组件更加通用和复用。唯一的问题是理解起来比较困难。试图去让你理解父与子作用域的交织关系,像解决一道数学难题。

简单点说slot就是插槽,它是可以被替换掉的,替换它的内容是可以拿到当前组件的上下文的
(为了简单起见,以下例子以模板为主)

举个简单的例子

//button.vue
<template>
 <button class="btn">
 <slot></slot> //相当于是占位
 </button>
</template>

<script>
export default {

}
</script>
//app.vue
<template>
 <div id="app">
 <Button>Buton with text</Button>
 <Button>
 <i class="fa fa-copy"></i>//这里取代了slot的位置
 </Button>

 <Button>
 <i class="fa fa-user"></i>Profile
 </Button>

 </div>
</template>

<script>
 import Button from './components/Button.vue'
 export default {
 name: 'app',
 components: {
 Button
 }
 }
</script>

slot其实就是一个占位,button.vue的slot位置会被app.vue里面的替换了。

复杂例子1:slot内的东西可以获取父组件的上下文信息

//list.vue
<template>
 <div>
 <slot v-for="item in items"
 :item="item">//这里是slot的占位
 </slot> 
 </div>
</template>
//app.vue
<template>
 <div id="app">
 <List :items="listItems">
 <div slot-scope="row"
 class="list-item1">//这里可以获取到item,item原本是属于List组件内部的。也就是说slot获取了父组件的上下文。
 {{row.item.text}}
 </div>
 </List>
 </div>
</template>

解释见上面代码注释。注意一点的是slot-scope=”row” 这里的名字(row)是可以任意取的。

named slots

可以直接放到普通标签上面,可以放template标签上

slot里面的作用域是普通标签或者template是一致的。不能访问父组件的作用域。

复杂例子2:slot里面是可以放东西的,是默认的模板,可被替换。

//table.vue
<template>
 <table class="table">
 <thead>
 <slot name="columns">//这里定义了一个slot,名字叫columns,也就是说这里的内容是可以被替换掉的
 <th v-for="column in columns">
 {{column}}
 </th>
 </slot>
 </thead>
 <tbody>
 <tr v-for="item in data">
 <slot :row="item">//这里slot有一个prop是row
 <td v-for="column in columns"
 v-if="hasValue(item, column)">
 {{itemValue(item, column)}}
 </td>
 </slot>
 </tr>
 </tbody>
 </table>
</template>
//app.vue
<template>
 <div id="app">
 <CustomTable :data="tableData" 
 :columns="tableColumns">
 </CustomTable>

 <div class="table-separator"></div>

 <CustomTable :data="tableData">
 <template slot="columns">//这里有一个slot="columns",意思是替换table.vue里面名字叫columns的slot
 <th>Title</th>
 <th>
 <i class="fa fa-images"></i> Image
 </th>
 <th class="actions-row">
 <i class="fab fa-vuejs vue-icon"></i> Actions
 </th>
 </template>

 <template slot-scope="{row}">//这里替换table.vue里面slot为row的内部内容
 <td class="bold-row">
 {{row.title}}
 </td>
 <td class="img-row">
 <img :src="row.img">
 </td>
 <td class="actions-row">
 <Button @click.native="handleAction('Edit')">
 <i class="fa fa-edit"></i>
 </Button>
 <Button @click.native="handleAction('Delete')" type="danger">
 <i class="fa fa-trash"></i>
 </Button>
 </td>
 </template> 
 </CustomTable>
 </div>
</template>

下载本文
显示全文
专题