Vue插槽详解

文章目录

  • 1. 默认插槽
  • 2. 具名插槽
  • 3. 作用域插槽


插槽(slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

1. 默认插槽

概述:

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

使用:

父组件:

<template>
  <div>
    <h3 class="title">App组件h3>
    <hr />
    
    <child>
      <h3>我是标题h3>
    child>
    
    <child />
    
    <child>child>
  div>
template>

<script>
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {}
  },
  methods: {}
}
script>

<style lang="scss" scoped>style>

子组件:

<template>
  <div>
    <h3>child组件h3>
    
    
    
    
    <slot>默认slot>
  div>
template>

<script>
export default {
  data() {
    return {}
  },
  methods: {}
}
script>

<style lang="scss" scoped>style>

Vue插槽详解_第1张图片

2. 具名插槽

概述:

有时我们需要多个插槽,来完成对应的数据自定义显示。一个不带 name 的 插槽会带有隐含的名字“default”,即默认插槽。带 name 即为具名插槽。

使用:

父组件:

<template>
  <div>
    <h3 class="title">App组件h3>
    <hr />
    <child>
      
      
      
      
      
        
      
      
      
      
      <template #header>
        <h3>我是文章标题1h3>
      template>
      <template #header>
        <h3>我是文章标题2h3>
      template>
      
      <template #header>
        <h3>我是文章标题3h3>
      template>

      
      <div>默认插槽div>
    child>
  div>
template>

<script>
// 同步导入
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {}
  },
  methods: {}
}
script>

<style lang="scss" scoped>style>

子组件:

<template>
  <div>
    <h3>child组件h3>

    
    <slot name="header">默认头部slot>

    
    <slot>默认slot>
  div>
template>

<script>
export default {
  data() {
    return {}
  },
  methods: {}
}
script>

<style lang="scss" scoped>style>

Vue插槽详解_第2张图片

3. 作用域插槽

概述:

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

在封装组件的过程中,可以为预留的插槽绑定props 数据,这种带有props 数据的 叫做“作用域插槽”。作用域插槽就是在具名插槽的基础上,多了数据的传递。

语法:

# 子组件中
Vue.component('child', {
template: `
<div class="child">
    <slot name="default" text="我是子组件中的内容">slot>
div>
`
})

# 父组件中
<div class="parent">
    <child>
        // 老写法
        <div name="default" slot-scope="props">
            <div>父组件div>
            <h3>{{ props.text }}h3>
        div>
        // 新写法
        <template #default="props">
            <div>
                <div>父组件div>
                <h3>{{ props.text }}h3>
            div>
        template>
    child>
div>

使用:

父组件:

<template>
  <div>
    <h3 class="title">App组件h3>
    <hr />
    <child :users="users">
      
      

      
      

      
      
      <template #del="index">
        
        <button @click="del(index)">删除button>
      template>
    child>
  div>
template>

<script>
// 同步导入
import child from "./components/child.vue";
export default {
  components: {
    child,
  },
  data() {
    return {
      users: [
        { id: 1, name: "张三" },
        { id: 2, name: "李四" },
        { id: 3, name: "王五" },
      ],
    };
  },
  methods: {
    // 传过来的index是一个对象,所以需要解构一下
    del({ index }) {
      console.log("app", index);
    },
  },
};
script>

<style lang="scss" scoped>style>

子组件:

<template>
  <div>
    <h3>child组件h3>
    <hr />
    <ul>
      <li v-for="(item, index) in users" :key="item.id">
        <span>
          {{ item.name }}
        span>
        <span>
          
          
          <slot name="del" :index="index">
            <span @click="del(index)">删除span>
          slot>
        span>
      li>
    ul>
  div>
template>

<script>
export default {
  props: ['users'],
  data() {
    return {}
  },
  methods: {
    del(index) {
      console.log(index)
    }
  }
}
script>

<style lang="scss" scoped>style>

Vue插槽详解_第3张图片

你可能感兴趣的:(Vue,vue.js,javascript,前端)