推荐使用hbuilderX

创建项目和运行项目


全局配置

pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、
窗口样式、原生的导航栏、底部的原生tabbar 等。
它类似微信小程序中app.json的页面管理部分。
注意定位权限申请等原属于app.json的内容,在uni-app中是在manifest中配置。
属性 类型 必填 描述 平台兼容
globalStyle Object 设置默认页面的窗口表现
pages Object Array 设置页面路径及窗口表现
easycom Object 组件自动引入规则 2.5.0+
tabBar Object 设置底部 tab 的表现
condition Object 启动模式配置
subPackages Object Array 分包加载配置
preloadRule Object 分包预下载规则 微信小程序
workers String Worker 代码放置的目录 微信小程序

pages.json里面的代码放在下面
//pages数组中第一项表示应用启动页,
参考:pages配置
既然pages中有对应的路径,在目录中找到pages在里面新建页面,对应下面的
tabBar为底部导航,其中有list属性,最少为2个,最多为5个,

其中iconPath和selectedIconPath只支持本地图片

{"pages": [{"path" : "pages/home/home","style" : {"navigationBarTitleText":"七毛商城-首页","enablePullDownRefresh":true}},{"path" : "pages/list/list","style" : {"navigationBarTitleText":"分类"}},{"path" : "pages/cart/cart","style" : {"navigationBarTitleText":"购物车"}},{"path" : "pages/setting/setting","style" : {"navigationBarTitleText":"设置"}},{"path" : "components/prolist/prolist","style" : {}},{"path" : "pages/detail/detail","style" : {}},{"path" : "pages/login/login","style" : {}},{"path" : "pages/reg/reg","style" : {}}],"globalStyle": {"navigationBarTextStyle": "white","navigationBarTitleText": "uni-app","navigationBarBackgroundColor": "#ff6666","backgroundColor": "#F8F8F8"},"tabBar":{"color":"#000","selectedColor":"#f66","backgroundColor":"#fff","list":[{"pagePath":"pages/home/home","text":"首页","iconPath":"static/assets/home.png","selectedIconPath":"static/assets/home_sel.png"},{"pagePath":"pages/list/list","text":"列表","iconPath":"static/assets/type.png","selectedIconPath":"static/assets/type_sel.png"},{"pagePath":"pages/cart/cart","text":"购物车","iconPath":"static/assets/cart.png","selectedIconPath":"static/assets/cart_sel.png"},{"pagePath":"pages/setting/setting","text":"设置","iconPath":"static/assets/setting.png","selectedIconPath":"static/assets/setting_sel.png"}]}
}

以上为页面基础配置,下面为请求封装,找到utils目录,新建js命名为index.js (随意)
所谓的封装就是对外暴露请求接口,代码如下

const baseUrl = '自己的接口文档基地址'
export function request(options){
// 自己想一下请求需要什么/例如axiosconst { url,data,method,header } = options//数据没有请求过来之前用加载条uni.showLoading({title:'加载中..'})//返回一个Promise对象,resolve为成功回调,reject为失败回调return new Promise((resolve,reject) => {uni.request({url:baseUrl+url,  //基地址拼上调用接口传递过来的urldata:data || {},  //data或者为空,有的时候不需要传递数据method:method || "GET",  // 请求接口默认为GET请求header:header || {}, //请求头   是否需要timeout:6000,  //请求超时时间success(res) {resolve(res)   // 成功回调},fail(err) {reject(err)   //失败回调函数},complete() {uni.hideLoading()  //数据请求完成后关闭加载条}})})
}
以上便是一个uni-app的封装,前几期的博客中页讲到过

//不知道你们会不会想到封装的好处,为什么要封装
最直观的感受

1,提高代码的复用性,减少项目体积,
在做项目的时候超过两个+的地方就可以考虑一下代码封装
调用者不需要关注代码是如何封装的,只需要调用暴露的接口即可,即过程是不可见,

以下是一个提示框的封装,过程不多说

export function toast (options) {const { title,icon,duration } = optionsuni.showToast({title:title,icon:icon || 'none',duration:duration || 5000})
}

以上为代码封装的问题,那么问题来了,当你展示首页的时候,是在什么地方调用接口,ok,下面是uni-app的生命周期

小程序生命周期

1应用生命周期

函数名 说明
onLaunch uni-app 初始化完成时触发(全局只触发一次)
onShow uni-app 启动,或从后台进入前台显示
onHide uni-app 从前台进入后台
onError uni-app 报错时触发
onUniNViewMessage nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯

== 注意以上应用生命周期仅可在App.vue中监听,在其它页面监听无效==

2页面生命周期

函数名 说明 平台差异说明 最低版本
onLoad 监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参),参考示例
onShow 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
onHide 监听页面隐藏
onUnload 监听页面卸载
onResize 监听窗口尺寸变化 App、微信小程序
onPullDownRefresh 监听用户下拉动作,一般用于下拉刷新,参考示例
onReachBottom 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项
onTabItemTap 点击 tab 时触发,参数为Object,具体见下方注意事项 微信小程序、支付宝小程序、百度小程序、H5、App(自定义组件模式)
onShareAppMessage 用户点击右上角分享 微信小程序、百度小程序、头条小程序、支付宝小程序
onPageScroll 监听页面滚动,参数为Object nvue暂不支持
onNavigationBarButtonTap 监听原生标题栏按钮点击事件,参数为Object App、H5
onBackPress 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解 app、H5、支付宝小程序
onNavigationBarSearchInputChanged 监听原生标题栏搜索输入框输入内容变化事件 App、H5 1.6.0
onNavigationBarSearchInputConfirmed 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。 App、H5 1.6.0
onNavigationBarSearchInputClicked 监听原生标题栏搜索输入框点击事件 App、H5 1.6.0

**3组件生命周期**

函数名 说明 平台差异说明 最低版本
beforeCreate 在实例初始化之后被调用。详见
created 在实例创建完成后被立即调用。详见
beforeMount 在挂载开始之前被调用。详见
mounted 挂载到实例上去之后调用。详见 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTickVue官方文档
beforeUpdate 数据更新时调用,发生在虚拟 DOM 打补丁之前。详见 仅H5平台支持
updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。详见 仅H5平台支持
beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。详见
destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。详见

是不是不知道组件生命周期的区别、自己以前总结的,大白话

beforeCreate(创建前)
在实例初始化之后,数据观测和事件配置之前被调用,此时组建的选项对象还未创建,el和data还没有初始化,因此无法访问methods,data,computed等上的方法和数据
created(创建后)
实例已经创建完成之后被调用,在这一步,实例已完成以下配置,数据观测,属性和方法的运算,watch/event事件回调,完成了data数据的初始化,el没有,但是,挂载阶段还没开始,$el属性不可见,在这个阶段你可以调用methods中的方法,改变data中的数据,注意点是这个周期是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合这个方法请求
beforeMount
#app还没挂载到el上
变量还没被解析
挂载开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成编译模版,把data里面的数据和模版生成html,完成了el和data初始化,注意此时还没有挂载html到页面上
mounted
挂载完成,也就是模板中的html渲染到页面中,此时一般可以做一些ajax操作,mounted只会执行一次
beforeUpdate(更新前)
视图dom不同,
document.getElementById('tit').innerHTML
在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步的更改状态,不会触发附加的重渲染过程
updated(更新后)
在由于数据更改导致地虚拟DOM重新渲染和调用,打补丁只会调用,调用时,组建DOM已经更新,所以可以执行依赖于DOM地操作,然后再大多数情况下,应该避免再此期间更改状态,因为可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用
beforeDestroy(销毁前)
在实例销毁之前调用,实例仍然完全可用
1,这一步还可以用this来获取实例
2一般在这一步做一些重置地操作,比如清除掉组件中的定时器和监听的dom事件
destroyed(销毁后)
在实例销毁之后调用,调用后,所有地事件监听器都会被移除,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

以上为小程序(uni-app)生命周期 ,有了生命周期,是不是开始写页面,以首页为例

wxml代码
<template><view><swiper class="swiper" autoplay><swiper-item v-for="(item,i) in bannerlist" :key="i" class="swiperchild"><image class="img" mode="aspectFill" :src="item.coverImg"></image></swiper-item></swiper><prolist  :prolist="prolist" /> // 为商品列表组件,只需传值把需要的值传过去即可(父传子)<view class="gotop" v-if="flag" @click="backtop"><view class="top">↑</view></view>   </view>
</template>
import prolist from '../../components/prolist/prolist'  // 引入组件import { request,toast } from '../../utils/index.js' //引入封装的请求export default {data() {return {prolist:[],  //当前商品的数据bannerlist:[],page:1,flag:false};},components:{prolist},methods:{//返回顶部,点击调用API即可backtop(){uni.pageScrollTo({scrollTop:0,duration:200})}},//异步请求数据async mounted() {const res = await request({url:'/api/v1/products'})console.log(res.data.products)this.prolist = res.data.productsthis.bannerlist = res.data.products},//返回顶部按钮在滚动条距离顶部200的时候显示,小于200隐藏onPageScroll (options) {const { scrollTop } = optionsif(scrollTop>=200){this.flag = true}else{this.flag = false}},//触底事件,用于加载更多,页码加1,再次请求数据即可async onReachBottom () {console.log('触底了')this.page++if(this.page>=19){toast({title:'暂无更多数据',icon:'none'})}else{const res = await request({url:'/api/v1/products',data:{page:this.page}})//扩展运算符的使用,把当前已请求的数据和刚请求的数据放在一个数据里面,赋值即可this.prolist = [...this.prolist,...res.data.products]}}}

以上为轮播图和商品列表的数据,只需要在子组件中调用即可,
子组件数据 路径 components/prolist/prolist.vue
父组件传递的数据在子组件中如何拿到

<view class="all"><view class="prolist"  v-for="(item,i) in prolist" @click="godetail(item._id)":key="i"><image class="img" :src="item.coverImg"></image><text class="name">{{item.name}}</text><view class="bottom"><text class="desc">{{item.descriptions}}</text><text class="price">{{item.price | glq}}</text></view></view></view>
export default {
//通过props中prollist直接获取props:{prolist:{type:Array, //生命传值的类型default:function () {return []}}},data() {return {}},mounted() {console.log(props)},methods: {//跳转详情godetail(e){if(e){uni.navigateTo({url:'/pages/detail/detail?id='+e,animationType:"slide-in-top",animationDuration:200,})}}},filters:{glq:function(data){return '¥'+data}}}

在商品详情中同样是调用接口,展示数据,在详情页面中加购等需要判断是否登录,本地是否存在token等字段

详情js
gocart () {console.log(this.value)let token = uni.getStorageSync('token')if(token){request({url:'/api/v1/shop_carts',method:"POST",header:{"authorization":"Bearer "+ token  //header头部信息传递token},data:{product:this.detail._id,quantity:this.value}}).then(res=>{if(res.data.code == 'success'){toast({title:res.data.message})}else{}})}else{toast({title:'请去登录'})//如果本地不存在token,说明登录过期或者没登陆,直接跳转到login页面uni.navigateTo({url:'/pages/login/login'})}}

以下为login页面

wxml页面
<view><input type="text" class="ipt"@input="Oninput"placeholder="请输入手机号"v-model="tel"/><textv-if="isshow"/*动态绑定class名如果长度为11为class为error反之success,css没写,自己写上即可*/:class="tel.length !== 11 ? 'error' : 'success'">{{teltip}}</text><inputtype="password" class="ipt"@input="Oninput1"placeholder="请输入密码"v-model="pwd"/><textv-if="isshow1":class="pwd.length < 6 ? 'error' : 'success'">{{pwdtip}}</text>/*disable属性动态的去判断为true还是false,进而去带来更好的用户体验type属性满足条件为warn,不满足为default   */<button class="btn":disabled="tel.length!==11 || pwd.length < 6":type="tel.length===11&&pwd.length>5?'warn':'default'"@click="login">点击登录</button></view>

文中的两个text为提示信息,基本逻辑如下

js
import { request,toast } from '../../utils/index.js'export default {data() {return {tel:'',pwd:'',isshow:false,isshow1:false};},methods:{Oninput (){if(this.tel.length >=1){this.isshow = true}else{this.isshow = false}},Oninput1 () {/*在tel输入框内容发生改变的时候触发当前事件,、如果长度大于1就说明输入框中已经存在值,让提示框显示去判断验证是否满足这个时候就应该去判断当前输入框的值是否满足手机号码,这个地方手机号码验证就不写了*/if(this.pwd.length >=1){this.isshow1 = true}else{this.isshow1 = false}},//登录操作login () {//再次判断,if(this.tel.length === 11 && this.pwd.length >= 6){request({url:'/api/v1/auth/login',method:"POST",data:{userName:this.tel,password:this.pwd}}).then(res=>{console.log(res)if(res.data.code == 'success'){toast({title:'登陆成功'})/*存储token,返回上一级,*/try{uni.setStorageSync('token',res.data.token)uni.navigateBack()}catch(e){//TODO handle the exception}}else{toast({title:res.data.message})}})}else{toast({title:'格式不正确',icon:'none'})}}},computed:{teltip () {if(this.tel.length !== 11){return '手机号码格式不正确'}else{return '手机号码格式正确'}},pwdtip () {if(this.pwd.length >= 6){return '密码强度为高'}else{return '密码强度为低'}}}}

既然已经加入购物车了,那就展示购物车中的数据呗
//注意的是跳转下面tabBar任何一个,都需要加上open-type=“switchTab”
更多请去了解uni-app路由
购物车中的问题无非就是全选反选,根据全选反选计算总价删除商品

<view><navigatoropen-type="switchTab"  class="noned" v-if="flag"url="../home/home">购物车为空去购买</navigator><view  class="allcartlist"><view class="everypro" v-for="(item,i) in cartlist" :key="i"><checkbox-group name="" @change="Onchange(item)"><checkbox :checked="item.product.onSale" /></checkbox-group><view class="proimg"><image class="img" :src="item.product.coverImg" mode=""></image></view><view class="right"><view class="name">{{item.product.name}}</view><view class="desc">{{item.product.descriptions}}</view><view class="bottomnum"><text class="price">{{item.product.price | glq}}</text><text class="quan">×{{item.quantity}}</text></view></view></view></view><view class="tipro"><view class="ti"><checkbox-group @change="allSelected"><checkbox :checked="isAllselected" /></checkbox-group><view class="app">总价:{{allprice}}</view><view class="tibtn">提交订单</view></view></view></view>
//cart/js
import { request,toast } from '../../utils/index.js'export default {data() {return {flag:false,cartlist:[],isAllselected:false};},//onShow生命周期是当页面从后台切换到前台的时候触发onShow() {let token = uni.getStorageSync('token')if(token){request({url:'/api/v1/shop_carts',header:{"authorization":"Bearer "+ token}}).then(res=>{//再次做个判断如果当前购物车中没有商品的话,展示去加购,跳转首页即可if(res.data == []){this.flag = true}else{this.flag = falseconsole.log(res.data)//赋值,v-for遍历展示数据this.cartlist = res.data}})}else{toast({title:'请登录'})uni.navigateTo({url:'/pages/login/login'})}},methods:{//全选反选操作Onchange (e) {e.product.onSale = !e.product.onSale// 如何有一项商品未被选中 ,则全选框不被选中//如果单独某一项被选中,看看其他商品是否被全部选中console.log(e.product.onSale)// 默认为false,如果当前购物车中的商品有意向没被选中的话,全选不被选中//反之,拿到当前购物车中的每一项数据,修改onSale属性为trueif(!e.product.onSale) { this.isAllselected = false}else{//设置每一项都为trueconst allChecked = this.cartlist.every(item=>{return item.product.onSale === true})// 下面判断allChecked是否为true即可,//如果为true则全被选中,让全选为true,如果为false,让全选为falseif(allChecked){this.isAllselected = true}else{this.isAllselected = false}}},/* 点击全选,如果全选被选中,则遍历当前购物车中每一项,设置onSale为true,就是每一项都被选中*/allSelected () {this.isAllselected = !this.isAllselected// console.log(this.isAllselected)if(this.isAllselected){this.cartlist.map(item=>{item.product.onSale = true})}else{this.cartlist.map(item=>{item.product.onSale = false})}}},filters:{glq:function(data){return '¥'+data}},computed:{//计算总价遍历选中每一项数据依次累加总价 = 当前选中的商品*价格,选中几项,累加几项即可,最后返回总价,展示页面allprice(){let allprice = 0;this.cartlist.map(res=>{// 如果被选中总价为当前购物车中每个商品的数量*每个商品的价格// 否则res.product.onSale?allprice+=res.quantity * res.product.price:allprice+=0})return allprice}}}

//以上为uni-app中轮播图,商品列表,跳详情,加购,购物车中展示数据,全选反选,登录,css均未写。

特殊时期,在家就不要乱走动,逆战中更要不断地磨练自我,争取在自己需要的时候绽放出光芒。下面带着大家写一套电商类小程序的主要流程,个人练习,不喜勿喷

使用uni-app完成电商类小程序流程相关推荐

  1. 电商类小程序开发审核及其他注意事项

    一.电商类小程序需要什么资质? 1.总的来说任何微信小程序所涉及的服务不超过5类,在单月内允许有三次的修改.资质方面的要求很严格,如果该小程序具有A类目的资质,但却具有B类目的服务,那么这样跨界的情况 ...

  2. 外卖+电商类小程序——微信小程序心得分享

    这个一个看起来像电商,实际业务接近外卖的一个小程序,不多说先上图 这是几个主要界面的样子,我会在之后分享其中的一些技术难点,有问题也可以留言哦 体验二维码

  3. 0403互联网新闻 | 哔哩哔哩上线电商类小程序;翼鸥教育和腾讯云联合发布ClassIn Cloud...

    戳戳戳戳一下"好看",你最好看

  4. 新电商模式——小程序+电商

    小程序的出现,为无数品牌和个人提供了新的服务消费者的方式,为新形势下的小程序+电商发展注入更强的力量. 从小程序上线到如今的深入发展,小程序的行业分布正趋于均衡化发展.而去年以拼多多为代表的" ...

  5. 电商微信小程序的开发,项目及功能描述

    开发类型:电商类小程序 项目名称:e家装猫商城 项目目标:本项目旨在开发一套基于微信小程序的线上电商平台,它将实现用户通过微信移动端选购自己需要的商品,商家后台获取用户订单信息来完成商品配送.核销的流 ...

  6. Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战

    Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战 说明:Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战,优惠券是一种常见的促销方式,在规定的周期内购买对应商品类型和额度的商品 ...

  7. 来客推仿拼多多电商商城小程序源码

    简介: 一款来客推内核仿拼多多电商商城小程序源码,APP+钱包+开源版. 安装步骤: 环境要求 环境配置正常,最好是PHP5.6+Mysql5.5 win下面可以使用phpstudy集成环境部署安装 ...

  8. 电商商城小程序开发|电商商城小程序怎么玩?

    电商商城其实我们都比较熟悉,比如淘宝.京东.拼多多之类的,都是电商商城,我们如果也想做类似的拼团,其实比较推荐大家去做小程序. 因为我们没有淘宝他们那么大的用户基础,所以我们做APP是不会有什么客户的 ...

  9. Axure电商服务小程序交互原型模板、电商小程序、拼团特惠、积分兑换、LBS电商小程序、活动、订单、会员、购物车、签到、钱包充值、拼团拼单、优惠券、电商原型、rp源文件、Axure原型、移动端电商系统

    Axure电商服务小程序交互原型模板.电商小程序.拼团特惠.积分兑换.LBS电商小程序.活动.订单.会员.购物车.签到.钱包充值.拼团拼单.优惠券.电商原型.rp源文件.Axure原型.移动端电商系统 ...

最新文章

  1. 最新Java中Date类型详解
  2. 以色列对话国际农民丰收节贸易会-万祥军:谋定无中生有
  3. java set 取第一个_set集合取第一个元素的几种方法
  4. 用Python实现二叉树,完全二叉树和满二叉树
  5. Codeup墓地-问题 A: 还是畅通工程
  6. oracle环境变量怎么配,oracle环境变量配置-Oracle
  7. vue ---- vue 的入门程序
  8. 卡尔曼滤波器及代码实现
  9. vue中 localStorage的使用方法(详解)
  10. RSA js 加密解密
  11. 人类简史--经典语句摘录
  12. Shapely的安装
  13. Xmind教程:思维导图原来这么简单实用!
  14. 解析解【闭式解(closed-form solution)】和数值解
  15. 电脑自动关机是什么原因?为什么电脑会自动关机?轻松弄懂
  16. windows 指纹识别不可用
  17. 7-2 查找书籍 (20 分)
  18. 双屏Android NDS模拟器,Android DraStic(NDS模拟器)r2.5.2.1a 内购版+金手指
  19. 01|读研这三年,你亏么?(研一篇)
  20. Matlab初学者入门

热门文章

  1. 某站视频python抓取: m3u8转mp4
  2. cocos creator 知识点,切换场景
  3. 如何利用虚拟主机搭建网站
  4. 关于计算机知识的手抄报图片大全,网络安全知识手抄报图片
  5. 统计各个部门的工资记录数
  6. Python 的元类设计起源自哪里?
  7. PCL教程-点云配准之成对逐步配准(两两配准)
  8. JVM——垃圾收集器
  9. 前端面试题目搜集——理论知识篇
  10. 在Geany里配置python的方法