摘要:手把手从0到1用vant组件库快速上手构建一个vue3移动端电商项目。
一、工具安装
- Node 版本要求
Vue CLI 4.x 需要 Node.js v8.9 或更高版本(推荐v10以上)。你可以使用n,nvm或nvm-windows在同一台电脑中管理多个 Node 版本。 - 关于旧版本
Vue CLI的包名称由vue0cli改成了@vue/cli。如果你已经全局安装了旧版本的vue-cli(1.x或2.x),你需要先通过npm uninstall vue-cli -g 或 yarn global remove vue-cli 卸载它。 - 安装命令
npm install -g @vue/cli
vue --version
vue -V
如果安装不成功,可以尝试以下几点安装
- npm设置淘宝镜像
- 安装cnpm,用cnpm安装
- 命令行窗口用管理员身份打开
- 多执行几次,多安装几次
二、开始创建项目
- 打开命令行 win+r
- 进入你要创建项目的目录下 cd 路径
- 输入 vue create 项目名称
- 在弹出提示中选择 Manually select features (通过方向键上下移动光标,空格键勾选,回车键确认)
- 在这个项目中我们只需要用到babel和router,只勾选这两项就好了
- 选择3.x版本
- 接下来根据提示选择你要的选项就可以了
三、安装vant
这里我们是vue3的项目,通过npm i vant 安装
通过命令行安装:
# Vue 3 项目,安装最新版 Vant
npm i vant
# Vue 2 项目,安装 Vant 2
npm i vant@latest-v2
四、引入组件样式
使用 unplugin-vue-components 插件,它可以自动引入组件,并按需引入组件的样式。
- 安装插件
# 通过 npm 安装
npm i unplugin-vue-components -D
# 通过 yarn 安装
yarn add unplugin-vue-components -D
# 通过 pnpm 安装
pnpm add unplugin-vue-components -D
- 配置插件
在 vue.config.js 文件中配置:
const { VantResolver } = require('unplugin-vue-components/resolvers');
const ComponentsPlugin = require('unplugin-vue-components/webpack');
module.exports = {
configureWebpack: {
plugins: [
ComponentsPlugin({
resolvers: [VantResolver()],
}),
],
},
};
完成以上两步,就可以直接在模板中使用 Vant 组件了,unplugin-vue-components 会解析模板并自动注册对应的组件。
五、使用vant构建页面
- 创建路由
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
name: 'home',
path: '/',
redirect: 'goods',
meta: {
title: '首页'
}
},
{
name: 'user',
path: '/user',
component: () => import('@/views/user'),
meta: {
title: '会员中心'
}
},
{
name: 'cart',
path: '/cart',
component: () => import('@/views/cart'),
meta: {
title: '购物车'
}
},
{
name: 'goods',
path: '/goods',
component: () => import('@/views/goods'),
meta: {
title: '商品详情'
}
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
router.beforeEach((to, from, next) => {
const title = to.meta && to.meta.title;
if (title) {
document.title = title;
}
next();
});
export default router
- 在views文件夹下写你的页面
- 商品页面
<template>
<div class="goods">
<van-swipe class="goods-swipe" :autoplay="3000">
<van-swipe-item v-for="thumb in goods.thumb" :key="thumb">
<img :src="thumb" />
</van-swipe-item>
</van-swipe>
<van-cell-group>
<van-cell>
<div class="goods-title">{{ goods.title }}</div>
<div class="goods-price">{{ formatPrice(goods.price) }}</div>
</van-cell>
<van-cell class="goods-express">
<van-col span="10">运费:{{ goods.express }}</van-col>
<van-col span="14">剩余:{{ goods.remain }}</van-col>
</van-cell>
</van-cell-group>
<van-cell-group class="goods-cell-group">
<van-cell value="进入店铺" icon="shop-o" is-link @click="sorry">
<template #title>
<span class="van-cell-text">有赞的店</span>
<van-tag class="goods-tag" type="danger">官方</van-tag>
</template>
</van-cell>
<van-cell title="线下门店" icon="location-o" is-link @click="sorry" />
</van-cell-group>
<van-cell-group class="goods-cell-group">
<van-cell title="查看商品详情" is-link @click="sorry" />
</van-cell-group>
<van-action-bar>
<van-action-bar-icon icon="chat-o" @click="sorry">
客服
</van-action-bar-icon>
<van-action-bar-icon icon="cart-o" @click="onClickCart">
购物车
</van-action-bar-icon>
<van-action-bar-icon icon="manager-o" @click="onClickUser">
会员中心
</van-action-bar-icon>
<van-action-bar-button type="warning" @click="sorry">
加入购物车
</van-action-bar-button>
<van-action-bar-button type="danger" @click="sorry">
立即购买
</van-action-bar-button>
</van-action-bar>
</div>
</template>
<script>
import { Toast } from 'vant';
import 'vant/es/toast/style';
export default {
data() {
return {
goods: {
title: '美国伽力果(约680g/3个)',
price: 2680,
express: '免运费',
remain: 19,
thumb: [
'https://img.yzcdn.cn/public_files/2017/10/24/e5a5a02309a41f9f5def56684808d9ae.jpeg',
'https://img.yzcdn.cn/public_files/2017/10/24/1791ba14088f9c2be8c610d0a6cc0f93.jpeg',
],
},
};
},
methods: {
formatPrice() {
return '¥' + (this.goods.price / 100).toFixed(2);
},
onClickCart() {
this.$router.push('cart');
},
onClickUser() {
this.$router.push('user')
},
sorry() {
Toast('暂无后续逻辑~');
},
},
};
</script>
<style lang="less">
.goods {
padding-bottom: 50px;
&-swipe {
img {
width: 100%;
display: block;
}
}
&-title {
font-size: 16px;
}
&-price {
color: #f44;
}
&-express {
color: #999;
font-size: 12px;
padding: 5px 15px;
}
&-cell-group {
margin: 15px 0;
.van-cell__value {
color: #999;
}
}
&-tag {
margin-left: 5px;
}
}
</style>
<template>
<div>
<van-nav-bar
title="购物车"
left-text="返回"
left-arrow
@click-left="onClickLeft"
/>
<van-checkbox-group class="card-goods" v-model="checkedGoods">
<van-checkbox
class="card-goods__item"
v-for="item in goods"
:key="item.id"
:name="item.id"
>
<van-card
:num="item.num"
:price="formatPrice(item.price)"
:desc="item.desc"
:title="item.title"
:thumb="item.thumb"
/>
</van-checkbox>
</van-checkbox-group>
<van-submit-bar
:price="totalPrice"
:button-text="submitBarText"
:disabled="!checkedGoods.length"
@submit="onSubmit"
/>
</div>
</template>
<script>
import { Toast } from "vant";
import "vant/es/toast/style";
export default {
data() {
return {
checkedGoods: ["1", "2", "3"],
goods: [
{
id: "1",
title: "进口香蕉",
desc: "约250g,2根",
price: 200,
num: 1,
thumb:
"https://img.yzcdn.cn/public_files/2017/10/24/2f9a36046449dafb8608e99990b3c205.jpeg",
},
{
id: "2",
title: "陕西蜜梨",
desc: "约600g",
price: 690,
num: 1,
thumb:
"https://img.yzcdn.cn/public_files/2017/10/24/f6aabd6ac5521195e01e8e89ee9fc63f.jpeg",
},
{
id: "3",
title: "美国伽力果",
desc: "约680g/3个",
price: 2680,
num: 1,
thumb:
"https://img.yzcdn.cn/public_files/2017/10/24/320454216bbe9e25c7651e1fa51b31fd.jpeg",
},
],
};
},
computed: {
submitBarText() {
const count = this.checkedGoods.length;
return '结算' + (count?`(${count})`:'')
},
totalPrice() {
var sum = 0;
for(let i = 0; i < this.checkedGoods.length; i++) {
for(let j = 0; j < this.goods.length; j++) {
if(this.checkedGoods[i] == this.goods[j].id) {
sum = sum + this.goods[j].price
}
}
}
return sum
}
},
methods: {
onClickLeft() {
this.$router.back();
},
formatPrice(price) {
return (price / 100).toFixed(2);
},
onSubmit() {
Toast("点击结算");
},
},
};
</script>
<style lang="less">
.card-goods {
padding: 10px 0;
background-color: #fff;
&__item {
position: relative;
background-color: #fafafa;
.van-checkbox__label {
width: 100%;
height: auto; // temp
padding: 0 10px 0 15px;
box-sizing: border-box;
}
.van-checkbox__icon {
position: absolute;
top: 50%;
left: 10px;
margin-top: -10px;
z-index: 1;
}
.van-card__price {
color: #f44;
}
}
}
</style>
<template>
<div>
<van-nav-bar
title="会员中心"
left-text="返回"
left-arrow
@click-left="onClickLeft"
/>
<img
class="user-poster"
src="https://img.yzcdn.cn/public_files/2017/10/23/8690bb321356070e0b8c4404d087f8fd.png"
/>
<van-row class="user-links">
<van-col span="6">
<van-icon name="pending-payment" />
待付款
</van-col>
<van-col span="6">
<van-icon name="records" />
待接单
</van-col>
<van-col span="6">
<van-icon name="tosend" />
待发货
</van-col>
<van-col span="6">
<van-icon name="logistics" />
已发货
</van-col>
</van-row>
<van-cell-group class="user-group">
<van-cell icon="records" title="全部订单" is-link />
</van-cell-group>
<van-cell-group class="user-group">
<van-cell icon="points" title="我的积分" is-link />
<van-cell icon="gold-coin-o" title="我的优惠券" is-link />
<van-cell icon="gift-o" title="我收到的礼物" is-link />
</van-cell-group>
</div>
</template>
<script>
export default {
methods: {
onClickLeft() {
this.$router.back()
}
}
};
</script>
<style lang="less">
.user {
&-poster {
width: 100%;
height: 53vw;
display: block;
}
&-links {
padding: 15px 0;
font-size: 12px;
text-align: center;
background-color: #fff;
.van-icon {
display: block;
font-size: 24px;
}
}
&-group {
margin-bottom: 15px;
}
}
</style>
六、页面效果
|