美文网首页
slot和v-slot解决样式需要不断重复的问题

slot和v-slot解决样式需要不断重复的问题

作者: 郑馋师 | 来源:发表于2020-02-16 20:36 被阅读0次

    遇到问题

    今天我在网上做vue开源项目的时候发现,如果要做多页面,样式该咋办?难道每个都一个一个插入吗?这样重复就是罪过,万一需求改变每个都改该多麻烦!
    所以我看了vue官方文档,发现有一个slot功能
    eg

    <template>
      <div class="nav-wrapper">
        <div class="content">
          111
        </div>
        <Nav/>
      </div>
    </template>
    
    <script lang="ts">
    import Vue from "vue";
    
    export default Vue.extend({
      name:'money'
    });
    </script>
    
    <style lang="scss" scoped>
      .nav-wrapper {
        border: 1px black solid;
        display: flex;
        flex-direction: column;
        height: 100vh;
      }
    
      .content {
        overflow: auto;
        border: 1px solid blue;
        flex-grow: 1;
      }
    </style>
    

    这是一个页面的vue文件,如果每个页面样式相似都要写这么多真的浪费时间而且不符合美观
    所以我想到把重复的内容封装到一个component里面,我暂且命名为Layout

    //Layout.vue
    <template>
      <div class="nav-wrapper">
        <div class="content">
    
        </div>
        <Nav/>
      </div>
    </template>
    
    <script lang="ts">
    import Vue from "vue";
    
    export default Vue.extend({
      name:'Layout'
    });
    </script>
    
    <style lang="scss" scoped>
      .nav-wrapper {
        border: 1px black solid;
        display: flex;
        flex-direction: column;
        height: 100vh;
      }
    
      .content {
        overflow: auto;
        border: 1px solid blue;
        flex-grow: 1;
      }
    </style>
    

    而删除了这些重复内容,原本的vue就变得干净清爽多了

    <template>
      <p>
        111
      </p>
    </template>
    
    <script lang="ts">
    import Vue from "vue";
    
    export default Vue.extend({
      name:'money'
    });
    </script>
    

    接下来把Layout组件在全局引用后,我们遇到一个问题,如何把这个111的p标签引入到Layout组件中呢
    通过不断翻阅Vue文档,找到一个方法,也就是这次的主角slot

    slot

    slot他只有一个属性就是
    name - string,是用于命名插槽。

    它的用法就是
    <slot> 元素作为组件模板之中的内容分发插槽。<slot> 元素自身将被替换。

    //Layout.vue
    
    <template>
        <div class="nav-wrapper">
            <div class="content">
        <slot></slot>
            </div>
            <Nav/>
        </div>
    </template>
    

    这样就会把外面传进来的把slot标签代替
    但是这种方法是不够全面,而且Vue文档也说已经废弃但是没有移除,那咋样才能跟好呢?因为无法针对性的插入,比如遇到不同页面样式不同就没辙了
    所以我们可以采用V-slot标签

    v-slot

    • 预期:可放置在函数参数位置的 JavaScript 表达式 (在支持的环境下可使用解构)。可选,即只需要在为插槽传入 prop 的时候使用。

    • 参数:插槽名 (可选,默认值是 default)

    • 限用于

      • <template>
      • 组件 (对于一个单独的带 prop 的默认插槽)
    • 用法

      提供具名插槽或需要接收 prop 的插槽。

    • 示例

      <!-- 具名插槽 -->
      <base-layout>
        <template v-slot:header>
          Header content
        </template>
      
        Default slot content
      
        <template v-slot:footer>
          Footer content
        </template>
      </base-layout>
      
      <!-- 接收 prop 的具名插槽 -->
      <infinite-scroll>
        <template v-slot:item="slotProps">
          <div class="item">
            {{ slotProps.item.text }}
          </div>
        </template>
      </infinite-scroll>
      
      <!-- 接收 prop 的默认插槽,使用了解构 -->
      <mouse-position v-slot="{ x, y }">
        Mouse position: {{ x }}, {{ y }}
      </mouse-position>
      

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

    <base-layout>
      <template #header>
        <h1>Here might be a page title</h1>
      </template>
    
      <p>A paragraph for the main content.</p>
      <p>And another one.</p>
    
      <template #footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>
    

    然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:

    <!-- 这样会触发一个警告 -->
    <current-user #="{ user }">
      {{ user.firstName }}
    </current-user>
    

    如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:

    <current-user #default="{ user }">
      {{ user.firstName }}
    </current-user>
    

    相关文章

      网友评论

          本文标题:slot和v-slot解决样式需要不断重复的问题

          本文链接:https://www.haomeiwen.com/subject/qmcmfhtx.html