vue插槽(slot)详解及element-ui表格操作列的插槽使用解析

发布于:2024-05-10 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、插槽的概念

image.png

image.png

组件标签中的内容,是不会显示在页面中的,要想显示出来,就要使用插槽

<template>
  <div class="child">
    child组件
    <slot />
  </div>
</template>

当在子组件中写上<slot />标签,书写在<Child></Child>中的内容便会在这个位置展示出来

image.png

二、具名插槽和匿名插槽

Child.vue

<template>
  <div class="child">
    <header>
      <slot name="header" />
    </header>
    <main>
      <slot />
    </main>
    <footer>
      <slot name="footer" />
    </footer>
  </div>
</template>

Parent.vue

<template>
  <div class="parent">
    parent组件
    <Child>
      <h1 slot="header">标题</h1>
      <p>内容</p>
      <p slot="footer">底部</p>
    </Child>
  </div>
</template>

image.png

slot标签的name属性就是具名插槽,否则就是匿名插槽,如果需要让某个内容显示在固定的位置上,可以考虑使用具名插槽

2.6.0+版本,父组件中可以这样写:

      <template v-slot:footer>
        <p>底部</p>
      </template>

但不能将v-slot:footer直接定义在p标签上

还可以使用#语法糖(v-slot:可以简写成#):

      <template #footer>
        <p>底部</p>
      </template>

三、插槽作用域

1、插槽作用域的作用:子组件可以传值给父组件

2、匿名插槽作用域传值

Child.vue

    <main>
      <slot :params="{ name: '小明', age: 18 }" />
    </main>

Parent.vue

老的写法

      <template slot-scope="scope">
        <p>
          内容
          {{ scope.params.name }}--{{ scope.params.age }}
        </p>
      </template>

2.6.0+ slot-scope可以写成v-slot

      <template v-slot="scope">
        <p>
          内容
          {{ scope.params.name }}--{{ scope.params.age }}
        </p>
      </template>

image.png

scope是自定义的变量名,可以用其他名字,也可以使用解构赋值

      <template v-slot="{ params }">
        <p>
          内容
          {{ params.name }}--{{ params.age }}
        </p>
      </template>

3、具名插槽作用域传值

Child.vue

    <header>
      <slot name="header" :params="{ name: '小明', age: 18 }" />
    </header>

Parent.vue

老的写法

      <template slot="header" slot-scope="scope">
        <h1>标题</h1>
        {{ scope.params.name }}--{{ scope.params.age }}
      </template>

2.6.0+

      <template v-slot:header="{ params }">
        <h1>标题</h1>
        {{ params.name }}--{{ params.age }}
      </template>

使用#简写:

      <template #header="{ params }">
        <h1>标题</h1>
        {{ params.name }}--{{ params.age }}
      </template>

image.png

四、解读el-table中使用的插槽

image.png

这里使用slot-scope="scope",说明el-table-column组件中通过slot标签传递了一些值供父组件使用

咱们来模拟一下: image.png

image.png

效果:

动画.gif

Parent.vue

<template>
  <div class="parent">
    parent组件
    <Child :tableData="tableData">
      <template v-slot="scope">
        <el-button @click="handleClick(scope.row)">查看</el-button>
        <el-button>编辑</el-button>
      </template>
    </Child>
  </div>
</template>
<script>
import Child from '../Child'
export default {
  components: { Child },
  data() {
    return {
      tableData: [
        { id: 1, name: '小明' },
        { id: 2, name: '小华' },
        { id: 3, name: '小王' }
      ]
    }
  },
  methods: {
    handleClick(row) {
      console.log({ ...row })
    }
  }
}
</script>
<style lang="less" scoped>
.parent {
  width: 200px;
  border: 1px solid deeppink;
  color: deeppink;
  padding: 10px;
}
</style>

Child.vue

<template>
  <div class="child">
    <div v-for="row of tableData" :key="row.id">
      <slot :row="row" />
    </div>
  </div>
</template>
<script>
export default {
  props: ['tableData']
}
</script>
<style lang="less" scoped>
.child {
  width: 150px;
  border: 1px solid deepskyblue;
  color: deepskyblue;
}
</style>