Vue中的插槽Slot技术详解

一、引言

Vue.js是一款流行的前端框架,提供了强大的组件化功能。其中,插槽(Slot)技术是一种用于组件化开发的重要技术,允许我们在组件中定义一些占位符,然后在使用组件时,通过插槽来传递内容。插槽的灵活性使得我们可以轻松地定制组件的外观和行为,可以帮助我们更好地处理组件的可复用性和灵活性。

二、插槽基础使用

在Vue中,插槽的使用方式可以分为三种:默认插槽、具名插槽和作用域插槽。

1. 默认插槽

默认插槽是最简单的插槽形式,它允许我们将组件的内容传递到组件内部的一个占位符中。在组件的模板中使用定义默认插槽,然后在使用组件时,将内容传递给这个插槽。

1

2

3

4

5

6

7

// Com01.vue

<template>

  <h2>学习插槽</h2>

  <div>

    <slot>我是默认插槽,没给我传内容就会默认显示这句话</slot>

  </div>

</template>

1

2

3

4

5

6

7

8

9

10

// 父组件App.vue

<template>

  <Com01>

    <p>你好,世界!</p>

    <!-- <p>你好,世界!</p> -->

  </Com01>

</template>

<script setup>

import Com01 from './components/Com01.vue'

</script>

在上面的代码示例中,<slot></slot>表示一个默认插槽,将传递给Com01组件的内容放置在这个插槽中。如果把p标签那一行注释掉,就会显示默认内容。

2. 具名插槽

具名插槽允许我们在组件中定义多个插槽,并且可以根据插槽的名称来传递内容。在组件的模板中使用<slot name="slotName"></slot>定义具名插槽,然后在使用组件时,使用<template v-slot:slotName>或者<template slot="slotName">来传递内容给指定的插槽。

1

2

3

4

5

6

7

8

9

10

// 子组件 Com02.vue

<template>

  <div>

    <slot name="header"></slot>

    <div class="content">

      <slot></slot>

    </div>

    <slot name="footer"></slot>

  </div>

</template>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// 父组件 App.vue

<template>

  <Com02>

    <template v-slot:header>

      <h2>我是头部内容!</h2>

    </template>

    <h2>你好,世界!</h2>

    <template v-slot:footer>

      <h2>我是底部内容!</h2>

    </template>

  </Com02>

</template>

<script setup>

import Com02 from './components/Com02.vue'

</script>

3. 作用域插槽

作用域插槽是一种特殊的插槽,它允许我们在插槽内部访问组件实例的数据,允许父组件将数据传递到子组件中,并在子组件中使用。在组件的模板中使用<slot name="slotName" v-bind:slotData="data"></slot>定义作用域插槽,并在使用组件时,使用<template slot="slotName" v-slot="scope">来访问插槽内部的数据。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// 子组件 Category.vue

<template>

  <div class="category">

    <h3>{{title}}分类组件</h3>

    <slot :foods="foods" :games="games" :films="films">我是插槽1</slot>

  </div>

</template>

<script>

export default {

  name: "Category",

  props: ["title"],

  data(){

    return {

      foods: ["红烧肉","番茄炒蛋","鱼香肉丝"],

      games: ["红色警戒", "穿越火线", "魔兽世界"],

      films: ["肖申克的救赎", "火影忍者", "泰坦尼克号"]

    }

  }

}

</script>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 父组件 App.vue

<template>

  <div class="container">

    <Category title="食物" >

      <template v-slot="scope">

        {{ scope }}

      </template>

    </Category>

  </div>

</template>

<script>

import Category from './components/Category.vue'

export default {

  name: "App",

  components: {Category},

}

</script>

可以看到父组件中拿到的scope就是一个对象,包括了子组件中传来的三个数组,我们可以自己选择展示哪些数据。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

// 父组件 App.vue

<template>

  <div class="container">

    <Category title="食物" >

      <template v-slot="scope">

        <ul>

          <li v-for="item in scope.foods">{{ item }}</li>

        </ul>

      </template>

    </Category>

  </div>

</template>

<script>

import Category from './components/Category.vue'

export default {

  name: "App",

  components: {Category},

}

</script>

三、插槽的高级用法

1. 具名作用域插槽

具名作用域插槽的工作方式也是类似的,插槽props可以作为v-slot指令的值被访问到:v-slot:header="props",也可以直接缩写成#header="props",这是缩写形式。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

// 子组件 Category02.vue

<template>

  <div class="category">

    <h3>{{title}}分类组件</h3>

    <slot name="header" :foods="foods" >我是插槽1</slot>

    <slot name="center" :games="games" >我是插槽2</slot>

    <slot name="footer" :films="films" >我是插槽3</slot>

  </div>

</template>

<script>

export default {

  name: "Category",

  props: ["title"],

  data(){

    return {

      foods: ["红烧肉","番茄炒蛋","鱼香肉丝"],

      games: ["红色警戒", "穿越火线", "魔兽世界"],

      films: ["肖申克的救赎", "火影忍者", "泰坦尼克号"]

    }

  }

}

</script>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

// 父组件 App.vue

<template>

  <div class="container">

    <Category title="食物游戏电影" >

      <template v-slot:header="scope">

        <ul>

          <li v-for="item in scope.foods">{{ item }}</li>

        </ul>

      </template>

      <template v-slot:center="props">

        <ul>

          <li v-for="(item,index) in props.games" :key="index">{{ item }}</li>

        </ul>

      </template>

      <template #footer="scope">

        <ul slot="center">

          <li v-for="(item,index) in scope.films" :key="index">{{ item }}</li>

        </ul>

      </template>

    </Category>

  </div>

</template>

<script>

import Category from './components/Category02.vue'

export default {

  name: "App",

  components: {Category},

}

</script>

2. 动态插槽名

动态插槽是一种动态地选择插槽名称的方式。我们可以根据组件的状态或属性来决定使用哪个插槽,可以动态地决定将内容插入到哪个具名插槽中。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

// 子组件 Com06.vue

<template>

  <div>

    <button @click="toggleSlot">切换插槽</button>

    <slot :name="currentSlot"></slot>

  </div>

</template>

<script>

export default {

  data() {

    return {

      currentSlot: 'default666',

    };

  },

  methods: {

    toggleSlot() {

      this.currentSlot = this.currentSlot === 'default666' ? 'custom666' : 'default666';

    },

  },

};

</script>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// 父组件 App.vue

<template>

  <div>

    <Com06>

      <template v-slot:default666>

        <p>这是默认内容!</p>

      </template>

      <template v-slot:custom666>

        <p>这是自定义内容!</p>

      </template>

    </Com06>

  </div>

</template>

<script>

import Com06 from './components/Com06.vue'

export default {

  name: "App",

  components: {Com06},

}

</script>

我们在组件中添加了一个按钮,并在按钮的点击事件处理程序中切换currentSlot的值。当按钮被点击时,currentSlot的值会从default切换到custom,或者从custom切换到default,从而实现默认内容和自定义内容的切换。

在父组件中使用这个组件时,可以根据currentSlot的值来动态地指定插槽名称。

3. 插槽内容的访问

可以通过this.$slots访问到插槽的内容。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

<template>

  <div>

    <button @click="toggleSlot">切换插槽</button>

    <slot :name="currentSlot"></slot>

  </div>

</template>

<script>

export default {

  data() {

    return {

      currentSlot: 'default666',

    };

  },

  methods: {

    toggleSlot() {

      console.log("this.$slots: ", this.$slots);

      console.log("this.$slots.default666: ", this.$slots.default666);

      console.log("this.$slots.custom666: ", this.$slots.custom666);

    },

  },

};

</script>

四、插槽的本质

其实从打印结果可以看出,slot本质就是Proxy代理的对象,属性名就是各个插槽的名字,属性值就是对应的函数,调用函数得到的结果就是虚拟结点。

<slot name="slot1"></slot>就相当于在调用属性名为slot1的函数,<slot name="slot2" msg="你好世界!"></slot>就相当于在调用属性名为slot2的函数,该函数接收了msg的参数。

插槽的注意事项

插槽内容可以是任意类型,包括HTML、组件等。

默认插槽可以不用写name属性,具名插槽必须写name属性。

作用域插槽传递的数据可以根据需要命名。

五、最后的话

插槽技术是Vue.js中重要的组件化特性之一,为我们提供了灵活的组件化开发方式,通过合理使用插槽,我们可以轻松地定制和扩展组件的功能,使组件的可复用性和灵活性大大提高。

以上就是Vue中的插槽Slot技术详解的详细内容,更多关于Vue插槽的资料请关注脚本之家其它相关文章!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vueslot)是一种用于组件之间内容分发的机制。它允许父组件向子组件传递内容,使得子组件可以根据需要展示不同的内容。可以用于传递任意类型的内容,包括HTML、文本和其他组件。 Vue有三种使用方式:slotslot-scope和v-slot。 1. slotslot标签是最基本的使用方式。父组件可以在子组件的slot标签放置内容,这些内容将会替换子组件具名的位置。例如: ```html <!-- 父组件 --> <template> <child-component> <template v-slot:header> <h1>这是标题</h1> </template> </child-component> </template> <!-- 子组件 --> <template> <div> <slot name="header"></slot> <!-- 其他子组件内容 --> </div> </template> ``` 上述代码,父组件在子组件的放置了一个标题,子组件通过`<slot name="header"></slot>`来展示这个的内容。 2. slot-scope:slot-scope指令用于在接收父组件传递的数据。通过这种方式,子组件可以访问父组件的数据,并在进行处理。例如: ```html <!-- 父组件 --> <template> <child-component> <template v-slot:default="slotProps"> <h1>{{ slotProps.title }}</h1> <p>{{ slotProps.content }}</p> </template> </child-component> </template> <!-- 子组件 --> <template> <div> <slot :title="title" :content="content"></slot> <!-- 其他子组件内容 --> </div> </template> <script> export default { data() { return { title: '这是标题', content: '这是内容' }; } }; </script> ``` 在上述代码,父组件通过`v-slot:default="slotProps"`将数据传递给子组件的,并在使用`slotProps`来访问这些数据。 3. v-slot:v-slot指令是Vue2.6版本及以上引入的新特性,用于简化的语法。它可以直接在子组件上使用,而不需要使用template标签。例如: ```html <!-- 父组件 --> <template> <child-component> <template #header> <h1>这是标题</h1> </template> </child-component> </template> <!-- 子组件 --> <template> <div> <slot name="header"></slot> <!-- 其他子组件内容 --> </div> </template> ``` 在上述代码,父组件使用`#header`来定义,并在子组件使用`<slot name="header"></slot>`来展示的内容。 总结一下,slot用于定义的位置,slot-scope用于接收父组件传递的数据,并在进行处理,v-slot是对语法的简化。这些的使用方式可以根据具体需求选择适合的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值