之前一直做得是pc端项目,使用的比较多的是element-ui,一直没怎么接触过移动端项目。趁着这段时间比较空闲,就了解了下vant,仿照极客时间的移动web商城。闹了个尴尬,极客时间商城就是用vant做的,难怪用着真香。 商城截图:
首先做项目我们得先做分析,先看上面的三张截图(也可以点击上面链接访问实际页面)。我们看到页面都是分区域的。从顶部往下分别是广告、礼品卡搜索、轮播、三张推荐小图、数据列表(两种布局)、底部copyright、固定底部的tabbar。为了方便修改,七个区块我们可以分为七个组件,这样便于后续页面内容的添加或删除。
我们使用vue-cli3.0生成基础目录结构,在view目录下新建一个home文件夹存放首页的内容,index.vue组件来承载上面说的七个区块,容器组件作为页面的顶层组件,可以用来处理一些数据请求并传递给区块组件,文件划分如下:
<template>
<div class="panel" v-if="Object.keys(data).length">
<div class="panel-title">
<div class="title">{{ data.title }}</div>
<div class="sub-title">-{{ data.subTitle }}-</div>
</div>
<div class="content">
<!-- 插槽用来放主要内容 -->
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
data: {
type: Object,
default() {
return {};
}
}
}
};
</script>
我们通过data传递title、subTitle,你也可以将他们拆开。 容器有了,我们来实现列表。实际上,列表可以分为两个组件,决定list布局方式的为一个组件,list每一个数据项是一个组件,这样拆开我们就可以随意更换每个数据项的内容。我们先来看list怎么决定布局的列数。我们知道vant有自带的栅格系统,我们基于栅格组件来处理列数的问题,如下:
<template>
<van-row>
<van-col v-for="(item, index) in data" :key="index" :span="spanNum">
<item :data="item" :height="height" />
</van-col>
</van-row>
</template>
span属性值决定了列元素的宽度,宽度的多少实际上就决定了一行可以显示多少列。我们根据传入的col参数计算van-col的span值:
<script>
export default {
props: {
col: {
type: Number,
default: 1
}
},
computed: {
spanNum() {
return Math.floor(24 / this.col);
}
}
};
</script>
然后循环传入的数据列表,并将每一个数据项的值传入到item组件里,由item组件自己做数据的渲染,item组件如下:
<template>
<div class="item">
<van-image :src="data.img" fit="scale-down" :height="height + ''" />
<h3 class="title">{{ data.title }}</h3>
<p class="price-info">
<span class="price-tag">¥</span>{{ data.price }}
<van-icon class="cart" :name="data.icon" />
</p>
</div>
</template>
<script>
export default {
props: {
data: {
type: Object,
default() {
return {};
}
},
height: {
type: Number
}
}
};
</script>
这就是我实现数据列表区域的思路,组件关系图如下:
使用方式如下:
<template>
<panel :data="data.category">
<list
:col="data.category.col"
:data="data.list"
:height="data.category.height"
/>
</panel>
</template>
<script>
import panel from "@/components/Panel";
import list from "@/components/List";
export default {
components: {
panel,
list
},
props: {
data: {
type: Object,
default() {
return {};
}
}
}
};
</script>
以上就是我的简要分析,多有不足,希望大家多提意见。
详细代码:https://gitee.com/linbingrong/vant-geektime.git