【vue】vue中的插槽以及使用方法

简介: 这里详细讲解下vue中的插槽

插槽

6.1 普通插槽

1、在父组件中直接调用子组件的标签,是可以渲染出子组件的内容;如果在子组件标签中添加了内容,父组件就渲染不出来了;

ParentComponent.vue:

<template>
  <div>
    <h1>Parent Component</h1>
    <child-component>
      <p>This is custom content inside the child component.</p>
    </child-component>
  </div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  name: 'ParentComponent',
  components: {
    ChildComponent
  }
};
</script>

image.gif

无名插槽(默认插槽)

ChildComponent.vue:

<!--    第一种方式-->
<template>
  <div>
    <h2>Child Component</h2>
    <slot></slot>
    <p>This is content from the child component.</p>
  </div>
</template>
<script>
export default {
  name: 'ChildComponent'
};
</script>

image.gif

2、如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容;

<!--    第二种方式-->
<template>
  <div>
    <h2>Child Component</h2>
    <slot><p>我们一起学猫叫</p></slot>
    <p>This is content from the child component.</p>
  </div>
</template>
<script>
export default {
  name: 'ChildComponent'
};
</script>

image.gif

在上述示例中,ChildComponent 组件使用了一个无名插槽(默认插槽)。在 ParentComponent 中,通过将内容包裹在 <child-component> 标签中,该内容就会被插入到 ChildComponent 的插槽中。

index.js

image.gif编辑

以父组件为loginnew,子组件为hello-world为例;

<!--父组件loginnew.vue->>
<hello-world></hello-world>
<hello-world>这是个hello-world插槽位</hello-world>
<!--如果想要渲染出父组件中调用子组件标签中的内容,就要在子组件中添加插槽-->
<!--子组件hello-world.vue文件-->
<!--如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容-->
<slot><p>hello-world:我们一起学猫叫</p></slot>

image.gif

6.2 具名/命名插槽

是 Vue.js 组件中的一种高级插槽技术,允许您在组件中定义多个具有名称的插槽,以便更精细地控制不同部分的内容插入位置。通过使用具名插槽,您可以在父组件中传递不同的内容到不同的插槽位置,从而实现更灵活和定制化的布局和组件复用。

以下是一个使用具名插槽的示例:

ChildComponent.vue:

<template>
  <div>
    <h2>Child Component</h2>
    <slot name="header"></slot>
    <slot></slot>
    <slot name="footer"></slot>
  </div>
</template>
<script>
export default {
  name: 'ChildComponent'
};
</script>

image.gif

ParentComponent.vue:

<template>
  <div>
    <h1>Parent Component</h1>
    <child-component>
      <template v-slot:header>
        <p>This is the header content.</p>
      </template>
      <p>This is the main content.</p>
      <template v-slot:footer>
        <p>This is the footer content.</p>
      </template>
    </child-component>
  </div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  name: 'ParentComponent',
  components: {
    ChildComponent
  }
};
</script>

image.gif

在上述示例中,ChildComponent 组件定义了三个插槽,分别是默认插槽以及具名插槽 headerfooter。在 ParentComponent 中,使用 <template> 元素配合 v-slot 指令来填充具名插槽的内容。

注意,Vue 2.6.0 及以上版本引入了新的缩写语法,将 v-slot:header 缩写为 #header,这样可以更简洁地使用具名插槽。

示例中的 ParentComponent 会渲染成如下内容:

<div>
  <h1>Parent Component</h1>
  <div>
    <h2>Child Component</h2>
    <p>This is the header content.</p>
    <p>This is the main content.</p>
    <p>This is the footer content.</p>
  </div>
</div>

image.gif

通过使用具名插槽,您可以在不同的插槽位置插入不同的内容,从而实现更灵活和可配置的组件。具名插槽使得您的组件能够更好地适应各种不同的使用场景。

父组件loginNew.vue:

<template>
  <div>
    <el-form :model="ruleForm" status-icon ref="ruleForm" label-width="70px" class="demo-ruleForm"
             :label-position="labelPosition">
      <el-form-item label="用户名" prop="username">
        <el-input type="username" v-model="ruleForm.username" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
    <!--  如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容-->
    <!--  <hello-world>这是个hello-world插槽位</hello-world>-->
    <!--  如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容-->
    <!--  <hello-world></hello-world>-->
    <hello-world>
      <!--    方法二  命名插槽-->
      <!--    在vue2.6之前版本-->
      <p slot="part1">一起喵喵喵</p>
      <!--    在vue2.6之后版本-->
      <template v-slot:part2>
        <p>在你面前撒个娇</p>
      </template>
      <!--       v-slot:可以简写成"#" -->
      <template #part3>
        <p>还是喵喵喵喵</p>
      </template>
      <!--        插槽作用域:父组件调取子组件的插槽内部要获取子组件的属性-->
      <!--        2.6 之前-->
      <p slot="part4" slot-scope="scope">
        {{ scope.user }}我得心脏砰砰跳
      </p>
      <template slot="part5" slot-scope="scope">
        <p>{{ scope.user }}我得心脏砰砰跳aaaaaa</p>
      </template>
      <!--        2.6 之后-->
      <template v-slot:part6="scope">
        <p>{{scope.user}}都是你的味道</p>
      </template>
      <template v-slot:part7="{user}">
        <p>{{user}}都是你的味道</p>
      </template>
    </hello-world>
  </div>
</template>
<script>
export default {
  name: "loginNew",
  data() {
    return {
      username: "daxiao",
      password: "123456",
      labelPosition: "right",
      ruleForm: {
        username: "111",
        password: "222",
      }
    }
  },
}
</script>
<style scoped>
.el-form {
  width: 350px;
  margin: 50px auto;
}
</style>

image.gif

子组件HelloWorld.vue:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h>{{ msg1 }}</h>
    <p>这是一个hello-world页面</p>
    <div>
      <el-image
          style="width: 300px; height: 200px"
          :src="url"
          fit="cover"></el-image>
    </div>
    <!--    第一种方式-->
    <!--    <slot></slot>-->
    <!--    第二种方式-->
    <slot><p>我们一起学猫叫</p></slot>
    <!--    第三种方式 命名插槽-->
    <slot name="part1"></slot>
    <slot name="part2"></slot>
    <slot name="part3"></slot>
    <!--    插槽作用域-->
    <slot name="part4" :user="username"></slot>
    <slot name="part5" user="六啊"></slot>
    <slot name="part6" user="七啊"></slot>
    <slot name="part7" user="八啊"></slot>
    <!--    <slot ></slot>-->
  </div>
</template>
<script>
// import axios from 'axios';
import {dogs} from '../api/api'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      url: '',
      username: "木子"
    }
  },
  mounted() {
    //方法一:不推荐
    // axios.get('https://dog.ceo/api/breeds/image/random')
    //     //如果请求成功,就会执行.then回调函数
    //     .then(function (response) {
    //       console.log('data:',response.data)
    //       console.log('response:',response)
    //       //此时的this指的是当前函数的应用
    //       this.url=response.data.message
    //     })
    //     //如果请求失败,就会执行.catch回调函数
    //     .catch(function (err) {
    //       console.log(err)
    //     });
    // axios.get('https://dog.ceo/api/breeds/image/random')
    //     //如果请求成功,就会执行.then回调函数
    //     //方法二:使用箭头函数
    //     .then(response => {
    //       console.log('data:', response.data)
    //       console.log('response:', response)
    //       //此时的this指的是当前函数的应用
    //       this.url = response.data.message
    //     })
    //     //如果请求失败,就会执行.catch回调函数
    //     .catch(function (err) {
    //       console.log(err)
    //     });
    dogs()
        //如果请求成功,就会执行.then回调函数
        //方法二:使用箭头函数
        .then(response => {
          console.log('data:', response.data)
          console.log('response:', response)
          //此时的this指的是当前函数的应用
          this.url = response.data.message
        })
        //如果请求失败,就会执行.catch回调函数
        .catch(function (err) {
          console.log(err)
        });
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

image.gif

6.3 作用域插槽

是 Vue.js 组件中一种高级插槽技术,它允许父组件向子组件传递数据,并在子组件中根据这些数据自定义渲染逻辑。作用域插槽允许子组件对传递的数据进行更灵活的处理和展示,从而实现更高级的定制。

作用域插槽适用于以下情况:

    • 当父组件需要向子组件传递数据,以在子组件内部进行渲染和处理。
    • 当子组件需要在不同的上下文中使用传递的数据,例如在列表渲染或嵌套组件中。

    以下是一个使用作用域插槽的示例:

    List.vue:

    <template>
      <div>
        <ul>
          <li v-for="(item, index) in items" :key="item.id">
            <slot :item="item" :index="index"></slot>
          </li>
        </ul>
      </div>
    </template>
    <script>
    export default {
      name: 'List',
      props: {
        items: Array
      }
    };
    </script>

    image.gif

    ParentComponent.vue:

    <template>
      <div>
        <h1>Parent Component</h1>
        <list :items="dataItems">
          <template v-slot="slotProps">
            <p>Item {{ slotProps.index }}: {{ slotProps.item.name }}</p>
          </template>
        </list>
      </div>
    </template>
    <script>
    import List from './List.vue';
    export default {
      name: 'ParentComponent',
      components: {
        List
      },
      data() {
        return {
          dataItems: [
            { id: 1, name: 'Item 1' },
            { id: 2, name: 'Item 2' },
            { id: 3, name: 'Item 3' }
          ]
        };
      }
    };
    </script>

    image.gif

    在上述示例中,List 组件使用作用域插槽将每个列表项的数据和索引传递给插槽内容。在 ParentComponent 中,通过 <template> 元素使用 v-slot 缩写来定义作用域插槽,并在插槽内部使用传递的数据进行渲染。

    作用域插槽的特点是,它将子组件内部的渲染逻辑交由父组件控制,子组件只需要关心数据的展示。这样可以实现更大程度的组件复用和定制。

    作用域插槽是 Vue.js 中非常强大和有用的特性,能够使您的组件更加灵活和高效

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