Vue项目实战:首页实现

目录

1. Nav-Header组件

2. 首页轮播功能实现

一. Nav-Header组件

(1)组件复用的一个技巧:

因为商场网站中多个页面共用了头部组件nav-header和底部组件nav-footer,而为了避免 每个需要这两个组件的页面中都需要单独引入组件,我们可以通过一个home页面来复用共用的组件。

  • 在路由文件中:
	{
			path: '/',
            name: 'home',
            component:Home,
            redirect: '/index',
            children: [ //下面是需要头部和底部组件的页面
                {
                    path: '/index',
                    name: 'index',
                    component: Index,
                },
                {
                    path: '/product/:id',
                    name: 'product',
                    component: Product,
                },
                {
                    path: '/detail/:id',
                    name: 'detail',
                    component: Detail,
                }                
            ]
        },
  • 在home.vue中:
<template>
    <div>
        home
        <nav-header></nav-header>
        <router-view></router-view>
        <nav-footer></nav-footer>
    </div>
</template>
<script>
import NavHeader from './../components/NavHeader';
import NavFooter from './../components/NavFooter';
export default {
    name: 'nav-home',
    components: {
        NavHeader,
        NavFooter

    }
}
</script>

(2)通过@mixin简化代码

为了有效的维护和开发项目,代码的重复利用就显得尤为重要。在Sass中,除了@import@extend可以使代码更加具有重复利用性,@mixin指令也同样能提高代码的重复使用率并简化你的代码。

  • 在assets文件夹中创建一个scss文件夹。在scss文件夹中创建mixin.scss文件,在里面存放将会共用的代码:
@mixin flex($hov: space-between, $col:center) {
    display: flex;
    justify-content: $hov;
    align-items: $col;
}

@mixin bgImg($w:0, $h:0, $img:'', $size:contain) {
    display: inline-block;
    width: $w;
    height: $h;
    background:url($img) no-repeat center;
    background-size: $size;
    margin-right: 4px;
}
  • 在用到mixin.scss里样式的文件NavHeader里,在<style>标签中引入mixin.scss文件并替换用到的css代码
<style lang="scss">
@import './../assets/scss/mixin.scss';
    .container{
            height: 112px;
		/*	display: flex;
        	justify-content: $hov;
        	 align-items: $col; */
            @include flex();
    }
        .my-cart{
            width: 100px;
            background-color: #FF6600;
            text-align: center;
            color: #ffffff;
            .icon-cart{
           /*
               display: inline-block;
  			   width: 16px;
   		       height: 12px;
  		  	   background:url('/imgs/icon-cart-checked.png') no-repeat center;
 			   background-size: contain;
 			   margin-right: 4px;
                */
                @include bgImg(16px, 12px, '/imgs/icon-cart-checked.png');
                margin-right:4px;
            }
        }  
    
</style>
  • @mixin学习资料:

Sass: @mixin指令介绍

Sass: @mixin 菜鸟教程

(3)统一修改系统主题色

  • 在scss文件夹中加入文件config.scss文件,该文件定义了一些常规样式。
/*
  样式规范表
*/
$min-width:1226px;  //容器安全区域宽度

// 常规字体大小设置
$fontA:       80px; //产品站大标题
$fontB:       38px; //产品站标题
$fontC:       28px; //导航标题
$fontD:       26px; //产品站副标题
$fontE:       24px; 
$fontF:       22px;
$fontG:       20px; //用在较为重要的文字、操作按钮
$fontH:       18px; //用于大多数文字
$fontI:       16px; //用于辅助性文字
$fontJ:       14px; //用于一般文字
$fontK:       12px; //系统默认大小

// 常规配色设置
$colorA:      #FF6600 !default; //用于需要突出和强调的文字、按钮和icon
$colorB:      #333333 !default; //用于较为重要的文字信息、内页标题等
$colorC:      #666666 !default; //用于普通段落信息 引导词
$colorD:      #999999 !default; //用于辅助、此要的文字信息、普通按钮的描边
$colorE:      #cccccc !default; //用于特别弱的文字
$colorF:      #d7d7d7 !default; //用于列表分割线、标签秒变
$colorG:      #ffffff !default; //用于导航栏文字、按钮文字、白色背景
$colorH:      #e5e5e5 !default; //用于上下模块分割线
$colorI:      #000000 !default; //纯黑色背景,用于遮罩层
$colorJ:      #F5F5F5 !default; //弹框标题背景色
$colorK:      #FFFAF7 !default; //订单标题背景色
  • 在需要用到常规样式的组件或页面中引入config.scss并使用样式:
<style lang="scss">
@import "./../assets/scss/config.scss";
          &:hover {
              color:$colorA;
          }
</style>    

(4) 数据请求

export default {
  name: "nav-header",
  data() {
    return {
      username: "jack",
      phoneList: []
    };
  },
  mounted() {
    this.getProductList();
  },
  methods: {
    getProductList() {
      this.axios
        .get("/products", {
          params: {
            categoryId: "100012"
          }
        })
        .then(res => {
          if (res.list.length > 6) {
            this.phoneList = res.list.slice(0, 6);
          }
        });
    },
  }
};

二. 首页轮播功能实现

(1)使用vue-awesome-swiper实现轮播图

  • 安装vue-awesome-swiper:

npm install vue-awesome-swiper --save

  • 在需要用到该插件的文件里导入和使用组件:
<template>
      <div class="swiper-box">
        <swiper v-bind:options="swiperOption">
          <swiper-slide v-for="(item, index) in slideList" v-bind:key="index">
            <a v-bind:href="'/#/product' + item.id">
              <img v-bind:src="item.img"/>
            </a>
          </swiper-slide>
          <div class="swiper-pagination" slot="pagination"></div>
          <div class="swiper-button-prev" slot="button-prev"></div>
          <div class="swiper-button-next" slot="button-next"></div>
        </swiper>
      </div>
</template>
<script>
import {swiper, swiperSlide} from 'vue-awesome-swiper';
import 'swiper/dist/css/swiper.css'
export default {
    name: 'index',
    components: {
        swiper,
        swiperSlide,
    },
    data() {
        return {
            swiperOption: {
                autoplay:true, //自动播放
                loop:true, //循环播放
                effect:'cube', //切换效果
                cubeEffect: { //cube的相关配置参数
                    slideShadows:true,
                    shadow:true,
                    shadowOffset:100,
                    shadowScale:0.6
                },
                pagination: { //指定分页器
                    el: '.swiper-pagination',
                    clickable:true //允许分页器可点击
                },
                navigation: { //指定前进后退按钮
                    nextEl: '.swiper-button-next',
                    prevEl: '.swiper-button-prev'
                }
            },
            slideList: [ //轮播图片数组
                {
                   id: '42',
                   img:'/imgs/slider/slide-1.jpg'   
                },
                {
                   id: '45',
                   img:'/imgs/slider/slide-2.jpg'   
                },
                {
                   id: '46',
                   img:'/imgs/slider/slide-3.jpg'   
                }
            ]
        }
    }
}
</script>
<!--省略样式代码-->

(2)首页轮播菜单实现

关于实现一个3行4列的图片展示区域:(数据为已定义好的静态数据)

              <div class="children">
                  <ul v-for="(item,i) in menuList" v-bind:key="i">
                      <li v-for="(sub, j) in item" v-bind:key="j">
                          <a v-bind:href="sub?'/#/product/'+sub.id : ''">
                            <img v-bind:src="sub?sub.img:'/imgs/item-box-1.png'">
                            {{sub?sub.name:'小米9'}}
                          </a>
                      </li>
                  </ul>
              </div>
<script>
export default {
    data() {
        return {
            menuList: [
          [
              {
                  id:30,
                  img:'/imgs/item-box-1.png',
                  name:'小米CC9'
              },{
                   id:31,
                  img:'/imgs/item-box-2.png',
                  name:'小米8青春版'                 
              },{
                    id:32,
                  img:'/imgs/item-box-3.jpg',
                  name:'Redmi K20 Pro'                  
              },{
                id:33,
                  img:'/imgs/item-box-2.png',
                  name:'移动4G专区' 
              }
              
          ],
          [0,0,0,0],
          [0,0,0,0]
      ]
        }
    }
}
</script>

(3)Modal弹窗动画 与 父子组件通信

  • 用到vue的transition组件,考虑到较多页面需要用到弹窗,所以将弹窗写成一个独立的组件,在Modal.vue中:
<!--弹窗内容写在transition组件中-->
<template>
  <transition name="slide">
    <div class="modal" v-show="showModal">
      <div class="mask"></div>
      <div class="modal-dialog">
        <div class="modal-header">
          <span>{{title}}</span>
          <a href="javascript:;" class="icon-close" v-on:click="$emit('cancel')"></a>
        </div>
        <div class="modal-body">
          <slot name="body"></slot>
        </div>
        <div class="modal-footer">
          <a href="javascript:;" class="btn" v-if="btnType==1" v-on:click="$emit('submit')">{{sureText}}</a>
          <a href="javascript:;" class="btn" v-if="btnType==2" v-on:click="$emit('cancel')">{{cancelText}}</a>
          <div class="btn-group" v-if="btnType==3">
            <a href="javascript:;" class="btn" v-on:click="$emit('submit')">{{sureText}}</a>
            <a href="javascript:;" class="btn btn-default" v-on:click="$emit('cancel')">{{cancelText}}</a>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>
<script>
  export default{
    name:'modal',
    props:{
      // 弹框类型:小small、中middle、大large、表单form
      modalType:{
        type:String,
        default:'form'
      },
      // 弹框标题
      title:String,
      // 按钮类型: 1:确定按钮 2:取消按钮 3:确定取消
      btnType:String,
      sureText:{
        type:String,
        default:'确定'
      },
      cancelText:{
        type:String,
        default:'取消'
      },
      showModal:Boolean
    }
  }
</script>
<style lang="scss">
@import './../assets/scss/config.scss';
@import './../assets/scss/mixin.scss';
@import './../assets/scss/modal.scss';
</style>
  • 在modal.scss中关于弹窗的动画:
 .modal{
	 transition: all .5s;
     &.slide-enter-active{
         top:0;
     }
     &.slide-leave-active{
         top:0;
     }
     &.slide-enter{
         top:-100%;
     }     
}
/*其他样式省略*/
  • 在index.vue页面中使用弹窗组件:
    <modal 
      title="提示" 
      sureText="查看购物车" 
      btnType="1" 
      modalType="middle" 
      v-bind:showModal="showModal"
      v-on:submit="goToCart"
      v-on:cancel="showModal=false"
      >
      <template v-slot:body>
        <p>商品添加成功!</p>
      </template>
    </modal>
<script>
import Modal from './../components/Modal'
export default {
  name: "index",
  components: {
    Modal
  },
  data() {
      return {
          showModal: false
      }
  },
  methods: {
    addCart() {
      this.showModal = true;
    },
    gotoCart() {
      this.$router.push('/cart');
    }
  }      
  }
    
</script>

(4)懒加载

  • 下载插件:

npm i vue-lazyload -S

  • 在main.js里引入并配置:
import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad, {
  loading:'/imgs/loading-svg/loading-bars.svg'//图片在加载过程的动画
})

  • 在index.vue中使用懒加载:
<!--没有懒加载的写法-->        
<a
     v-bind:href="'/#/product/' + item.id"
     v-for="(item, index) in adsList"
     v-bind:key="index"
>
     <img v-bind:src="item.img" alt />
</a>
<a href="/#/product/30">
      <img src="'/imgs/banner-1.png'" alt />
</a>

<!--使用懒加载的写法-->   
<a
      v-bind:href="'/#/product/' + item.id"
       v-for="(item, index) in adsList"
       v-bind:key="index"
>
      <img v-lazy="item.img" alt />
</a>
<a href="/#/product/30">
    <img v-lazy="'/imgs/banner-1.png'" alt />
</a>

发布了77 篇原创文章 · 获赞 181 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_46124214/article/details/105183521