vue.js三十七—— 从无到有完整的项目实战4

1. 商品购买模块

1.1 路由改造

1.1.1 新建goodsList.vue组件模板

<template>
    
    <div>
        <h3>商品购买</h3>
    </div>

</template>

<script>
export default {
    
}
</script>

<style lang="scss" scoped>

</style>

1.1.2 在routers.js中配置

// 导入商品列表组件
import goodsList from './components/goods/goodsList.vue';

{path:'/home/goodsList',component:goodsList}      // 商品列表

1.1.3 在homeContainner.vue中改造

 <li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-3">
                <router-link to="/home/goodsList">
                    <img src="../../images/menu3.png"  alt="" />
                    <div class="mui-media-body">商品购买</div>
                </router-link>
            </li>

点击商品购买,如图:

1.2 界面布局

我们要实现经典的商品展示两列布局,用flex与justify-content配合使用

<template>
    
    <div>
        <div class="goodlist">
            <div class="goods-item">
                <img src="http://img10.360buyimg.com/n1/s450x450_jfs/t11266/172/3136897597/311385/898550cb/5ce41430N7bb10f75.jpg" alt=""  />
                <h1 class="title">华为荣耀手机</h1>
                <div class="info">
                    <p class="price">
                        <span class="now">¥5999.00</span>
                        <span class="old">¥3999.00</span>
                    </p>
                    <p class="sell">
                        <span>热卖中</span>
                        <span>剩60件</span>
                    </p>
                </div>
            </div>
            
            <div class="goods-item">
                <img src="http://img10.360buyimg.com/n1/s450x450_jfs/t11266/172/3136897597/311385/898550cb/5ce41430N7bb10f75.jpg" alt=""  />
                <h1 class="title">华为荣耀手机</h1>
                <div class="info">
                    <p class="price">
                        <span class="now">¥5999.00</span>
                        <span class="old">¥3999.00</span>
                    </p>
                    <p class="sell">
                        <span>热卖中</span>
                        <span>剩60件</span>
                    </p>
                </div>
            </div>
            
            <div class="goods-item">
                <img src="http://img10.360buyimg.com/n1/s450x450_jfs/t11266/172/3136897597/311385/898550cb/5ce41430N7bb10f75.jpg" alt=""  />
                <h1 class="title">华为荣耀手机</h1>
                <div class="info">
                    <p class="price">
                        <span class="now">¥5999.00</span>
                        <span class="old">¥3999.00</span>
                    </p>
                    <p class="sell">
                        <span>热卖中</span>
                        <span>剩60件</span>
                    </p>
                </div>
            </div>
            
        </div>
    </div>

</template>

<script>
export default {
    
}
</script>

<style lang="scss" scoped>
    .goodlist {
        display: flex;
        flex-wrap: wrap;    // 让flex换行
        padding: 6px;
        justify-content: space-between;
        .goods-item {
            width:49%;  // 设置宽度,让每列显示两张图片
            border:1px solid #ccc;
            box-shadow: 0 0 10px #ccc;
            margin:3px 0;   // 设置上下边距2px,左右0
            padding:2px;
            img {
                width:  100%;
            }
            .title {
                font-size:14px;
            }
            .info {
                p {
                    margin:0;
                    padding:5px;
                }
                background: #eeee;
                .price {
                    .now {
                        color:red;
                        font-weight: bold;
                        font-size: 16px;
                    }
                    .old {
                        text-decoration: line-through;
                        text-decoration-color: black;
                        font-size: 13px;
                        margin-left: 10px;
                    }
                }
                .sell {
                    display: flex;
                    justify-content: space-between;
                    font-size: 13px;
                }
            }
        }
    }
</style>

效果图:

这样有一个问题,当其中一个标题过长的时候,与之并列的另一个会出现留白。我们通过css3的特性,通过改变主抽的方式来解决该问题

display:flex;
            flex-direction: column; // 更改主抽方向,默认是横向,现在改为竖向
            justify-content: space-between;

完整的css样式:

.goodlist {
        display: flex;
        flex-wrap: wrap;    // 让flex换行
        padding: 6px;
        justify-content: space-between;
        .goods-item {
            width:49%;  // 设置宽度,让每列显示两张图片
            border:1px solid #ccc;
            box-shadow: 0 0 10px #ccc;
            margin:3px 0;   // 设置上下边距2px,左右0
            padding:2px;
            display:flex;
            flex-direction: column; // 更改主抽方向,默认是横向,现在改为竖向
            justify-content: space-between;
            min-height: 293px;
            img {
                width:  100%;
            }
            .title {
                font-size:14px;
            }
            .info {
                p {
                    margin:0;
                    padding:5px;
                }
                background: #eeee;
                .price {
                    .now {
                        color:red;
                        font-weight: bold;
                        font-size: 16px;
                    }
                    .old {
                        text-decoration: line-through;
                        text-decoration-color: black;
                        font-size: 13px;
                        margin-left: 10px;
                    }
                }
                .sell {
                    display: flex;
                    justify-content: space-between;
                    font-size: 13px;
                }
            }
        }
    }

1.4 加载商品列表数据

我们前面的数据都是写死在界面的,现在我们需要从接口获取数据

1.4.1 定义获取数据的方法

getGoods(){
            this.$http.get('getgoods?pageindex='+this.pageindex).then(res => {
               this.goodsList = res.data.message;
            });
        },

1.4.2 改造页面

<div class="goods-item" v-for="item in goodsList" :key="item.id">
                <img :src="item.img_url" alt=""  />
                <h1 class="title">{{item.title}}</h1>
                <div class="info">
                    <p class="price">
                        <span class="now">¥{{item.sell_price}}</span>
                        <span class="old">¥{{item.market_Price}}</span>
                    </p>
                    <p class="sell">
                        <span>热卖中</span>
                        <span>剩{{item.stock_quantity}}件</span>
                    </p>
                </div>
            </div>

1.4.3 调用方法

created() {
        this.getGoods();
    }

运行效果如图:

1.5 制作加载更多按钮

1.5.1 定义加载更多的方法

getMore(){
            this.pageindex = this.pageindex+1;
            this.getGoods();
        }

1.5.2 改造getGoods方法

getGoods(){
            this.$http.get('getgoods?pageindex='+this.pageindex).then(res => {
               this.goodsList = this.goodsList.concat(res.data.message);
            });
        },

1.5.3 页面新增加载更多按钮

<mt-button type="danger" size="large" @click="getMore()">加载更多</mt-button>

2. 商品详情

2.1 传统的路由改造

2.2.1 新建goodsinfo.vue模板

<template>
    
    <div>
       <h1> 商品详情 ---- {{id}}</h1>
    </div>

</template>

<script>
export default {
    data(){
		return {
            id:this.$route.params.id
		}
    },
    created() {
        
    },
    methods: {
        
    },
}
</script>

<style lang="scss" scoped>
    
</style>

注意:this.$route.params.id 是获取链接地址中的参数id的

2.2.2 路由配置

// 导入商品详情组件
import goodsinfo from './components/goods/goodsinfo.vue';

{path:'/home/goodsinfo/:id',component:goodsinfo}      // 商品详情

2.2.3 页面改造

将goodsList.vue文件中的class=goods-item的div标签改为router-link并加上to属性

<router-link class="goods-item" v-for="item in goodsList" :key="item.id"
                :to="'/home/goodsinfo/' + item.id ">
                <img :src="item.img_url" alt=""  />
                <h1 class="title">{{item.title}}</h1>
                <div class="info">
                    <p class="price">
                        <span class="now">¥{{item.sell_price}}</span>
                        <span class="old">¥{{item.market_Price}}</span>
                    </p>
                    <p class="sell">
                        <span>热卖中</span>
                        <span>剩{{item.stock_quantity}}件</span>
                    </p>
                </div>
            </router-link>

注意:页面跳转方式,我们常用的有三种:

1. a标签形式

2. 在vue中使用router-link的方式

3. 使用window.location.href跳转,我们称这种方式为编程式导航

2.2 编程式导航

我们希望通过编程的方式动态的实现URL跳转,可以使用window.location.href,但是,我们在vue中是不提倡这种直接操作DOM元素的方式的,那么,我们可以想到vuerouter应该有给我们提供相应的方式。

参考文档链接:https://router.vuejs.org/zh/

2.2.1 使用

方式一:router.push(location, onComplete?, onAbort?)

方式二:this.$router.push

// 字符串
this.$router.push('home')  // 这里的home指的是router.js中配置的path地址

// 对象
this.$router.push({ path: 'home' })

// 命名的路由
this.$router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
this.$router.push({ path: 'register', query: { plan: 'private' }})

2.2.2 利用this.$router编程式导航跳转商品详情

1. 在div上定义点击事件

<div class="goods-item" v-for="item in goodsList" :key="item.id" @click="goDetail(item.id)">
                <img :src="item.img_url" alt=""  />
                <h1 class="title">{{item.title}}</h1>
                <div class="info">
                    <p class="price">
                        <span class="now">¥{{item.sell_price}}</span>
                        <span class="old">¥{{item.market_Price}}</span>
                    </p>
                    <p class="sell">
                        <span>热卖中</span>
                        <span>剩{{item.stock_quantity}}件</span>
                    </p>
                </div>
            </div>

2. 在methods中定义点击函数

goDetail(id){
    // 方式一:参数为route.js中定义的路由路径path
    //this.$router.push('/home/goodsinfo/'+id);

    // 方式二:参数为一个配置对象,key为path,值为route.js中的路由路径path
    // this.$router.push({ path: '/home/goodsinfo/'+id})

    /* 方式三:命名路由,参数为一个配置对象,name为路由对象的别名,params为参数
              例如:在route.js中有如下路由配置 
               {path:'/home/goodsinfo/:id',component:goodsinfo,name:'goodsInfo'}
              那么,命名路由形式如下:

    */
    // router.push({ name: 'goodsInfo', params: { id }}) 
    // 注意:当key为id,属性值的变量也为id的时候,可以简写id
    
}

2.2.3 this.$route与this.$router

我们在控制台打印this,发现其有两个对象,分别是route与router,这两者有什么区别呢?

1. this.$route:是路由参数对象,所有路由中的参数,params,query都属于它

2. this.$router:是一个路由导航对象,用它可以方便的使用js代码,实现路由的前进、后退、跳转到新的URL地址。

2.3 绘制商品详情页面卡片视图

在MUI中有一个实例card.html,其中有三种卡片形式,分别复制该三种形式,到指定的地方

<div class="goodsInfo-container">
      <!-- 轮播图区域 -->
      <div class="mui-card">
				<div class="mui-card-content">
					<div class="mui-card-content-inner">
						这是一个最简单的卡片视图控件;卡片视图常用来显示完整独立的一段信息,比如一篇文章的预览图、作者信息、点赞数量等
					</div>
				</div>
			</div>

      <!-- 数据区域 -->
      <div class="mui-card">
				<div class="mui-card-header">页眉</div>
				<div class="mui-card-content">
					<div class="mui-card-content-inner">
						包含页眉页脚的卡片,页眉常用来显示面板标题,页脚用来显示额外信息或支持的操作(比如点赞、评论等)
					</div>
				</div>
			</div>

      <!-- 页脚-->
      <div class="mui-card">
				<div class="mui-card-header">页眉</div>
				<div class="mui-card-content">
					<div class="mui-card-content-inner">
						包含页眉页脚的卡片,页眉常用来显示面板标题,页脚用来显示额外信息或支持的操作(比如点赞、评论等)
					</div>
				</div>
				<div class="mui-card-footer">页脚</div>
			</div>

    </div>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值