Vue 插槽的使用

news/2024/7/9 23:48:26 标签: vue

文章目录

  • 默认插槽
  • 具名插槽
  • 作用域插槽
  • 插槽总结
  • $slot

默认插槽

首先做一个页面:
在这里插入图片描述

新增 Category.vue

<template>
<div class="category">
  <h3>{{title}}分类</h3>
  <ul>
    <li v-for="(item,index) in listData" :key="index">{{item}}</li>
  </ul>
</div>
</template>

<script>
export default {
  name: "Category",
  props:["title","listData"]
}
</script>

<style scoped>
.category{
  background-color: skyblue;
  width: 200px;
  height: 300px;
}
h3{
  text-align: center;
  background-color: orange;
}
</style>

App.vue 中使用

<template>
  <div class="container">
    <Category title="美食" :listData="foods"/>
    <Category title="游戏" :listData="games"/>
    <Category title="电影" :listData="films"/>
  </div>
</template>

<script>
import Category from "@/components/Category";

export default {
  name: 'App',
  components: {Category},
  data(){
    return{
      foods:["火锅","烧烤","小龙虾","牛排"],
      games:["劲舞团","QQ飞车","超级玛丽","无人深空"],
      films:["《教父》","《狩猎》","《禁闭岛》","《聚焦》"]
    }
  }

}
</script>

<style>
.container {
  display: flex;
  justify-content: space-around;
}
</style>

刚才每个分类要展示的信息,样式都是一样的,所以通过传值就可以实现。现在修改需求,每个分类都要展示不同的内容:
在这里插入图片描述
这里就用到了插槽。插槽是给组件预留的空间,插槽如何使用由父组件决定。修改 Category.vue

<template>
<div class="category">
  <h3>{{title}}分类</h3>
  <slot></slot>
</div>
</template>

<script>
export default {
  name: "Category",
  props:["title"]
}
</script>

<style scoped>
.category{
  background-color: skyblue;
  width: 200px;
  height: 300px;
}
h3{
  text-align: center;
  background-color: orange;
}
</style>

修改 App.vue

<template>
  <div class="container">
    <Category title="美食" :listData="foods">
      <img src="https://img2.baidu.com/it/u=2073611229,1921777437&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675"/>
    </Category>
    <Category title="游戏" :listData="games">
      <ul>
        <li v-for="(g,index) in games" :key="index">{{g}}</li>
      </ul>
    </Category>
    <Category title="电影">
      <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"/>
    </Category>
  </div>
</template>

<script>
import Category from "@/components/Category";

export default {
  name: 'App',
  components: {Category},
  data(){
    return{
      foods:["火锅","烧烤","小龙虾","牛排"],
      games:["劲舞团","QQ飞车","超级玛丽","无人深空"],
      films:["《教父》","《狩猎》","《禁闭岛》","《聚焦》"]
    }
  }

}
</script>

<style>
.container {
  display: flex;
  justify-content: space-around;
}
img,video{
  width: 100%;
}
</style>

具名插槽

具名插槽是当子组件需要显示不同的效果时使用具名插槽,通过 name 属性给插槽命名。我们修改 Category.vue

<template>
<div class="category">
  <h3>{{title}}分类</h3>
  <slot name="center">这是一些默认值,没有内容时展示</slot>
  <slot name="footer">这是一些默认值,没有内容时展示</slot>
</div>
</template>

<script>
export default {
  name: "Category",
  props:["title"]
}
</script>

<style scoped>
.category{
  background-color: skyblue;
  width: 200px;
  height: 300px;
}
h3{
  text-align: center;
  background-color: orange;
}
</style>

修改 App.vue

<template>
  <div class="container">
    <Category title="美食" :listData="foods">
      <img slot="center" src="https://img2.baidu.com/it/u=2073611229,1921777437&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675"/>
      <a slot="footer" href="https://www.baidu.com">更多美食</a>
    </Category>
    <Category title="游戏" :listData="games">
      <ul slot="center">
        <li v-for="(g,index) in games" :key="index">{{g}}</li>
      </ul>
      <div class="foot" slot="footer">
        <a href="https://www.baidu.com">单机游戏</a>
        <a href="https://www.baidu.com">网络游戏</a>
      </div>
    </Category>
    <Category title="电影">
      <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"/>
      <!--v-slot 只有template能用-->
      <template v-slot:footer>
        <div class="foot" slot="footer">
          <a href="https://www.baidu.com">经典</a>
          <a href="https://www.baidu.com">热门</a>
          <a href="https://www.baidu.com">推荐</a>
        </div>
      </template>
    </Category>
  </div>
</template>

<script>
import Category from "@/components/Category";

export default {
  name: 'App',
  components: {Category},
  data(){
    return{
      foods:["火锅","烧烤","小龙虾","牛排"],
      games:["劲舞团","QQ飞车","超级玛丽","无人深空"],
      films:["《教父》","《狩猎》","《禁闭岛》","《聚焦》"]
    }
  }

}
</script>

<style>
.container,.foot {
  display: flex;
  justify-content: space-around;
}
img,video{
  width: 100%;
}
</style>

作用域插槽

在这里插入图片描述
如果数据在 Category 中,但需要展示不同的形式,我们可以通过插槽传值,类似于我们从父组件向子组件传值

<template>
  <div class="category">
    <h3>{{ title }}分类</h3>
    <slot :games="games" :msg="hello"></slot>
  </div>
</template>

<script>
export default {
  name: "Category",
  props: ["title"],
  data() {
    return {
      games: ["劲舞团", "QQ飞车", "超级玛丽", "无人深空"]
    }
  }
}
</script>

<style scoped>
.category {
  background-color: skyblue;
  width: 200px;
  height: 300px;
}

h3 {
  text-align: center;
  background-color: orange;
}
</style>

App 中在子组件中使用 <template> 包裹要展示的内容

<template>
  <div class="container">
    <Category title="游戏">
      <template v-slot="receiveValue">
        <ul>
          <li v-for="(g,index) in receiveValue.games" :key="index">{{ g }}</li>
        </ul>
        <a>{{ receiveValue.msg }}</a>
      </template>
    </Category>

    <Category title="游戏">
      <template v-slot="{games,msg}">
        <ol>
          <li v-for="(g,index) in games" :key="index">{{ g }}</li>
        </ol>
        <a>{{ msg }}</a>
      </template>
    </Category>

    <Category title="游戏">
      <template v-slot="{games,msg}">
        <h4 v-for="(g,index) in games" :key="index">{{ g }}</h4>
        <a>{{ msg }}</a>
      </template>
    </Category>

  </div>
</template>

<script>
import Category from "@/components/Category";

export default {
  name: 'App',
  components: {Category},
}
</script>

<style>
.container, .foot {
  display: flex;
  justify-content: space-around;
}

img, video {
  width: 100%;
}
</style>

插槽总结

1、作用:让父组件可以向子组件指定位置插入 html 结构,也是一种组件问通信的方式,适用于父组件==>子组件
2、分类:默认插槽、具名插槽、作用域插槽
3、使用方式:

默认插槽

父组件中
<Category>
	<div>html结构</div>
<Category>

子组件中
<template>
	<div>
	<!--定义插槽-->
	<slot>插槽默认内容...</slot>
	</div>
</templdte>

具名插槽

父组件中
<Category>
	<template slot="center">
		<div>html结构1</div>
	</template>
	<tenplate v-slot:footer>
		<div>html结构2</div>
	</template>
</Category>
子组件中
<template>
	<div>
	<1--定义插槽-->
	<slot name="center">插槽默认内容...</slot>
	<slot name="footer”>插槽默认内容...</slot>
	</div>
</template>

作用域插槽
1、理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定,(games 数据在 Category 组件中,但使用数据所遍历出来的结构由 App 组件决定)
2.具体编码:

父组件中
<category>
	<template v-slot="scopeData"
	<!--生成的是ul列表-->
	<ul>
		<li v-for="g in scopeDsta.games" : key="g">{g}</li>
	</ul>
	</template>
</Category>

<Category>
	<template v-slot={scopeData}>
	<!--生成的是h4标题-->
	<h4 v-for="g in scopeData" :key="g">{{g}}</h4>
	</template>
</Category>

子组件中
<template>
	<div>
		<slot :games="games"></slot>
	</div>
</template>

<script>
export default{
	name: "Category ',
	props: ["title"],
	//数据在子组件自身
	data() {
		return{
			games:['红色警戒,穿越火线',"劲舞团",超级玛丽"]
		}
	}
}</script>

注意scopeslot-scope过时了,可以使用v-slot

$slot

App 中有 Demo 组件,使用插槽

<template>
  <div>
    <Demo>
      <h2>你好</h2>
    </Demo>
  </div>
</template>

在子组件 Demo 中的 mounted 生命钩子中打印 this

mounted() {
    console.log(this);
}

可以看到 $slot中有刚才使用的 h2 标签
在这里插入图片描述

如果在App中使用具名插槽

<template>
  <div>
    <Demo>
      <template slot="slot1">
        <h2>你好</h2>
      </template>
    </Demo>
  </div>
</template>

那么在 Demo 中打印结果:
在这里插入图片描述


http://www.niftyadmin.cn/n/1816721.html

相关文章

XSL学习笔记

http://www.cnsdn.com.cn/blog/article.asp?id702摘要&#xff1a;xsl:templatexsl:value-ofxsl:for-eachxsl:sortxsl:ifxsl:choosexsl:whenxsl:otherwisexsl:apply-templatesxsl:importxsl:includexsl:apply-importsxsl:attributexsl:attribute-setxsl:paramxsl:call-templat…

angularJS 单页面 两个及以上个 ng-app 的处理方式

1 <div ng-app"myApp1" ng-controller"myCtrl1">2 3 名: <input type"text" ng-model"firstName"><br>4 姓: <input type"text" ng-model"lastName"><br>5 <br>…

FLEX实例:BT文件搜索.

uyang 太有才了&#xff0c;搞了个BT文件搜索的例子.引自原文&#xff1a;由于自己经常下BT文件&#xff0c;总是一个个上那些网站挨个搜索&#xff0c;总觉得有点麻烦&#xff0c;干脆自己做了个FLEX 程序&#xff0c;把这几个世界上比较有名的BT网站全加一块。前段时间做的Bt…

Vue Vuex学习(搭建vuex环境、vuex求和案例)

文章目录理解Vuex求和案例--纯vue版搭建vuex环境求和案例--vuex版一些疑惑和问题理解Vuex Vuex介绍 概念 在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件&#xff0c;对 vue 应用中多个组件的共享状态进行集中式的管理(读写)&#xff0c;也是一种组件间通信的方式&#x…

requireJS基本配置相关

requireJS: (1)实现js文件的异步加载&#xff0c;避免页面失去响应&#xff1b; (2)管理模块之间的依赖性&#xff0c;便于代码的编写和维护。 加载&#xff1a; <script src"js/require.js" ></script> 由于加载的模块较多&#xff0c;可能会造成页…

SOA系列二:采用SOA的常见失误

一、构建类似传统分布式架构的面向服务架构 或许组织在实现SOA时所面临的第一大障碍是&#xff0c;一构建当代SOA为借口来构建传统的分布式架构&#xff1b;二、非标准化的SOA 有时可能需要在较大的组织中同时规划不同的IT项目&#xff0c;因此定制标准极其重要。如…

jquery ajax 请求中多出现一次OPTIONS请求及其解决办法

http://www.tangshuang.net/2271.html 在上一篇《服务端php解决jquery ajax跨域请求restful api问题及实践》中&#xff0c;我简单介绍了如何通过服务端解决jquery ajax的跨域请求问题&#xff0c;但是&#xff0c;在这个过程中&#xff0c;我们会发现&#xff0c;在很多post,…

Vue Vuex学习(vuex配置项、多组件数据共享案例)

文章目录getters 配置项mapState、mapGettersmapActions、mapMutations多组件共享数据没有看过上一篇的同学可以查看&#xff1a; Vue Vuex学习(搭建vuex环境、vuex求和案例)getters 配置项 index.js 中增加 getters 配置项 //准备getters&#xff0c;用于将state中的数据进行…