Vue项目实战

通过前面的学习已经初步掌握了Vue的相关基础知识,这周主要是通过一个小项目对Vue的相关知识进行学习。

项目详细代码链接,实时更新(https://github.com/TaiYiZhen/supermall.git)

一.自定义TabBar组件

首先新建一个项目tabbar用来封装自定义TabBar组件以便于在后期项目中使用

实现思路:

1. 如果在下方有一个单独的TabBar组件,你如何封装 自定义TabBar组件,在APP中使用 让TabBar出于底部,并且设置相关的样式

2.TabBar中显示的内容由外界决定 定义插槽 flex布局平分TabBar 

3.自定义TabBarItem,可以传入 图片和文字 定义TabBarItem,并且定义两个插槽:图片、文字。 给两个插槽外层包装div,用于设置样式。 填充插槽,实现底部TabBar的效果

4.传入 高亮图片 定义另外一个插槽,插入active-icon的数据 定义一个变量isActive,通过v-show来决定是否显示对应的icon

5.TabBarItem绑定路由数据 安装路由:npm install vue-router —save 完成router/index.js的内容,以及创建对应的组件 main.js中注册router APP中加入<router-view>组件

6.点击item跳转到对应路由,并且动态决定isActive 监听item的点击,通过this.$router.replace()替换路由路径 通过this.$route.path.indexOf(this.link) !== -1来判断是否是active

7.动态计算active样式 封装新的计算属性:this.isActive ? {'color': 'red'} : {}

主要代码如下

<template>
  <div id="tab-bar">
    <slot></slot>
  </div>
</template>

<script>
  export default {
    name: "TabBar"
  }
</script>

<style scoped>
  /*使用flex布局让其均等分,居中*/
#tab-bar {
  display: flex;
  background-color: #f6f6f6;
  /*置底显示*/
  position: fixed;;
  left: 0;
  right: 0;
  bottom: 0;
  /*阴影*/
  box-shadow: 0 -3px 1px rgba(100, 100, 100, .1);
}


</style>
<template>
  <div class="tab-bar-item" @click="itemClick">
    <div v-if="!isActive"><slot name="item-icon"></slot></div>
    <div v-else><slot name="item-icon-active"></slot></div>
    <div :style="activeStyle"><slot name="item-text"></slot></div>
  </div>
</template>

<script>
  export default {
    name: "TabBarItem",
    props:{
      path:String,
      activeColor:{
        type:String,
        default:'red'
      }
    },
    data(){
      return{
        /*isActive:true*/
      }
    },
    computed:{
      isActive(){
        return this.$route.path.indexOf(this.path)!==-1
      },
      activeStyle(){
        return this.isActive ? {color: this.activeColor} : {}
      }
    },
    /*监听事件*/
    methods:{
      itemClick(){
        this.$router.replace(this.path);
      }
    }
  }
</script>

<style scoped>
  .tab-bar-item {
    flex: 1;
    text-align: center;
    height: 49px;
    font-size: 14px;
  }

  .tab-bar-item img {
    width: 24px;
    height: 24px;
    margin-top: 3px;
    vertical-align: middle;
  }

</style>

二.axios网络请求模块封装(+拦截器)

封装一个axios网络请求模块,便于后期开发维护

import axios from 'axios'

export function request(config) {
    /*创建axios实例*/
    const instance = axios.create({
        baseURL: '接口地址',
        timeout: 5000
    })

    /*axios的拦截器*/
    /*拦截请求*/
    instance.interceptors.request.use(config => {
            console.log(config);
            /*为什么要拦截请求:*/
            /*比如config中有一些信息不符合服务器要求*/
            /*比如每次发送网络请求时希望显示请求图标*/
            /*某些网络请求(比如登陆)必须携带一些特殊信息*/
            /*f返回请求*/
            return config;
        }, err => {
            console.log(err);
        }
    );
    /*拦截响应*/
    instance.interceptors.response.use(res=>{
            console.log(res);
            /*返回响应*/
            return res.data;
        }, err => {
            console.log(err);
        }
    );
    /*发送真正的网络请求*/
    return instance(config)
}

/*export function request(config) {
    return new Promise((resolve, reject) => {
        /!*创建axios实例*!/
        const instance=axios.create({
            baseURL:'接口地址',
            timeout:5000
        })
        /!*发送真正的网络请求*!/
        instance(config)
            .then(res => {
                resolve(res)
            })
            .catch(err => {
                reject(err)
            })
    })
}*/

/*export function request(config) {
    /!*创建axios实例*!/
    const instance=axios.create({
        baseURL:'接口地址',
        timeout:5000
    })
    /!*发送真正的网络请求*!/
    instance(config.baseConfig)
        .then(res=>{
            /!*console.log(res);*!/
            config.success(res)
        })
        .catch(err =>{
            /!*console.log(err);*!/
            config.failure(err)
        })
}*/

/*
export function request(config,success,failure) {
    /!*创建axios实例*!/
    const instance=axios.create({
        baseURL:'接口地址',
        timeout:5000
    })
    /!*发送真正的网络请求*!/
    instance(config)
        .then(res=>{
            /!*console.log(res);*!/
            success(res)
        })
        .catch(err =>{
            /!*console.log(err);*!/
            failure(err)
        })
}*/
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
}).$mount('#app')

/*axios简单使用*/
/*axios({
    url: '接口地址',
    methods: 'get'
}).then(res => {
    console.log(res);
})

axios({
    url: '接口地址',
    //专门针对get请求的参数拼接
    params: {
        type: 'pop',
        page: 1
    }
}).then(res => {
    console.log(res);
})*/

/*axios发送并发请求*/
/*axios.all([axios({
    url: '接口地址'
}), axios({
    url: '接口地址',
    params: {
        type: 'pop',
        page: 1
    }
})]).then(results => {
    console.log(results);
    console.log(results[0]);
    console.log(results[1]);
})*/

/*使用全局的axios和对应的配置在进行网络请求*/
/*axios.defaults.baseURL='接口地址'
axios.defaults.timeout=5000
axios.all([axios({
    url: '/home/multidata'
}), axios({
    url: '/home/data',
    params: {
        type: 'pop',
        page: 1
    }
})]).then(axios.spread((res1,res2)=> {
    console.log(res1);
    console.log(res2);
}))*/

/*/!*创建对应的axios的实例*!/
const instance1=axios.create({
    baseURL:'接口地址',
    timeout:5000
})
instance1({
    url:'/home/multidata'
}).then(res=>{
    console.log(res);
})
instance1({
    url:'/home/data',
    params: {
        type: 'pop',
        page: 1
    }
}).then(res=>{
    console.log(res);
})*/

/*封装request模块*/
import {request} from "./network/request";

request({
    url:'/home/multidata'
}).then(res=>{
    console.log(res);
},err=>{
    console.log(err);
})

/*request({
    baseConfig:{
    },
    success:function (res) {
    },
    failure:function (err) {
    }
})*/

/*request({
    url:'/home/multidata'
},res=>{
    console.log(res);
},err=>{
    console.log(err);
})*/


三.首页开发

首页开发初步效果如下(代码太多不做展示,对源码感兴趣的见文章顶部链接)

项目采用组件化开发思想

首页主要由以下组件构成:

NavBar组件:构成顶部导航栏

轮播组件:构成首页顶端的轮播效果

RecommendView:首页推荐信息的展示

FeatureView:首页本周流行展示(该组件比较简单)由图片加链接构成

tabControl:首页商品类型切换(流行,新款,精选)

GoodsList:商品数据展示

Scroll:原生的滚动效果不理想,采用betterscroll组件

BackTop:回到顶部

四.详情页开发

解决了轮播不畅的问题

<template>
  <div>
    <swiper class="detail-swiper" v-if="topImages.length">
      <swiper-item class="swiper-item" v-for="(item, index) in topImages" :key="index">
        <img :src="item" alt="">
      </swiper-item>
    </swiper>
  </div>
</template>

添加v-if="topImages.length"解决

详情页开发效果如下:

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值