美文网首页
Vue组件封装之--选项卡封装

Vue组件封装之--选项卡封装

作者: 晴天守候 | 来源:发表于2020-04-27 17:52 被阅读0次

    好记性不如烂笔头,所以觉得有些常用的组件封装记录下,不但加深印象和理解,也方便为以后回头翻阅。并且在前进的路上留下脚印,以后看到也是满满的成就感的。O(∩∩)O哈哈~_

    这里把一个组件分成两个来封装,第一个是基础,第二个是在第一个的基础上来继续封装的,根据使用的场景选择

    主要以贴代码为主,代码很全,可以直接使用,代码比较简单,只是Vue卡槽的使用如果忘了的话就要先去了解下了

    一、基础的封装card组件

    1.card图片示例


    card.png

    card.vue代码如下,后续的引用文件也会贴出来

    card.vue --template

    <template>
      <div class="card bg-white p-3 mt-3">
        <div class="card-header pb-3">
          <div class="d-flex py-1 ai-center">
            <i class="iconfont fs-lg" :class="`icon-${icon}`"></i>
            <div class="flex-1 ml-2 fs-xl">{{title}}</div>
            <i class="iconfont icon-more"></i>
          </div>
          <img class="w-100 pt-3" :src="image" v-if="image" />
        </div>
        <div class="card-body pt-3">
          <slot></slot>
        </div>
      </div>
    </template>
    

    card.vue --js

    export default {
      props: {
        title: { type: String, required: true },
        icon: { type: String, required: true },
        image: { type: String }
      },
      data() {
        return {};
      },
      created() {}
    };
    

    card.vue --scss

    //引用的scss变量文件,然后这里可以直接用定义好的变量   注:用的是用scss写的样式
    @import "../assets/scss/_variables.scss";
    .card {
      .card-header {
        border-bottom: 1px solid $border-color;
      }
    }
    </style>
    

    使用card组件

    <m-card
          icon="heroku"
          title="英雄列表"
          image="http://ossweb-img.qq.com/upload/webplat/info/yxzj/20200108/20796372351730.jpg"
        ></m-card>
    

    二、listCard组件

    1.listCard示例图片


    WeChat69bf09823a3980e3300db02a6900f670.png

    listCard.vue --template:

    <template>
      <div>
        <m-card :icon="icon" :title="title">
          <div class="nav jc-between">
            <div class="nav-item" :class="{active:active === i}" v-for="(category,i) in categories" :key="i">
              <div class="nav-link" @click="$refs.list.swiper.slideTo(i)">{{category.name}}</div>
            </div>
          </div>
          <div class="pt-2">
            <swiper ref="list" :options="{autoHeight:true}"
            @slide-change="()=>active = $refs.list.swiper.realIndex">
              <swiper-slide v-for="(category,i) in categories" :key="i">
                <slot name="items" :category="category"></slot>
              </swiper-slide>
            </swiper>
          </div>
        </m-card>
      </div>
    </template>
    
    export default {
      props: {
        title: { type: String, required: true },
        icon: { type: String, required: true },
        categories: { type: Array, required: true },
        image: { type: String }
      },
      data(){
        return{
          active: 0
        }
      }
    };
    

    使用listCard组件

    <m-list-card icon="Menu" title="新闻资讯" :categories="newsCats">
          <template #items="{category}">
            <!--组件里的solt的name是items,所以这里的也是items -->
            <router-link
            tag="div"
            :to="`/article/${news._id}`"
            class="py-2 d-flex"
            v-for="(news,i) in category.newsList" :key="i">
              <span class="text-info">[{{news.categoryName}}]</span>
              <span class="px-2">|</span>
              <span class="flex-1 text-ellipsis text-dark-1 pr-2">{{news.title}}</span>
              <span class="text-grey-1 fs-sm">{{news.data | date}}</span>
            </router-link>
          </template>
        </m-list-card>
    

    这里还有个造假数据的快捷方法,很方便

    newsCats: [  //造假数据
            {
              name: "热门",
              newsList: new Array(5).fill(1).map(v => ({
                categoryName: "热门",
                title: "3月11日全服不停机更新公告3月11日全服不停机更新公告",
                data: "11/03"
              }))
            },
            {
              name: "新闻",
              newsList: new Array(5).fill(1).map(v => ({
                categoryName: "新闻",
                title: "3月11日全服不停机更新公告",
                data: "11/03"
              }))
            },
            {
              name: "公告",
              newsList: new Array(5).fill(1).map(v => ({
                categoryName: "公告",
                title: "3月11日全服不停机更新公告",
                data: "11/03"
              }))
            },
            {
              name: "活动",
              newsList: new Array(5).fill(1).map(v => ({
                categoryName: "活动",
                title: "3月11日全服不停机更新公告",
                data: "11/03"
              }))
            },
            {
              name: "赛事",
              newsList: new Array(5).fill(1).map(v => ({
                categoryName: "赛事",
                title: "3月11日全服不停机更新公告",
                data: "11/03"
              }))
            }
          ]
    

    在main.js中打入组件,就可以全局使用了

    import VueAwesomeSwiper from 'vue-awesome-swiper' //轮播图
    // require styles
    import 'swiper/dist/css/swiper.css'
    import '../src/assets/scss/style.scss'
    import '../src/assets/iconfont/iconfont.css'   
    Vue.use(VueAwesomeSwiper, /* { default global options } */)  
    //中全局引用组件,也可以在使用的地方单独引用
    import Card from "../src/components/Card.vue"
    Vue.component('m-card',Card);
    import ListCard from "../src/components/ListCard.vue"
    Vue.component('m-list-card',ListCard);
    

    以下就是全部scss代码了。

    还是比较喜欢scss来写样式,定义变量,可以轻松实现”变脸“效果。而且使用scss/less开发工具样式,还更加方便快捷。

    1、_variables.scss存放样式变量(注意前面是下划线哦)

    //colors
    $colors:(
        'primary':#db9e3f,
        'info':#4b67af,
        'danger':#791a15,
        'blue-1':#1f3695,
        'blue':#4394e4,
        'white':#fff,
        'light':#f9f9f9,
        'light-1':#d4d9de,
        'grey':#999,
        'grey-1':#666,
        'dark-1':#343440,
        'dark':#222,
        'black':#000,
    );
    $border-color:map-get($colors,'light-1');
    //font-size
    $base-font-size:1rem;
    $font-size:(
        xxs:0.6154, //8px
        xs:0.7692,  //10px
        sm:0.9231,  //12px
        md:1,       //13px
        lg:1.0769,  //14px
        xl:1.2308   //16px
    );
    $flex-jc:(
        start:flex-start,
        end:flex-end,
        center:center,
        between:space-between,
        around:space-around,
    );
    $flex-ai:(
        start:flex-start,
        end:flex-end,
        center:center,
        stretch:stretch,
    );
    //spacing
    $spacing-types:(
        m:margin,
        p:padding);
    $spacing-directions:(
        t:top,
        r:right,
        b:bottom,
        l:left);
    $spacing-base-size:1rem;
    $spacing-sizes:(
        0:0,
        1:0.25,
        2:0.5,
        3:1,
        4:1.5,
        5:3,
    );
    

    style.scss

    //这里需要注意的,导入_variables.scss的时候不带下划线,像这样导入就好了
    @import './variables';
    * {
        box-sizing: border-box;
        outline: none;
    }
    html {
        font-size: 13px;
    }
    body {
        margin: 0;
        font-family: Arial, Helvetica, sans-serif;
        line-height: 1.2em;
        background: #f1f1f1;
        -webkit-font-smoothing: antialiased;
    }
    a {
        color: #999;
    }
    p{
        line-height: 1.5rem;
    }
    //colors
    @each $colorKey,
    $color in $colors {
        .text-#{$colorKey} {
            color: $color
        }
        .bg-#{$colorKey} {
            background-color: $color
        }
    }
    //text overflow
    .text-ellipsis{
        display: inline-block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    //text-align
    @each $var in (left, center, right) {
        .text-#{$var} {
            text-align: $var !important;
        }
    }
    //font-size
    @each $sizeKey,
    $size in $font-size {
        .fs-#{$sizeKey} {
            font-size: $size * $base-font-size
        }
    }
    //width,height
    .w-100 {
        width: 100%;
    }
    .h-100 {
        height: 100%;
    }
    // flex (布局)
    .d-flex {
        display: flex;
    }
    .flex-column {
        flex-direction: column;
    }
    .flex-wrap {
        flex-wrap: wrap;
    }
    @each $key,
    $value in $flex-jc {
        .jc-#{$key} {
            justify-content: $value;
        }
    }
    @each $key,
    $value in $flex-ai {
        .ai-#{$key} {
            align-items: $value;
        }
    }
    .flex-1 {
        flex: 1
    }
    .flex-grow-1 {
        //简写是上面的
        flex-grow: 1,
    }
    //spacing
    @each $typeKey,
    $type in $spacing-types {
        //m-1形式
        @each $sizeKey,
        $size in $spacing-sizes {
            .#{$typeKey}-#{$sizeKey} {#{$type}: $size * $spacing-base-size;}}
        //mx-1 左右、my-1上下的形式
        @each $sizeKey,
        $size in $spacing-sizes {
            .#{$typeKey}x-#{$sizeKey} {#{$type}-left: $size * $spacing-base-size;#{$type}-right: $size * $spacing-base-size;}}
        @each $sizeKey,
        $size in $spacing-sizes {
            .#{$typeKey}y-#{$sizeKey} {#{$type}-top: $size * $spacing-base-size;#{$type}-bottom: $size * $spacing-base-size;}}
        //mt-1的形式
        @each $directionKey,
        $direction in $spacing-directions {
            @each $sizeKey,
            $size in $spacing-sizes {
                .#{$typeKey}#{$directionKey}-#{$sizeKey} {#{$type}-#{$direction}: $size * $spacing-base-size;}}}
    }
    //button
    .btn {
        border: none;
        border-radius: 0.1538rem;
        font-size: map-get($font-size, 'sm') * $base-font-size;
        padding: 0.2rem 0.6rem;
    }
    //nav
    .nav {
        display: flex;
        .nav-item {
            border-bottom: 3px solid transparent;
            padding-bottom: 0.2rem;
            &.active {
                //在同一层,所以要用 &
                color:map-get($colors,'primary');
                border-bottom-color:map-get($colors,'primary');
            }
        }
        &.nav-inverse{
            .nav-item{
                border-bottom: 3px solid transparent;
                color:map-get($colors,'white');
                &.active{
                    border-bottom-color:map-get($colors,'white');
                }
            }
        }
    }
    // sprite 精灵图
    .sprite {
        background: url(../images/index.png) no-repeat 0 0;
        background-size: 28.8462rem;
        display: inline-block;
        &.sprite-news {
            width: 1.7692rem;
            height: 1.5385rem;
            background-position:63.546% 15.517%;
        }
        &.sprite-arrow{
            width:0.7692rem;
            height:0.7692rem;
            background-position: 38.577% 52.076%;
        }
    }
    //border
    @each $dir in (top,right,bottom,left){
        .border-#{$dir}{
          border-#{$dir}:1px solid  $border-color;
        }
    }
    

    好了,都这里就结束了,隔了好久没写博客了,我的atom都陌生了😂。

    相关文章

      网友评论

          本文标题:Vue组件封装之--选项卡封装

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