Vue插槽理解

简介: Vue插槽理解

插槽

slot又名插槽,vue内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口

插槽slot是子组件的一个模板标签元素,而这一个元素是否显示,以及怎么显示是由父组件决定的

slot分为三类:默认插槽、具名插槽、作用域插槽

  • 默认插槽

父组件代码详情

<template>
  <div class="parent">
  <h1>这里是parent组件</h1>
  <Child>
    <h3>这是parent组件传递给child组件的值</h3>
  </Child>
  </div>
</template>
<script>
import Child from "../component/Child.vue"
</script>

子组件代码详情

<template>
  <div class="child">
  <h1>这里是child组件</h1>
  <Child>
    <h3>这是child组件</h3>
    <slot></slot>
  </Child>
  </div>
</template>

运行结果:

768e22f13977496783f01612c3b5aa74.png

又叫匿名插槽,当插槽slot没有指定name属性值的时候一个默认显示一个插槽,一个组件内只有一个匿名插槽

  • 具名插槽

带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽

父组件代码详情

<template>
  <div class="parent">
  <h1>这里是parent组件</h1>
  <Child>
    <div slot="header">给header内容</div>
    <div slot="main">给main内容</div>
    <div slot="footer">给footer内容</div>
  </Child>
  </div>
</template>

子组件代码详情

<template>
  <div class="child">
  <h1>这里是parent组件</h1>
  <Child>
    <div name="header">给header内容</div>
    <div name="main">给main内容</div>
    <div name="footer">给footer内容</div>
  </Child>
  </div>
</template>

运行结果:

8219ee2557e24a328fa5075229ed1214.png

  • 作用域插槽

在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件传递过来的数据如何渲染该插槽

父组件代码详情

<template>
  <button @click="show">显示隐藏</button>
  <div class="home" v-show="isShow">
    <Dialog title="商品选择">
      <!-- 匿名插槽的使用 -->
      <!-- 写法一 -->
      <!-- 12243 -->
      <!-- 写法二 -->
      <template #default>
        <!-- 666666666666666666 -->
        <FruitList>
          <template #default="{goods}">{{ goods }}</template>
        </FruitList>
      </template>
      <!-- 具名插槽使用 -->
      <!-- 写法一 -->
      <!-- <template v-slot:footer>
        <Rbutton>取消</Rbutton>
        <Rbutton>确认</Rbutton>
      </template> -->
      <!-- 写法二 -->
      <template #footer>
        <Rbutton style=" display: inline-block;border-radius: 5px;margin-right: 10px;">取消</Rbutton>
        <Rbutton style="background-color: #1890ff; display: inline-block; border-radius: 5px;">确认</Rbutton>
      </template>
    </Dialog>
  </div>
</template>
<script>
import Dialog from '@/components/Dialog.vue'
import Rbutton from '@/components/Rbutton.vue';
import FruitList from '@/components/FruitList.vue';
export default {
  data(){
    return{
      isShow:false
    }
  },
  name: 'DialogParent',
  components: {
    Dialog,
    Rbutton,
    FruitList
  },
  methods:{
    onAddCart(gid,gname){
      console.log(gid,gname);
    },
    show(){
      this.isShow=!this.isShow
    }
  }
}
</script>
<style lang="scss" scoped>
.home{
  // position: relative;
  background-color: yellow;
}
</style>

子组件代码详情

<template>
    <div class="fruit">
        <table class="ftable">
            <thead>
                <tr>
                    <td>ID</td>
                    <td>名字</td>
                    <td>价格</td>
                </tr>
            </thead>
            <tbody>
                <tr v-for="f in fruits" :key="f.id" @click="onAddCart([f.id,f.name])">
                    <td>{{ f.id }}</td>
                    <td>{{ f.name }}</td>
                    <td>{{ f.price }}</td>
                </tr>
                <slot :goods="f"></slot>
            </tbody>
        </table>
    </div>
</template>
<script>
export default {
    data(){
        return{
            fruits:[
                {
                    id:'01',
                    name:'苹果~~🍎',
                    price:'3.90'
                },
                {
                    id:'01',
                    name:'西瓜~~🍉',
                    price:'3.70'
                },
                {
                    id:'01',
                    name:'葡萄~~🍇',
                    price:'3.80'
                },                
                {
                    id:'01',
                    name:'橙子~~🍊',
                    price:'3.50'
                },                
                {
                    id:'01',
                    name:'香蕉~~🍌',
                    price:'3.30'
                },
            ]
        }
    },
    methods:{
        onAddCart(params){
            this.$emit('add-cart',...params)
        }
    }
}
</script>
<style lang="scss" scoped>
.fruit{
    // li{
    //     list-style: none;
    // }
    width: 100%;
    // height: 100%;
    // background-color: plum;
    table{
        width: 95%;
        // border-radius: 20px;
        margin: 0 auto;
        border: 1px bolid black;
        thead{
            width: 100%;
            // border-radius: 20px;
            // background-color: blue;
            text-align: center;
        }
        tbody{
            // border-radius: 20px;
            width: 100%;
            background-color: aliceblue;
            text-align: center;
        }
    }
}
</style>

**原理:**当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm.s l o t 中,默认插槽为 v m . slot中,默认插槽为vm.slot中,默认插槽为vm.slot.default,具名插槽为vm.s l o t . x x x , x x x 是插槽的名字,当组件执行渲染函数时候,遇到 s l o t 标签,使用 slot.xxx,xxx是插槽的名字,当组件执行渲染函数时候,遇到slot标签,使用slot.xxx,xxx是插槽的名字,当组件执行渲染函数时候,遇到slot标签,使用slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则就是作用域插槽


相关文章
|
3天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
3天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
3天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
3天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
2天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
4天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
2天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
4天前
|
存储 JavaScript
Vue 组件间如何通信
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
|
9天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
9天前
|
存储 JavaScript
Vue 状态管理工具vuex
Vue 状态管理工具vuex