目录
我是helloworld中的插槽啊
name属性为left
name属性为right
{{slotProps.users.name}}
{{users.name}}
{{person.name}}
首页 web前端 前端问答 vue插槽解决什么问题

vue插槽解决什么问题

Jan 13, 2023 pm 06:26 PM
vue 插槽

vue插槽解决的问题:引入的子组件标签中间不允许写内容的。插槽(Slot)是vue为组件的封装者提供的能力;允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽;可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

vue插槽解决什么问题

本教程操作环境:windows7系统、vue3版,DELL G3电脑。

什么是插槽?

我们知道,在vue中,引入的子组件标签中间是不允许写内容的。为了解决这个问题,官方引入了插槽(slot)的概念。

插槽,其实就相当于占位符。它在组件中给你的HTML模板占了一个位置,让你来传入一些东西。插槽又分为匿名插槽具名插槽以及作用域插槽

你可能不太明白,为什么我要给子组件中传入HTML,而不直接写在子组件中呢?答案是这样的。你可以想象一个场景,你有五个页面,这五个页面中只有一个区域的内容不一样,你会怎么去写这五个页面呢?复制粘贴是一种办法,但在vue中,插槽(slot)是更好的做法。

vue插槽解决什么问题

匿名插槽


匿名插槽,我们又可以叫它单个插槽或者默认插槽。与具名插槽相对,它不需要设置name属性。(它隐藏的name属性为default。)

例子:

文件目录如下,Home组件是HelloWorld的父组件。

vue插槽解决什么问题

  • 在HelloWorld中写一个匿名插槽
<template>
  <div>
     Helloworld组件

     <div>
       <slot></slot>
     </div>

  </div>
</template>

<script>
export default {

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.hello{
  width:100%;
  height:300px;
  background:#ccc;
  margin-top:50px;
  .slotTxt{
    width:500px;
    height:200px;
    margin:30px auto;
    background:red;
  }
}
</style>
登录后复制
  • 在Home组件中引入子组件,并在子组件标签中写入内容
<template>
  <div>
    我是Home父组件
    <helloworld>
      <!-- 没有插槽,这里的内容不显示 -->
      <h1 id="我是helloworld中的插槽啊">我是helloworld中的插槽啊</h1>  
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
登录后复制

效果

vue插槽解决什么问题

不难看出,HelloWorld标签中的内容(红色部分)已经显示出来了。

具名插槽


上面已经说过,插槽有一个name属性。与匿名插槽相对,加了name属性的匿名插槽就是具名插槽。

  • HelloWorld组件中写入name属性分别为left和right的插槽
<template>
  <div>
     Helloworld组件

     <div>
       <slot></slot>
     </div>

     <div>
       <slot></slot>
     </div>

  </div>
</template>

<script>
export default {

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.hello{
  width:700px;
  height:300px;
  background:#ccc;
  margin: 0 auto;
  margin-top:50px;
  .slotLeft{
    width:300px;
    height:200px;
    float:left;
    background:red;
  }
  .slotRight{
    width:300px;
    height:200px;
    float:right;
    background:pink;
  }
}
</style>
登录后复制
  • Home组件通过在template上写v-slot:name来使用具名插槽
<template>
  <div>
    我是Home父组件
    <helloworld>
      <template>
         <h1 id="name属性为left">name属性为left</h1> 
      </template>
      <template>
         <h1 id="name属性为right">name属性为right</h1> 
      </template>
     
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
<style>
.home{
  width:900px;
  margin:0 auto;
  background:yellow;
  padding-bottom:100px;
}
</style>
登录后复制

注意 v-slot 只能添加在template标签上 (只有一种例外情况)。

  • 效果

vue插槽解决什么问题

  • 例外情况(被废弃的slot=‘name’)
    带slot属性的具名插槽自 2.6.0 起被废弃,vue3.x被完全废弃。只有vue3之前的cli可以使用。
<template>
  <div>
    我是Home父组件
    <helloworld>
      <h1 id="name属性为left">name属性为left</h1>  
      <h1 id="name属性为right">name属性为right</h1>  
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
<style>
.home{
  width:900px;
  margin:0 auto;
  background:yellow;
  padding-bottom:100px;
}
</style>
登录后复制

效果同上。

  • 具名插槽的小知识点
    跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header。

作用域插槽


作用域插槽其实就是可以传递数据的插槽。子组件中的一些数据想在父组件中使用,必须通过规定的方法来传递。在官方文档中提出了一条规则,**父级模板里的所有内容都是在父级作用域中编译的。子模板里的所有内容都是在子作用域中编译的。**如果你在父组件直接使用子组件中的值,是会报错的。

匿名插槽的作用域插槽

为了让 子组件中的数据 在父级的插槽内容中可用,我们可以将 数据 作为 元素的一个特性绑定上去:

语法:v-bind:users="user"
登录后复制
  • 子组件HelloWorld代码
<template>
  <div>
     Helloworld组件  
     <div>
       <slot></slot>
     </div> 
     
  </div>
</template>

<script>
export default {
  data(){
    return{
      user:{
        name:&#39;oralinge&#39;,
        age:18
      }
    }  
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.hello{
  width:700px;
  height:300px;
  background:#ccc;
  margin: 0 auto;
  margin-top:50px;
  .slotLeft{
    width:300px;
    height:200px;
    // float:left;
    background:red;
    margin:20px auto
  }
  .slotRight{
    width:300px;
    height:200px;
    float:right;
    background:pink;
  }
}
</style>
登录后复制

绑定在 元素上的特性(v-bind:users=“user”)被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字。

语法:v-slot:default="随意取的名字"  // default可省略,简写为v-slot="随意取的名字"
登录后复制
  • 父组件Home代码
<template>
  <div>
    我是Home父组件
    <helloworld>
      <template>
         <h1 id="slotProps-users-name">{{slotProps.users.name}}</h1> 
      </template>
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
<style>
.home{
  width:900px;
  margin:0 auto;
  background:yellow;
  padding-bottom:100px;
}
</style>
登录后复制
登录后复制

注意:
     父组件中的slotProps可以是随意取的。
     子组件中users是随意取的,与之对应的是父组件中的users。
     子组件中的user为数据。

效果

vue插槽解决什么问题

具名插槽的作用域插槽

与匿名插槽同理,只需要把default替换成插槽的name值即可。

  • 子组件HelloWorld代码
<template>
  <div>
     Helloworld组件  
     <div>
       <slot></slot>
     </div> 
     
  </div>
</template>

<script>
export default {
  data(){
    return{
      user:{
        name:&#39;hello world&#39;,
        age:18
      }
    }  
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.hello{
  width:700px;
  height:300px;
  background:#ccc;
  margin: 0 auto;
  margin-top:50px;
  .slotLeft{
    width:300px;
    height:200px;
    // float:left;
    background:red;
    margin:20px auto
  }
  .slotRight{
    width:300px;
    height:200px;
    float:right;
    background:pink;
  }
}
</style>
登录后复制
登录后复制
  • 父组件Home代码
<template>
  <div>
    我是Home父组件
    <helloworld>
      <template>
         <h1 id="slotProps-users-name">{{slotProps.users.name}}</h1> 
      </template>
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
<style>
.home{
  width:900px;
  margin:0 auto;
  background:yellow;
  padding-bottom:100px;
}
</style>
登录后复制
登录后复制

效果

vue插槽解决什么问题

注意:
     默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确。

vue插槽解决什么问题

另,slot-scope写法在2.6之后已废弃,作用与上面相同,在此不做解释。

上面的写法是不是觉得有些麻烦?别着急,我们来看一看解构插槽 Prop

解构插槽 Prop

作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里:

function (slotProps) {
  // 插槽内容
}
登录后复制

这意味着 v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。所以在支持的环境下 (单文件组件或现代浏览器),你也可以使用 ES2015 解构来传入具体的插槽 prop。

语法:v-slot="{ users }"
登录后复制
  • HelloWold组件
<template>
  <div>
     Helloworld组件  
     <div>
       <slot></slot>
     </div> 
     
  </div>
</template>

<script>
export default {
  data(){
    return{
      user:{
        name:&#39;hello world&#39;,
        age:18
      }
    }  
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.hello{
  width:700px;
  height:300px;
  background:#ccc;
  margin: 0 auto;
  margin-top:50px;
  .slotLeft{
    width:300px;
    height:200px;
    // float:left;
    background:red;
    margin:20px auto
  }
  .slotRight{
    width:300px;
    height:200px;
    float:right;
    background:pink;
  }
}
</style>
登录后复制
登录后复制
  • Home组件
<template>
  <div>
    我是Home父组件
    <helloworld>
      <template>
         <h1 id="users-name">{{users.name}}</h1> 
      </template>
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
<style>
.home{
  width:900px;
  margin:0 auto;
  background:yellow;
  padding-bottom:100px;
}
</style>
登录后复制
登录后复制
  • 效果

vue插槽解决什么问题

  • 重命名----更改users这个名字
<template>
  <div>
    我是Home父组件
    <helloworld>
      <template>
         <h1 id="person-name">{{person.name}}</h1> 
      </template>
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
<style>
.home{
  width:900px;
  margin:0 auto;
  background:yellow;
  padding-bottom:100px;
}
</style>
登录后复制

效果如上图。

  • 定义后备内容,用于插槽 prop 是 undefined 的情形
    此处按照官方文档的写法会出现语法报错,后期应该会修复(有知道的麻烦通知一声)。
<template>
  <div>
    我是Home父组件
    <helloworld>
      <template>
         <h1 id="users-name">{{users.name}}</h1> 
      </template>
    </helloworld>
  </div>
</template>

<script>
import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
export default {
  name: &#39;home&#39;,
  components: {
    HelloWorld
  }
}
</script>
<style>
.home{
  width:900px;
  margin:0 auto;
  background:yellow;
  padding-bottom:100px;
}
</style>
登录后复制
登录后复制

使用场景


  • 复用公共组件
    代码示例如下:
<template>
  <div>
    <div>
      <span>{{title}}</span>
      <div>
        <slot></slot>
      </div>
    </div>
    <div>
      <slot></slot>
    </div>
  </div>
</template>
<script>
export default {
  data () {
    return {
    }
  },
  props: {
    title: {
      type: String,
      required: true
    }
  }
}
</script>
<style>
.title-box {
  padding: 16px 0;
  border-bottom: 1px solid #eff1f5;
  .title {
    font-family: MicrosoftYaHei;
    font-size: 24px;
    color: #283039;
    letter-spacing: 0;
    line-height: 24px;
    &::before {
      width: 4px;
      margin-right: 20px;
      content: "";
      background-color: #5da1ff;
      display: inline-block;
      height: 20px;
      vertical-align: middle;
    }
  }
  .right {
    float: right;
    margin-right: 20px;
  }
}
</style>
登录后复制

使用的ui框架为ivew。

相关推荐:vue.js视频教程

以上是vue插槽解决什么问题的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

vue.js怎么引用js文件 vue.js怎么引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三种:直接使用 &lt;script&gt; 标签指定路径;利用 mounted() 生命周期钩子动态导入;通过 Vuex 状态管理库进行导入。

vue怎么给按钮添加函数 vue怎么给按钮添加函数 Apr 08, 2025 am 08:51 AM

可以通过以下步骤为 Vue 按钮添加函数:将 HTML 模板中的按钮绑定到一个方法。在 Vue 实例中定义该方法并编写函数逻辑。

vue中的watch怎么用 vue中的watch怎么用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 选项允许开发者监听特定数据的变化。当数据发生变化时,watch 会触发一个回调函数,用于执行更新视图或其他任务。其配置选项包括 immediate,用于指定是否立即执行回调,以及 deep,用于指定是否递归监听对象或数组的更改。

vue中怎么用bootstrap vue中怎么用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分为五个步骤:安装 Bootstrap。在 main.js 中导入 Bootstrap。直接在模板中使用 Bootstrap 组件。可选:自定义样式。可选:使用插件。

vue返回上一页的方法 vue返回上一页的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一页有四种方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 组件window.history.back(),方法选择取决于场景。

Vue 实现跑马灯/文字滚动效果 Vue 实现跑马灯/文字滚动效果 Apr 07, 2025 pm 10:51 PM

在 Vue 中实现跑马灯/文字滚动效果,可以使用 CSS 动画或第三方库。本文介绍了使用 CSS 动画的方法:创建滚动文本,用 &lt;div&gt; 包裹文本。定义 CSS 动画,设置 overflow: hidden、width 和 animation。定义关键帧,设置动画开始和结束时的 transform: translateX()。调整动画属性,如持续时间、滚动速度和方向。

怎样查询vue的版本 怎样查询vue的版本 Apr 07, 2025 pm 11:24 PM

可以通过以下方法查询 Vue 版本:使用 Vue Devtools 在浏览器的控制台中查看“Vue”选项卡。使用 npm 运行“npm list -g vue”命令。在 package.json 文件的“dependencies”对象中查找 Vue 项。对于 Vue CLI 项目,运行“vue --version”命令。检查 HTML 文件中引用 Vue 文件的 &lt;script&gt; 标签中的版本信息。

vue遍历怎么用 vue遍历怎么用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍历数组和对象有三种常见方法:v-for 指令用于遍历每个元素并渲染模板;v-bind 指令可与 v-for 一起使用,为每个元素动态设置属性值;.map 方法可将数组元素转换为新数组。

See all articles