0
点赞
收藏
分享

微信扫一扫

Vue 组件插槽

萨科潘 2022-01-13 阅读 53
前端Vue

目录

一、组件插槽

1.1、单个插槽

2.2、具名插槽

2.3、作用域插槽

插槽,我要钻到你的怀里

默认插槽

具名插槽

作用域插槽

插槽默认值


一、组件插槽

组件的最大特性就是 复用性 ,而用好插槽能大大提高组件的可复用能力

1.1、单个插槽

当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,并 替换 掉插槽标签本身。

2.2、具名插槽

有时我们需要多个插槽,来完成对应的数据自定义显示。

一个不带 name 的 <slot> 出口会带有隐含的名字 “default” 。

自 2.6.0 起有所更新。已废弃的使用 slot

# 子组件
<div class="container">
  <header> 
<slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
</div>

# 父组件
<app-layout>
    // 老写法
    <h1 slot="header">这里可能是一个页面标题</h1>
// 新写法
// v-slot 只能添加在 <template> 上
// 简写 v-slot:header ==  #header
	<template v-slot:header>
    	<h1>这里可能是一个页面标题</h1>
 	</template>

  <p>主要内容的一个段落。</p>
</app-layout>

2.3、作用域插槽

作用域插槽 是一种特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样

<div id="app">
    <child :users='users'>
      <!-- 
        vue2.6之前
       -->
      <!-- <h6 slot="action" slot-scope="row" @click="pdel(row)">删除一下</h6> -->
      <!-- 
         vue2.6之后
        -->
      <!-- <template v-slot:action="row">
        <h3 @click="pdel(row)">删除</h3>
      </template> -->
      <template #action="row">
        <h3 @click="pdel(row)">删除</h3>
      </template>
    </child>
  </div>

  <script type="text/template" id="userhtml">
    <div>
      <table width="600" border="1">
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>操作</th>
        </tr>
        <tr v-for="(item,index) in users" :key="item.id">
          <td>{{item.id}}</td>
          <td>{{item.name}}</td>
          <td>
            <!-- 通过slot传数据,此slot为作用域插槽 -->
            <slot name="action" :info="item">
              <button @click="del(index)">删除</button>
            </slot>
          </td>
        </tr>
      </table>
    </div>
  </script>
  <script>
    const child = {
      props: ['users'],
      name: 'child',
      template: '#userhtml',
      methods: {
        del(index) {
          console.log(index)
        }
      }
    }

    const vm = new Vue({
      el: '#app',
      data() {
        return {
          users: [
            { id: 1, name: '张三' },
            { id: 2, name: '李四' },
            { id: 3, name: '王五' },
          ]
        }
      },
      components: { child },
      methods: {
        pdel(row) {
          console.log(row.info)
        }
      }

    })
  </script>



自己项目中的使用 , 仅供参考 :

比如我这里有很多页面的头部都一样,所以这里我们可以利用插槽的复用性来进行一下代码的简化 :

<template>
  <div>
    <div class="header">
      <img src="../assets/image/LOGO.png">
    </div>
      <!--具名插槽-->
      <slot name="content"></slot>
    </div>
  </div>
</template>

<script>
export default {}
</script>

使用 : 

<template>
  <div id="dwBodyUser">
    <public-header>
      <el-tabs
        v-model="activeName"
        @tab-click="handleClick"
        slot="content"
      >
        <el-tab-pane
          label="所有事项"
          name="first"
          :model="formData"
          ref="formDatas"
        >
          <!-- 所有事项组件 -->
          <all-matters></all-matters>
        </el-tab-pane>
        <el-tab-pane
          label="场景共享"
          name="second"
          :model="formData"
          ref="formDatas"
        >
          <!-- 场景共享组件 -->
          <scene-sharing></scene-sharing>
        </el-tab-pane>
      </el-tabs>
    </public-header>
  </div>
</template>

<script>
import publicHeader from '@/components/publicHeader/index.vue'
import allMatters from './component/allMattersTab.vue'
import screnSharing from './component/sceneSharingTab.vue'

export default {
  components: {
    publicHeader,  // 公共头部组件
    allMatters,    // 所有事项组件
    sceneSharing,  // 场景共享组件
  }
}
</script>

还有一个 公共 Table 示例 :

<!--作者 : 小灰狼
    功能 : 表格组件
    时间 : 2022/01-->
<template>
  <div>
    <el-table :data="tableList" style="width: 100%" :header-cell-style="{background: '#EFEFEF'}">
      <el-table-column type="selection" width="55" v-if="showCheckBox"></el-table-column>
      <el-table-column label="序号" width="120" v-if="showNumber">
        <template slot-scope="scope">{{ scope.$index + 1 }}</template>
      </el-table-column>
      <el-table-column v-for="item in headerList" :prop="item.props" :label="item.label" :min-width="item.minWidth"></el-table-column>
      <el-table-column fixed="right" label="操作" width="300">
        <template slot-scope="scope">
          <el-popconfirm title="是否确定?">
            <el-button slot="reference" style="color:#ED3740">{{ content }}</el-button>
          </el-popconfirm>
        </template>
        <!-- 事项操作插槽 -->
        <slot name="matterOperation"></slot>
        <!-- 场景操作插槽 -->
        <slot name="sceneOperation"></slot>
      </el-table-column>
    </el-table>
  </div>
</template>
 
<script>
export default {
  props: {
    tableList: {
      type: Array
    },
    headerList: {
      type: Array
    },
    showCheckBox: {   // 是否显示多选框
      type: Boolean,
      default: false
    },
    showNumber: {    // 是否显示序号
      type: Boolean,
      default: true
    },
    content: {
      type: String,
      default: "删除"
    },
  }
}
</script>
 
<style lang="scss" scoped>
  .cell button {
    border: none;
    padding-left: 0
  }
</style>

使用 :

<template>
  <div>
    <public-table
      :tableList="tableList"
      :showNumber="formData.showNumber"
      :headerList="headerList"
    >
      <!-- 场景操作插槽 -->
      <template #sceneOperation>
        <el-tooltip content="占位">
          <el-button
            size="small"
            icon="el-icon-edit-outline"
          ></el-button>
        </el-tooltip>
      </template>
    </public-table>
  </div>
</template>

<script>
import publicTable from '@/components/publicTable/index'

export default {
  components: {
    publicTable,  // 公共表格组件
  }
}
</script>
举报

相关推荐

0 条评论