小程序项目流程

1.mobx-miniprogram创建 Store 对象

2.在组件中使 用 Store 数据

 3.在页面中使用 Store 数据-方式

用component进行构造

4.在页面中使用 Store 数据-方式

 

 5.fields、actions 对象写法

 

 6.实现小程序登录功能

 

 

 7.使用数据渲染用户信息

 

8. 更新用户信息-渲染用户信息

 

 

9.收集省市区数据

思路分析:
省市区的结构使用了小程序本身自带的`picker` 件,并将组件的 `mode` 属性设置为了 `region`,从而变成省市区选择器

如果想获取省市区的数据,需要给 `picker` 选择组件添加`change` 事件来监听属性值的改变,获取选中的省市区

<!-- 省市县 -->
<view class="item">
  <text class="label">省/市/县 (区)</text>
 
  <!-- mode:给组件添加 mode 属性设置为了 region,从而变成省市区选择器 -->
  <!-- value:要求是一个数组,表示选中的省市区,默认选中每一列的第一个值 -->
  <!-- bindchange:来监听属性值的改变,也就是获取选中的省市区 -->
  <picker
    mode="region"
    value="{{ [provinceName, cityName, districtName] }}"
    bindchange="onAddressChange"
  >
    <view wx:if="{{ provinceName }}" class="region">
     {{ provinceName + ' ' + cityName + ' ' + districtName }}
    </view>
    <view wx:else class="placeholder">请填写收货人所在城市</view>
  </picker>
 
  <view class="location" bindtap="onLocation">
    <van-icon name="location-o" color="#777" />
    <text>定位</text>
  </view>
</view>

10.收集新增地址其他请求参数

思路分析:
使用简易双向数据 `model:value` 绑定来收集新增地址表单数据。

在将数据收集以后,需要组织两个数据:
1. 是否是默认地址,0 不设置为默认地址,1 设置为默认地址
2. 拼接完整的收货地址
实现步骤:
1. 使用简易双向数据绑定来收集新增地址表单数据。
3. 给按钮绑定点击事件,在事件处理函数中收集并整理数据

Page({
 
  saveAddrssForm(event) {
      
    // 解构出省市区以及 是否是默认地址
    const { provinceName, cityName, districtName, address, isDefault } = this.data
    
    // 拼接完整的地址
    const fullAddress = provinceName + cityName + districtName + address
      
    // 合并接口请求参数
    const params = {
      ...this.data,
      fullAddress,
      isDefault: isDefault ? 1 : 0
    }
 
    console.log(params)
  }
})

 11.拒绝授权的解决方案

async onLocation() {
 
  const { authSetting } = await wx.getSetting()
  console.log(authSetting)
 
  const isAuth = !!authSetting['scope.userLocation']
 
  if (!isAuth) {
 
    const modalRes = await wx.modal({
      title: '授权提示',
      content: '需要需要您的地理位置信息,请确认授权'
    })
 
    // 如果用户点击了取消,说明用户拒绝了授权,给用户提示
    if (!modalRes) return wx.toast({ title: '您拒绝了授权' })
 
    // 如果用户点击了确定,调用 wx.openSetting 打开微信客户端小程序授权页面
    // 并返回授权以后的结果
    const { authSetting } = await wx.openSetting()
 
    // 如果用户没有更新授权信息,提示没有更新授权
    if (!authSetting['scope.userLocation'])
      return wx.toast({ title: '授权失败!' })
 
    try {
      const locationRes = await wx.getLocation()
      // 打印地理位置信息
      console.log(locationRes)
    } catch (err) {
      console.log(err)
    }
  } else {
    try {
 
      const locationRes = await wx.getLocation()
      console.log(locationRes)
    } catch (error) {
      wx.toast({ title: '您拒绝授权获取地址位置' })
    }
  }
}

12. 开启腾讯位置服务

13.async-validator 基本使用 

1.安装 async-validator

npm i async-validator

2.开发者工具,点击构建 npm,对 async-validator 进行构建

3.在 js 文件中导入 async-validator

// 1️⃣ 引入 async-validator,async-validator 提供了一个构造函数
import Schema from 'async-validator'
 
Page({
  // 2️⃣定义需要验证的数据
  data: {
    name: '你好'
  },
 
  // 验证数据
  onValidate() {
    // 3️⃣创建表单验证规则
    const rules = {
      // key 建议和 需要验证的数据字段名字保持一致
      name: [
        // required 是否是必填项
        { required: true, message: 'name 不能为空' },
 
        // type 数据的类型
        // message 如果验证失败,提示的错误内容
        { type: 'string', message: 'name 不是字符串' },
 
        // min 最少位数,max 最大位数
        { min: 2, max: 5, message: '名字最少 2 个字,最多 5 个字' }
 
        // 正则表达式
        // { pattern: '', message: '' }
 
        // 自定义验证规则
        // { validator: () => {} }
      ]
    }
 
    // 4️⃣创建表单验证实例
    // 在创建实例时需要传入验证规则
    const validator = new Schema(rules)
 
    // 5️⃣ 调用 validate 实例方法对数据进行验证
    // validate 方法接收一个对象作为参数,对象是需要验证的数据
    // 注意:validate 方法只会验证和验证规则同名的属性
    validator.validate(this.data, (errors, fields) => {
   // 如果验证失败,errors 是所有错误的数组
      // 如果验证成功,errors 是 null
      console.log(errors)
 
      // fields 是需要验证的属性,属性值是数组,数组中包含错误信息
      console.log(fields)
 
      if (errors) {
        console.log('验证没有通过')
        console.log(errors)
        return
      }
 
      console.log('验证通过')
    })
  }
})

14. 封装商品模块接口 API

import http from '../utils/http'
 
/**
 * @description 获取商品列表
 * @return Promise
 */
export const reqGoodsList = ({ limit, page, ...reset }) => {
  return http.get(`/mall-api/goods/list/${page}/${limit}`, reset)
}
 
/**
 * @description 获取商品详情
 * @param {*} goodsId 商品Id
 * @returns Promise
 */
export const reqGoodsInfo = (goodsId) => {
  return http.get(`/mall-api/goods/${goodsId}`)
}

15. 商品列表-获取商品列表数据并渲染


思路分析:
在准备商品列表的请求参数以后,

在页面调用 `API` 函数获取商品列表的数据,在获取到数据以后,使用后端返回的数据对页面进行渲染。

实现步骤:
1. 在 `/pages/goods/list/list.js` 中导入封装好的获取商品列表的 `API` 函数
2. 页面数据在页面加载的时候进行调用,在 `onLoad` 钩子函数中调用  `reqGoodsList` 方法
3. 在获取到数据以后,使用后端返回的数据对页面进行渲染

 /modules/goodsModules/pages/list/list.js`
 import { reqGoodsList } from '../../../../../api/good'
Page({
  // 页面的初始数据
  data: {
    goodsList: [], // 商品列表数据
     total: 0, // 数据总条数
    isFinish: false, // 判断数据是否加载完毕
    // 接口请求参数
    requestData: {
      page: 1, // 页码
      limit: 10, // 每页请求多少条数据
      category1Id: '', // 一级分类 id
      category2Id: '' // 二级分类 id
    }
  },
   // 获取商品列表的数据
   async getGoodsList() {
     // 调用 API 获取数据
     const { data } = await reqGoodsList(this.data.requestData)
 
     // 将返回的数据赋值给 data 中的变量
     this.setData({
       goodsList: data.records,
       total: data.total
     })
   },
  // 生命周期函数--监听页面加载
  onLoad(options) {
    // 接收传递的参数
    Object.assign(this.data.requestData, options)
    // 获取商品列表的数据
    this.getGoodsList()
  }
})

16.商品列表-实现上拉加载

/modules/goodsModule/pages/list/list.js`
 
import { reqGoodsList } from '../../../api/goods'
 
Page({
 
  // coding...
 
  // 获取商品列表的数据
  async getGoodsList() {
    // 调用 API 获取数据
    const { data } = await reqGoodsList(this.data.params)
 
    // 将返回的数据赋值给 data 中的变量
    this.setData({
       goodsList: [...this.data.goodsList, ...data.records],
      total: data.total
    })
  },
 
  // coding...
 
  // 监听页面的上拉操作
   onReachBottom() {
     let { page } = this.data.requestData
 
     // 页码 + 1
     this.setData({
       requestData: { ...this.data.requestData, page: page + 1 }
     })
 
     // 重新发送请求
     this.getGoodsList()
   }
 
})

17. 商品列表-实现下拉刷新

1. 在`页面.json` 中开启允许下拉,同时可以配置 窗口、loading 样式等 

2. 在`页面.js` 中定义 `onPullDownRefresh` 事件监听用户下拉刷新

/modules/goodsModule/pages/list/list.json`
{
  "usingComponents": {
    "goods-card": "/components/goods-card/goods-card"
  },
 
  "navigationBarTitleText": "商品列表",
  "enablePullDownRefresh": true,
  "backgroundColor": "#f7f4f8",
  "backgroundTextStyle": "dark"
}
/modules/goodsModule/pages/list/list.js`
 
// 监听页面的下拉刷新
onPullDownRefresh() {
  // 将数据进行重置
  this.setData({
    goodsList: [],
    total: 0,
    isFinish: false,
    requestData: { ...this.data.requestData, page: 1 }
  })
 
  // 重新获取列表数据
  this.getGoodsList()

}

 18封装结算支付的接口 API

 /api/orderpay.js`
import http from '@/utils/http'
 
/**
 * @description 获取订单详情
 * @returns Promise
 */
export const reqOrderInfo = () => {
  return http.get('/order/trade')
}
 
/**
 * @description 获取订单列表
 * @param {*} page 页码
 * @param {*} limit 每页展示的条数
 * @returns Promise
 */
export const reqOrderList = (page, limit) => {
  return http.get(`/order/order/${page}/${limit}`)
}
 
/**
 * @description 获取订单收货地址
 * @returns Promise
 */
export const reqOrderAddress = () => {
  return http.get('/userAddress/getOrderAddress')
}
 
/**
 * @description 获取立即购买商品的详情信息
 * @param { Object } params { goodsId: 商品 Id,  blessing:祝福语 }
 * @returns Promise
 */
export const reqBuyNowGoods = ({ goodsId, ...data }) => {
  return http.get(`/order/buy/${goodsId}`, data)
}
 
/**
 * @description 提交订单
 * @returns Promise
 */
export const reqSubmitOrder = () => {
  return http.post('/order/submitOrder')
}
 
/**
 * @description 获取微信预支付信息
 * @param {*} orderNo 订单 ID
 * @returns Promise
 */
export const reqPreBuyInfo = (orderNo) => {
  return http.get(`/webChat/createJsapi/${orderNo}`)
}
 
/**
 * @description 微信支付状态查询
 * @param {*} orderNo
 * @returns Promise
 */
export const reqPayStatus = (orderNo) => {
  return http.get(`/webChat/queryPayStatus/${orderNo}`)
}

19. 商品结算-更新收货地址功能


思路分析:
当用户需要更改收货地址时,我们需要跳转到收货地址页面,重新选择收货地址
当用户点击了某个地址以后,我们需要将该地址显示到商品结算页面中。
更新收货地址功能,采用 `getApp()` 全局共享数据的方式来实现。

实现步骤:
在 `app.js` 中定义全局共享的数据 `globalData.address`
点击箭头,携带参数跳转到收货地址页面,标识是从订单结算页面进入
在选择收货地址成功以后,将数据存储到 `globalData.address`中,然后返回到订单结算页面。
在订单结算页面判断 `globalData.address` 是否存在收货地址数据,如果存在则渲染

app.js`
App({
   // 定义全局共享的数据
   globalData: {
    address: {}
  }
})


/pages/address/list/index.html`
<!-- 每一个收货地址 -->
<view
  class="info"
   bindtap="changeAddress"
   data-id="{{ item.id }}"
>
  <view class="user-info">
    <text>{{ item.name }}</text>
    <text>{{ item.phone }}</text>
    <text wx:if="{{ item.isDefault === 1 }}" class="default-tag">默认</text>
  </view>
 
  <view class="address-info"> {{ item.fullAddress }} </view>
</view>
 

20 节流阀

如果事件被频繁触发,节流能够减少事件触发的频率,因此,节流是有选择性地执行一部分事件!

1.定义节流阀
代码如下(示例):

// 步骤1. 定义节流阀
    var timer = null //false

2.绑定 mousemove 事件
        // 2. 绑定 mousemove 事件
                $(document).on('mousemove', function (e) {
                    // 步骤3:判断节流阀是否为空,如果不为空,则证明距离上次执行间隔不足16毫秒
                    if (timer) {
                        return
                    }
                    // 3. 设置图片的位置
                    // 步骤2:开启延时器 2.当设置了鼠标跟随效果后,清空 timer 节流阀,方便下次开启延时器
                    timer = setTimeout(function () {
                        $(angel).css('top', e.pageY + 'px').css('left', e.pageX + 'px')
                        console.log('ok')
                        timer = null
                    }, 16)
                    
                })


3. 判断节流阀是否为空,如果不为空,说明距离上一次执行时间还没有设定的时间。则返回。
            if (timer) {
                return
            }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值