1.小程序全局配置
创建uniapp,首先打开HBuilderX
创建uniapp环境安装
npm install -g @vue/cli
vue create -p dcloudio/uni-preset-vue my-project
在点击工具栏里的文件 -> 新建 -> 项目:
2.在uni-app件的小程序里建立页面
全局配置:
在pages.json入口
`
{
“pages”: [
{
“path” : “pages/home/home”,
“style” : {
“navigationBarTitleText”: “清青-首页”,
“enablePullDownRefresh”: true
}
},
{
“path”: “pages/index/index”,
“style”: {
}
},
{
“path” : “pages/kind/kind”,
“style” : {
“navigationBarTitleText”: “清青-分类”
}
},
{
“path” : “pages/cart/cart”,
“style” : {
“navigationBarTitleText”: “清青-购物车”
}
},
{
“path” : “pages/user/user”,
“style” : {
“navigationBarTitleText”: “清青-我的”
}
},
{
“path” : “pages/detail/detail”,
“style” : {}
}
,{
“path” : “pages/login/login”,
“style” : {}
}
,{
“path” : “pages/register/register”,
“style” : {}
}
],
“globalStyle”: {
“navigationBarTextStyle”: “white”,
“navigationBarTitleText”: “清青”,
“navigationBarBackgroundColor”: “#ff6666”,
“backgroundColor”: “#F8F8F8”
},
“tabBar”: {
“color”: “#333”,
“selectedColor”: “#f66”,
“backgroundColor”: “#efefef”,
“borderStyle”: “white”,
“list”: [
{
“pagePath”: “pages/home/home”,
“text”: “首页”,
“iconPath”: “static/resources/home.png”,
“selectedIconPath”: “static/resources/home_active.png”
},
{
“pagePath”: “pages/kind/kind”,
“text”: “分类”,
“iconPath”: “static/resources/kind.png”,
“selectedIconPath”: “static/resources/kind_active.png”
},
{
“pagePath”: “pages/cart/cart”,
“text”: “购物车”,
“iconPath”: “static/resources/cart.png”,
“selectedIconPath”: “static/resources/cart_active.png”
},
{
“pagePath”: “pages/user/user”,
“text”: “我的”,
“iconPath”: “static/resources/user.png”,
“selectedIconPath”: “static/resources/user_active.png”
}
]
},
“condition”: { //模式配置,仅开发期间生效 ---- 设置小程序的编译模式
“current”: 0, //当前激活的模式(list 的索引项)
“list”: [{
“name”: “首页”,
“path”: “pages/home/home”
},{
“name”: “分类”,
“path”: “pages/kind/kind”
},{
“name”: “购物车”,
“path”: “pages/cart/cart”
},{
“name”: “我的”,
“path”: “pages/user/user”
},{
“name”: “登陆”,
“path”: “pages/login/login”
}]
}
}
底部导航栏
在pages页面创立页面
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200223151830116.png)
3首页-轮播图以及商品列表
```javascript
<swiper :indicator-dots="true" :autoplay="true" :circular="true">
<swiper-item v-for="(item, index) of bannerlist" :key="index">
<image :lazy-load="true" mode="aspectFit" :src="'http://daxun.kuboy.top' + item" ></image>
</swiper-item>
</swiper>
<prolist :prolist="prolist"/>//
<view class="tip" v-if="flag">没有更多数据了</view>
<view class="iconfont" @click="backtop">↑</view>
import prolist from '../../components/prolist/prolist.vue'
import { request } from '../../utils/index.js'
export default {
data() {
return {
bannerlist: [],
prolist: [],
pageCode: 1,
flag: false // 表示有无数据的标识
}
},
components: {
prolist
},
mounted () {
request({
url: '/pro/banner'
}).then(res => {
console.log(res.data)
this.bannerlist = res.data.data
})
request({
url: '/pro'
}).then(res => {
console.log(res.data)
this.prolist = res.data.data
})
},
onPullDownRefresh () { // 下拉刷新
console.log('下拉刷新')
request({
url: '/pro'
}).then(res => {
console.log(res.data)
this.prolist = res.data.data
this.pageCode = 1 // 重置页码
this.flag = false // 有无数据标识隐藏
// 当处理完数据刷新后,uni.stopPullDownRefresh 可以停止当前页面的下拉刷新。
uni.stopPullDownRefresh()
})
},
onReachBottom () { // 上拉加载
request({
url: '/pro',
data: {
pageCode: this.pageCode,
limitNum: 10
}
}).then(res => {
this.pageCode++
if (res.data.code === '10000') {
this.flag = true
} else {
this.prolist = [...this.prolist, ...res.data.data]
}
})
},
methods: {
backtop () {
uni.pageScrollTo({
scrollTop: 0,
duration: 200
})
}
}
}
封装请求 utils/index.js
const baseUrl = "http://xxx.xxx"
export function request (options) {
const { url, method, data, header } = options
uni.showLoading({
title: '加载中'
});
return new Promise((resolve, reject) => {
uni.request({
url: baseUrl + url,
data: data || {},
method: method || 'GET',
header: header || {},
timeout: 6000, // 请求超时时间设置
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
},
complete: () => {
uni.hideLoading()
}
})
})
}
export function toast (options) {
const { title, icon, duration } = options
uni.showToast({
title: title,
icon: icon || 'none',
duration: duration || 5000
})
}
.自定义组件components/prolist/prolist
<view @click="toDetail(item.proid)" class="proitem" v-for="(item, index) of prolist" :key="index">
<view class="itemimg">
<image :src="item.proimg" mode=""></image>
</view>
<view class="iteminfo">
<view class="title">{{ item.proname }}</view>
</view>
</view>
export default {
// props: ['prolist'],
props: {
// prolist: Array
prolist: {
type: Array,
default: function () {
return []
}
}
},
data() {
return {
};
},
methods: {
toDetail (proid) {
uni.navigateTo({
url: '/pages/detail/detail?proid=' + proid
})
}
}
}
4.加入购物车
<view>
<image :src="proimg" mode=""></image>
<view>{{proname}}</view>
<view>{{price}}</view>
<button @click="addCart">加入购物车</button>
</view>
import { request, toast } from '../../utils/index.js'
export default {
data() {
return {
proname: '',
proid: '',
proimg: '',
price: 0
}
},
onLoad (options) {
// console.log(options)
const { proid } = options
request({
url: `/pro/detail?proid=${proid}`
}).then(res => {
console.log(res.data.data)
const { proname, proimg, price } = res.data.data
this.proname = proname
this.proimg = proimg
this.price = price
this.proid = proid
uni.setNavigationBarTitle({
title: proname
})
})
},
methods: {
addCart () {
// 获取本地存储的信息 token userid
try {
const token = uni.getStorageSync('token');
const userid = uni.getStorageSync('userid');
if (token && userid) { // 前端校验登陆
// 加入购物车判断用户是不是登陆状态 ---- 登陆 ---- 继续加入购物车
request({
url: '/cart/add',
method: 'POST',
data: {
token, userid, num: 1, proid: this.proid
}
}).then(res => {
if (res.data.code === '10119') { // 后端校验登陆状态
toast({title:'请先登录'})
uni.navigateTo({
url: '/pages/login/login'
})
} else {
toast({title:'加入购物车成功'})
}
})
} else {
toast({title:'请先登录'})
uni.navigateTo({
url: '/pages/login/login'
})
}
} catch (e) {
// error
}
}
}
}
5.购物车
```javascript
<template>
<view>
<view v-if="flag">
购物车空空如也,请<navigator open-type="switchTab" url="/pages/home/home">选购</navigator>
</view>
<view v-else>
<view class="cartlist">
<view class="cartitem" v-for="(item,index) of cartlist" :key="index">
<checkbox-group @change="selected(item)">
<checkbox :checked="item.flag"></checkbox>
</checkbox-group>
<image :src="item.proimg"></image>
<text>{{item.proname}}</text>
<text>¥{{item.price}}</text>
<text @click="reduce(item)">-</text>
{{item.num}}
<text @click="add(item)">+</text>
<text @click="del(item,index)">删除</text>
</view>
</view>
</view>
<checkbox-group @change="allselected">
<checkbox :checked="allchecked">全选</checkbox>
</checkbox-group>
<view>总数:{{totalNum}}</view>
<view>总价:{{totalPrice}}</view>
</view>
</template>
<script>
import {request,toast} from '../../utils/index.js'
export default {
data() {
return {
flag:true,
cartlist:[],
allchecked:true
}
},
computed:{
totalNum(){
let totalNum = 0
this.cartlist.map(item =>{
item.flag?totalNum += item.num :totalNum += 0
})
return totalNum
},
totalPrice(){
let totalPrice = 0;
this.cartlist.map(item =>{
item.flag ? totalPrice += item.num*item.price : totalPrice += 0
})
return totalPrice
}
},
onLoad() {
console.log('onLoad')
},
//不使用onLoad以及mounted是因为页面被缓存,数据更新不及时
onShow() {
console.log('onShow')
try{
let userid = uni.getStorageSync('userid')
let token = uni.getStorageSync('token')
if(userid && token){
request({
url:'/cart',
data:{
userid,
token
}
}).then(res=>{
if(res.data.code === '10019'){
toast({title:'请先登录'})
uni.navigateTo({
url:'/pages/login/login'
})
}else if(res.data.code === '10012'){
toast({title:'请先选购商品'})
this.flag = true
}else{
toast({title:'购物车列表获取成功'})
this.flag = false
//赋值之前给数据添加数据项 item.flag
res.data.data.map(item=>{
item.flag = true
})
this.cartlist = res.data.data
console.log(this.cartlist)
}
})
}else{
toast({title:'请先登录'})
uni.navigateTo({
url:'/pages/login/login'
})
}
}catch(e){
//TODO handle the exception
}
},
methods: {
allselected(){
this.allchecked = ! this.allchecked
console.log(this.allchecked)
//如果为真,修改数据的每一项的flag的值都为真,否则都为假
if(this.allchecked){
this.cartlist.map(item =>{
item.flag = true
})
}else{
this.cartlist.map(item=>{
item.flag = false
})
}
},
selected(item){
console.log('test',item)
item.flag = !item.flag
console.log(this.cartlist)
//如果单独某一项没被选中,那么全选一定不被选中
//如果单独某一项被选中了,检测其他项是否都被选中,如果都被选中了,全选被选中
if(!item.flag){
this.allchecked = false
}else{
//检测某余项是否被选中 -- 一假则假
const test = this.cartlist.every(item=>{
return item.flag === true
})
if(test){
this.allchecked = true
}else{
this.allchecked = false
}
}
},
reduce(item){
//如果当前的个数为1不操作,如果大于1减1操作
let num = item.num
if(num>1){
num -= 1
}else{
num = 1
}
let token = uni.getStorageSync('token')
request({
url:'/cart/update',
data:{
token,
cartid:item.cartid,//item包含购物车记录id
num
}
}).then(res=>{
if(res.data.code === '10019'){
toast({title:'请先登录'})
uni.navigateTo({
url:'/pages/login/login'
})
}else{
toast({title:'修改数量成功'})
item.num = 1//服务器返回成功之后 试图才更新
}
})
},
add(item){
//如果当前的个数为1不操作,如果大于1减1操作
let num = item.num
num += 1
let token = uni.getStorageSync('token')
request({
url:'/cart/update',
data:{
token,
cartid:item.cartid,//item包含购物车记录id
num
}
}).then(res=>{
if(res.data.code === '10019'){
toast({title:'请先登录'})
uni.navigateTo({
url:'/pages/login/login'
})
}else{
toast({title:'修改数量成功'})
item.num += 1//服务器返回成功之后 试图才更新
}
})
},
del(item,index){
let token = uni.getStorageSync('token')
request({
url:'/cart/delete',
data:{
token,
cartid:item.cartid
}
}).then(res=>{
if(res.data.code === '10019'){
toast({title:'请先登录'})
uni.navigateTo({
url:'/pages/login/login'
})
}else{
toast({title:'删除数据成功'})
this.cartlist.splice(index,1)//删除当前的数据
//如果点击删除,删完之后要显示没有数据了
this.cartlist.length === 0 ? this.flag = true : this.flag = false
}
})
}
}
}
</script>
<style>
.cartlist image{
width: 100px;
height: 100px;
}
</style>