小程序的使用

news2024/12/27 12:05:47

微信小程序开发 外部链接别人的总结查看(超详细保姆式教程)

基础语法

1.数据绑定

1.1 初始化数据

  • 页面.js的data选项中
    Page({
      data: {
        motto: 'Hello World',
        id:18
      }
    })
    
  • 使用数据
  1. 单项数据流:Mustache 语法
    a)模板结构中使用双大括号 {{data}}

       	<text id="{{id}}">{{motto}}</text>
       	<input type="text" value="{{motto}}"/>
    
  2. 双向数据绑定

  • a)表单项使用 model:value = ‘{{data}}’

    <input type="text" model:value="{{motto}}"/>
    
  • b)坑!!!

    • i.双向数据绑定数据变量名不能是简单的a, b, c,否则无法实现
    • ii.双向数据绑定不能绑定data路径,如: a.b
      <input type="text" model:value="{{a}}"/>
      

1.2 修改数据

  1. this.setData({message: ‘修改之后的数据’}, callback)
  2. 特点:
  • a)同步修改: this.data值被同步修改
  • b)异步更新: 异步将setData 函数用于将数据从逻辑层发送到视图层(异步)
  1. 注意点:
  • a)直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
  • b)单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
    Page({
      data: {
        motto: 'Hello World',
        a: 'abc'
      },
      onLoad(){
        this.setData({
          motto: 'change data'
        })
      }
    })
    

2.事件绑定

2.1 事件分类

    1. 冒泡事件
    • a) 定义:冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
    • b) 冒泡事件列表:冒泡官网地址
  • 2)非冒泡事件

    • a) 定义:当一个组件上的事件被触发后,该事件不会向父节点传递。
    • b) 非冒泡事件:表单事件和自定义事件通常是非冒泡事件
      非冒泡事件官网地址

2.2 绑定事件

  1. bind绑定:事件绑定不会阻止冒泡事件向上冒泡

    <view bindtap="handleTap" class='start_container'>
      <text class='start'>开启小程序之旅</text>
    </view>
    
  2. catch 绑定: 事件绑定可以阻止冒泡事件向上冒泡

    <view catchtap="handleTap" class='start_container'>
      <text class='start'>开启小程序之旅</text>
    </view>
    

2.3 向事件对象传参

  1. 语法: data-key=value
 <button catchtap="changeName" data-name='{{firstName}}'>点击修改名称</button>
  1. 获取: event.target.dataset.key || event.currentTarget.dataset.key

  2. Event.target 和 event.currentTarget的区别
    a.) Event.target是触发事件的对象,但不一样是绑定事件的对象,如: 事件委托,冒泡
    b) currentTarget触发事件的对象一定是绑定事件的对象, 没有事件委托

3.列表渲染

3.1 语法说明

  1. wx:for="{{arr}}"
  2. wx:key="唯一值或者index"
  <view wx:for="{{ list }}" wx:key="id">
    <view>{{ index }} --  {{ item.content }}</view> 
  </view>

3.2 wx:key

  1. 同Vue一样,循环遍历的时候需要为每一个item添加唯一的key值

  2. Key值分类:

    a)Item本身就是唯一值,如: number,string
    b)*this,代表item本身,同样需要item自身是唯一的,如;number,string
    c)Item的唯一属性,如: id; 官网没有明确语法说明,只能在示例代码中找到

  3. 注意事项:

    a)Wx:key后跟的变量不需要使用插值语法,即不需要使用大括号包裹
    b)Item中如果有唯一值属性,可以直接使用
    如:item = {id: 1}, 则wx:key = 'id'

3.3 重新命名

1.默认的个体: item
2.默认的下标: index
3.自定义个体变量名称: wx:for-item=’myItem’
4.自定义下标变量名称: wx:for-index=’myIndex’

<view wx:for="{{ list }}" wx:key="id" wx:for-item="myItem" wx:for-index="myIndex">
  <view>{{ myIndex}} -- {{myItem.content}}</view>
</view>

4. 条件渲染

4.1 语法说明

  1. wx:if=’条件’
  2. wx:elif=’条件’
  3. wx:else
    <view>
      <!-- 条件渲染 -->
      <view wx:if="{{ isShow }}">表白成功</view>
      <view wx:else>表白失败</view>
      <!-- <view wx:else="{{ !isShow }}">表白失败</view> -->
      <view>-----------------</view>
      <view wx:if="{{ sex === 0 }}"></view>
      <view wx:elif="{{ sex === 1 }}"></view>
      <view wx:else>未知</view>
    </view>
    

4.2 wx:if VS hidden 区别

1.hidden用法: <view hidden='{{true}}' ></view>
2.wx:if 等同于 v-if, 条件为false的时候不加载,条件切换的时候决定元素销毁或者重新加载渲染
3.hidden 等同于 v-show, 始终加载元素, 条件切换的时候决定元素的显示和隐藏

5. 模板使用

5.1 定义模板

在这里插入图片描述

5.2 引入模板

  1. 引入模板结构:
  2. 引入模板样式: @Import ‘模板样式路径’

5.3 使用模板

在这里插入图片描述

5.4 向模板导入数据并使用数据

在这里插入图片描述

6.生命周期

官方图示:官方图

在这里插入图片描述

生命周期函数执行时机执行次数特点说明
onLoad页面加载时触发1可以通过参数获取打开当前页面路径中的参数
onShow页面显示/切入前台时触发多次如页面没有被销毁,会重复多次显示隐藏,可以在此发送请求获取最新数据
onReady页面初始化渲染完成时触发1可以同UI界面进行交互
onHide页面隐藏/切入后台时触发多次wx.navigateTo 或底部 tab 切换到其他页面,小程序切入后台等
onUnload页面卸载时触发1wx.redirectTo或wx.navigateBack到其他页面时

个人见解

官网生命周期图示是错误的;错误部分:标注onLoad及onShow执行的位置不对

参考:小程序启动执行的所有流程

参考地址:

https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips/start_process.html

7.小程序适配方案: rpx (responsive pixel响应式像素单位)

小程序适配单位: rpx

规定任何屏幕下宽度为750rpx

小程序会根据屏幕的宽度不同自动计算rpx值的大小

Iphone6下: 1rpx = 1物理像素 = 0.5px

在这里插入图片描述

8. 小程序API

8.1 API使用说明

  1. 小程序提供了很多实用的方法供开发者使用
  2. 小程序全局对象是: wx
  3. 所有的API都保存在wx对象中

8.2 常用API

  1. 界面交互
    a)显示消息提示框: wx.showToast()
    b)显示消息加载框: wx.showLoading()
    c)关闭消息提示框: wx.hideToast()
    d)关闭消息加载框: wx.hideLoading()
    e)提示消息警告框:wx.showModal()
  2. 路由跳转
    a)wx.navigateTo() 保留当前页面,跳转到应用内的某个页面
    b)wx.redirectTo() 关闭当前页面,跳转到应用内的某个页面
    c)wx.switchTab() 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
  3. 网络请求
    a)wx.request()
  4. 本地存储
    a)wx.setStorage() 异步设置
    b)wx.setStorageSync() 同步设置
    c)wx.getStorage() 异步获取
    d)wx.getStorageSync() 同步获取
  5. 媒体
    a)wx.getBackgroundAudioManager() 获取全局唯一的背景音频管理器
    b)wx.playVoice()
    6.支付
    a)Wx.requestPayment()

8.3 快速查找技巧

  1. 小程序的初学者可能对于小程序的官网的众多内容一时毫无头绪,无从下手不知道从哪来找想要的内容
  2. 当在小程序中想要实现某一种布局,查看:组件
  3. 当在小程序中想要实现某一个功能,查看: API
  4. 当在小程序中想要进行某一个配置或者某一种页面语法,查看: 框架 + 指南
  5. 查看小程序官网的时候要细心,最好是将要使用的API的相关内容看完整,因为API的配置及限制较多

9.组件传参

组件传参 - 把标题"猜你喜欢", "人气推荐"传入到组件中

怎么传? — 标签直接帮属性即可

<goods-list title="猜你喜欢" list="{{likeList}}"></goods-list>

怎么接?

组件内使用 properties 接(不支持数组,支持对象和配置对象)

// 不支持数组写法
// properties: ["title"],
// 支持对象写法
// properties: {
//   title: String,
// },
// 支持配置对象写法
properties: {
  title: {
    type: String,
    required: true
  },
  list: {
     type: Array,
     required: true
   }
},

路由传参query

使用标签和js都可以跳转

  1. 标签跳转

    <navigator
         url="/pages/goods/list/list?category2Id={{item.id}}"
    ></navigator>
    

    同时携带了 query 参数(路由带参)

  2. js跳转

    wx.navigateTo({
      url: '/pages/goods/list/list',
    });
    

    没带参数

跳转页面的API

wx.switchTab 跳转到tabbar页面
wx.redirectTo  关闭当前页面,跳转下一个页面,当前页面不在历史记录中
wx.navigateTo  跳转页面(有历史记录)
wx.navigateBack({ delta: 1 }) 回退页面,没有参数默认是1
wx.reLaunch   关闭所有的页面,打开到应用内的某个页面

进阶知识

1. 小程序本地存储

1.1 语法说明

  1. 存入数据
    a)wx.setStorage() 异步
    b)wx.setStorageSync() 同步
    在这里插入图片描述

  2. 读取数据
    a)wx.getStorage()异步
    b)wx.getStorageSync() 同步
    在这里插入图片描述

  3. 删除数据
    a)wx.removeStorage() 异步
    b)wx.removeStroageSync() 同步
    在这里插入图片描述

  4. 清空数据
    a)wx.clearStorage() 异步
    b)wx.clearStorageSync() 同步
    在这里插入图片描述

1.2 注意事项

  1. 除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用
  2. 单个 key 允许存储的最大数据长度为 1MB
  3. 所有数据存储上限为 10MB

1.3 官网对应地址

https://developers.weixin.qq.com/miniprogram/dev/api/storage/wx.setStorage.html
在这里插入图片描述

2. 小程序前后端交互

2.1 语法说明

  1. wx.request()
    在这里插入图片描述

2.2 相关配置

  1. 每个微信小程序需要事先设置通讯域名,小程序只可以跟指定的域名进行网络通信
  2. 服务器域名请在 「小程序后台-开发-开发设置-服务器域名」 中进行配置
  3. 默认超时时间和最大超时时间都是 60s
  4. 超时时间可以在 app.json 中通过 networktimeout 配置

2.3 注意事项

  1. 小程序为了安全起见只支持Https请求
  2. wx.request最大并发限制10个

2.4 官网对应地址

https://developers.weixin.qq.com/miniprogram/dev/api/storage/wx.setStorage.html
在这里插入图片描述

3. 小程序页面通信

3.1 路由传参

  1. 传参方式
    a) 路由地址中 + query传参数
    b)示例: url?a=123
    wx.navigateTo({
      url: '/pages/target/target?a=1&b=2',
    });
    
  2. 获取参数
    a)跳转目标页面的onLoad函数中的options实参中获取
    onLoad(options){
      const {a, b} = options;
    }
    

3.2 消息订阅发布

  1. 使用第三方库: pubsub-js
  2. 安装: npm install pubsub-js
  3. 使用:
    a)import PubSub from ‘pubsub-js’
    b)订阅消息: PubSub.subscribe(‘eventName’, callback)
    c)发布消息: PubSub.publish(‘eventName’, data)
    d)取消订阅: PubSub.unsubscribe(‘eventName’)

3.3 eventChannel 事件通道

  1. 订阅事件
    a)wx.navigateTo()跳转的时候在events选项中定义事件名及事件对应的回调
    在这里插入图片描述

  2. 获取事件总线对象
    a)目标页面中通过: 实例.getOpenerEventChannel()
    b)示例: const eventChannel = this.getOpenerEventChannel()

  3. 触发事件
    a)eventChannel.emit(‘事件名’, data)
    在这里插入图片描述

3.4 借助app传参

  1. 获取App
    const app = getApp()
  2. 在app上写入数据
    app.currentAddress = currentAddress;
  3. 获取数据
    const app = getApp()
    let currentAddress = app.currentAddress 获取数据

4. 小程序自定义组件

4.1. 创建组件

  1. 开发工具中在指定的文件夹下右键新建组件
    a)建议:文件夹名称与组件名称最好一致。
  2. 组件对应的json文件中设置: component: true
{
  "component": true,
  "usingComponents": {}"navigationStyle": "custom"  -----> 自定义导航  导航栏样式
  "navigationBarTitleText": "登录"   -----> 自定义文字
}

4.2. 使用组件

1.使用组件的页面的json文件中注册使用组件

{
  "usingComponents": {
    "goods-list": "/components/goods-list/goods-list"
  }
}
<goods-list title="猜你喜欢" list="{{ likeList }}"></goods-list>

5. 小程序使用npm包

5.1 初始化package.json

npm init

5.2 勾选允许使用npm(老版本)

老版本需要勾选
新版本已全面支持,没有当前选项
在这里插入图片描述

5.3 下载npm包

npm install packageName

5.4 构建npm

  1. 微信开发工具 —> 工具选项 —> 构建npm
  2. 会将node_modules中的包打包到miniprogram_npm中
    a)小程序中使用的第三方包内容会去miniprogram_npm中查找而不是node_modules
  3. 注意:
    a)开发中如果使用UI组件库,每次引入新的组件使用可能会导致样式不能生效,需要再次重新构建npm即可

5.5 流程执行不完整带来的错误

在这里插入图片描述

6.小程序登录流程

6.1 刚刚被作废的方式

6.1.1 首次获取

  1. Button组件设置open-type属性为getUserInfo
  2. <button open-type=’getUserInfo’></button>
  3. 设置后首次登陆点击button可以弹出授权窗口
  4. 注意: 授权的动作只发生一次,除非清除缓存,点击butotn授权一次之后再点击失效,不会弹出授权窗口
  5. 官网对应地址
    https://developers.weixin.qq.com/miniprogram/dev/component/button.html
    在这里插入图片描述

6.1.2 授权之后获取

  1. wx.getUserInfo()
  2. 官网对应地址:
    https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserInfo.html

6.1.3 作废说明

a) 依然可以使用,但不会出现授权弹窗
b) 获取到的用户名为 ‘微信用户’, 头像为灰色头像

6.2 目前推荐登录方式

6.2.1 通过token标识用户

  1. 通过用户临时登录code获取用户唯一标识token
  2. 如果需要展示用户头像和用户自定义用户名可通过页面引导用户自行设置

6.2.2 登录流程图解

在这里插入图片描述

8.6.2.3 登录流程说明

  1. wx.login()
    code是临时标识,只有5分钟内有效在这里插入图片描述

  2. 发送code给服务器端

  3. 服务器端发送请求携带参数(code, appSecret, appId)给微信服务器获取openId
    a) 微信接口API: GET https://api.weixin.qq.com/sns/jscode2session

  4. appSecret,appId在小程序首页获取
    在这里插入图片描述

  5. 服务器获取openId后进行加密返回给前端Token标识

7. 小程序使用UI组件库vant

7.1 下载安装

  • Npm安装
    npm i @vant/weapp -S --production
  • Yarn安装
    yarn add @vant/weapp –production

7.2 修改app.json

  • 操作: 将 app.json 中的 “style”: “v2” 去除
  • 原因:程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。

7.3 修改project.config.json

"packNpmRelationList": [
   {
      "packageJsonPath": "./package.json",
      "miniprogramNpmDistDir": "./"
   }
],

7.4 构建npm

微信开发工具 —> 工具 —> 构建npm

7.5 引入组件

  1. 页面.json文件中
{
  "usingComponents": {
    "van-action-sheet": "@vant/weapp/action-sheet/index",
    "van-stepper": "@vant/weapp/stepper/index",
    "van-icon": "@vant/weapp/icon/index",
    "van-button": "@vant/weapp/button/index"
  }
}

8.7.6 使用组件

<van-button block type="primary" round bindtap='handleSubmit'>确定</van-button>

8. 小程序分包流程

8.1 为什么要分包

  1. 小程序要求压缩包体积不能大于2M,否则无法发布
  2. 实际开发中小程序体积如果大于2M就需要使用分包机制进行发布上传
  3. 分包后可解决2M限制,并且能分包加载内容,提高性能
  4. 分包后单个包的体积不能大于2M
  5. 包后所有包的体积不能大于20M

8.2 分包形式

  1. 常规分包
  2. 独立分包
  3. 分包预下载
  4. 分包异步化

8.3 常规分包

  1. 开发者通过在 app.json subpackages 字段声明项目分包结构
  2. 特点:
  • a)加载小程序的时候先加载主包,当需要访问分包的页面时候才加载分包内容
  • b)分包的页面可以访问主包的文件,数据,图片等资源
  • c)主包:
    • i.主包来源: 除了分包以外的内容都会被打包到主包中
    • ii.通常放置启动页/tabBar页面
  1. 注意点:root包名必须是当前分包目录名

在这里插入图片描述

在这里插入图片描述

8.4 独立分包

  1. 设置 independent为true
  2. 特点:
  • a)独立分包可单独访问分包的内容,不需要下载主包
  • b)独立分包不能依赖主包或者其他包的内容
  1. 使用场景
  • a)通常某些页面和当前小程序的其他页面关联不大的时候可进行独立分包
  • b)如:临时加的广告页 || 活动页
    在这里插入图片描述

8.5 分包预下载

  1. 配置
  • a)app.json中设置preloadRule选项
  • b)key(页面路径): {packages: [预下载的包名 || 预下载的包的根路径])}
    在这里插入图片描述
    在这里插入图片描述
  1. 特点:
  • a) 在加载当前包的时候可以设置预下载其他的包
  • b) 缩短用户等待时间,提高用户体验

8.6 分包异步化

  1. 理解:
    a)独立分包不能依赖其他分包文件,如果要加载使用其他分包怎么办?
  2. 设计思想:
    a)等待其他分包加载后,异步加载依赖文件
  3. 异步分类
  • a)异步加载组件

    • i.使用内置组件设置占位
    • ii.等待异步加载后再加载使用依赖的组件
    • iii.设置选项:对应组件json文件中 ‘componentPlaceholder’ 字段
      // subPackageA/pages/index.json
      {
      "usingComponents": {
      "button": "../../commonPackage/components/button",
      "list": "../../subPackageB/components/full-list",
      "simple-list": "../components/simple-list"
      },
      "componentPlaceholder": {
      "button": "view",
      "list": "simple-list"
      }
      }
      
  • b)异步加载js文件

    • require 方法
    • 回调函数方式
      /* 回调函数形式 */
      let findUserAddress, delAddress;
      require('../../../../utils/api', utils => {
      findUserAddress = utils.findUserAddress;
      delAddress = utils.deleteAddress;
      }, ({mod, errMsg}) => {
      console.error(`path: ${mod}, ${errMsg}`)
      })
    
    • Promise方法
      /* promise形式 */
      (async function(){
      let utils = await require('../../../../utils/api')
      console.log(utils)
      findUserAddress = utils.findUserAddress;
      delAddress = utils.deleteAddress;
      })()
    

8.7 分包效果演示

在这里插入图片描述

8.8 官网对应地址

https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html

9. 小程序转发分享

9.1 分享实现

  1. Button组件设置open-type为share
  2. <button open-type=’share’ ></button>

9.2 自定义分享内容

  1. 生命周期回调中onShareAppMessage回调中return 对象设置自定义内容
    在这里插入图片描述

9.3 设置体验权限

  1. 开发阶段分享给微信好友,默认没有体验权限,无法打开分享小程序,需要在开发页面设置
  2. 最多添加15个微信好友
    在这里插入图片描述

10. 小程序支付流程

10.1 支付流程官网图解

在这里插入图片描述

10.2 支付流程详细说明

  1. 用户在小程序客服端下单
    • a)用户标识token
    • b)商品信息: id,数量,附属信息(备注等)
    • c)地址信息
  2. 小程序客户端发送下单支付请求给商家服务器
    • a)获取商家订单id
  3. 商家服务器发送请求调用统一下单API获取预支付订单信息
    • a)接口地址: https://api.mch.weixin.qq.com/pay/unifiedorder
  • b)需要携带参数
    1. 用户openid
    2. 商户id
    3. 商户订单id
    4. 。。。
  1. 商家对预支付信息签名加密后返回给小程序客户端
    • a)签名方式: MD5
    • b)签名字段:小程序ID, 时间戳, 随机串,数据包,签名方式
    • c)参考地址: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3
  2. 用户确认支付(鉴权调起支付)
    • a)API: wx.requestPayment()
    • b)鉴权通过后客户端调起输入框,用户输入支付密码
    • c)注意:模拟器上会弹出二维码需要使用当前开发者微信扫码进行支付操作
  3. 微信服务器返回支付结果给小程序客户端
    • a)支付成功后客户端发送请求给商家服务器查询订单信息
    • b)根据订单信息决定如何跳转页面及展示信息给用户
  4. 微信服务器推送支付结果给商家服务器端

10.3 官网对应地址

https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_8_2.shtml

10.4 描述

整体流程:

  1. 用户下单,发请求给商家服务器(这一步前端做),商家服务器生成订单,然后给腾讯服务发请求,生成预付单,生成腾讯生成预付单的目的是为了知道这个订单要收多少钱,腾讯服务知道收多钱之后反馈给商家服务器,生成支付签名信息返回给小程序

  2. 小程序端接收到商家返回的支付签名信息,调用 wx.requestPayment() 发起微信支付(这一步前端做)

  3. 发起之后要去腾讯服务鉴权,鉴定有没有实名、有没有绑定银行卡,鉴权成功之后告诉小程序可以调起微信支付,此时要去弹出密码输入框(这一步是调用完 requestPayment)小程序自己和腾讯服务的交互

  4. 小程序弹出密码弹框,用户输入密码,授权付款,钱在腾讯服务上,所以授权要发送给腾讯服务,腾讯服务接到授权后,会把用户账号中的款扣了,把钱划给商家,返回支付成功告诉用户,提示"支付成功",这里的支付成功可以理解为"扣款成功"(这时会弹一个弹框,微信弹的)

    在这个步骤的同时,会异步告诉商家服务,该用户已经付款,可以发货

  5. 点击微信弹出弹框确认之后,要回到商家的小程序,小程序也要提示用户"订单支付成功",所需小程序发请求给商家服务,商家服务接到请求之后,找腾讯服务确认用户是否支付成功,确认之后,返回给用户支付成功的数据,小程序展示"订单支付成功"页面

前端步骤:

  1. 调用创建订单接口,创建出订单,返回 orderId

  2. 拿着 orderId 获取支付信息

  3. 拿着支付信息调用 wx.requestPayment() 去支付

    只有支付成功之后,才会走 wx.requestPayment() 的 success 回调

  4. 在支付成功之后,调用接口查询订单状态(已支付),跳转支付成功页

项目中使用的

1.导航设置★

app.json

{
  "pages":[
    "pages/index/index"
  ],
  "window":{
    "navigationBarBackgroundColor": "#9c0211",
    "navigationBarTitleText": "慕尚花坊",
    "navigationBarTextStyle":"white"
  },
}

2.小程序中的ui

2.1. swiper 轮播

 <swiper
    class="banner-container"
    indicator-dots
    indicator-color="#fff"
    indicator-active-color="#ff734c"
    autoplay
    circular
    interval="2200"
    duration="400"
  >
    <swiper-item
      class="banner-item"
      wx:for="{{ bannerList }}"
      wx:key="id"
    >
      <image class="banner-img" src="{{ item.imageUrl }}"></image>
    </swiper-item>
  </swiper>

2.2. image 组件

<view class="action">
  <image class="action-img" src="{{backgroundImg}}" mode="widthFix"></image>
</view>

注意: image 组件的 mode="widthFix" 是设置宽度,保持图片的宽高比不变,自己去算高度

2.3scroll-view 的使用

页面宽高设置100%是相对于父级的,而父级是 page 这个元素,这个元素需要设置 宽高100%才可以,这个元素样式在 app.wxss 中设置,这是个全局的,每个页面的根元素都是 page 这个元素

  <!-- scroll-view 如果要使用flex布局,需要设置enable-flex属性 -->
<view class="category-container">
  <view class="menu">

    <scroll-view
      class="menu-list"
      scroll-y
    >
      <view class="menu-item active">
        鲜花玫瑰
      </view>
      <view class="menu-item">
        鲜花玫瑰
      </view>
      <view class="menu-item">
        鲜花玫瑰
      </view>
      <view class="menu-item">
        鲜花玫瑰
      </view>
    </scroll-view>

  </view>

注意:scroll-view 如果要使用flex布局,需要设置enable-flex属性

2.4 button

  1. button 组件添加 open-type="chooseAvatar" 属性点击才能展示出选择头像的弹框

  2. input 组件添加 type="nickname" 属性才能弹出选择昵称的弹框

3.封装 request.js 文件★


function request ({
  url,
  method = 'GET',
  data,
  header = {},
  timeout = 30000
}) {

  wx.showLoading({ title: '加载中' }); // 显示loading

  const baseURL = `https://gmall-prod.atguigu.cn`

  header = {
    'content-type':'application/json',
    ...header
  }

  // 获取个人信息需要携带token
  let token = wx.getStorageSync("TOKEN");
  if (token) {
    header.token = token
  }
  
  return new Promise((resolve, reject) => {

    // wx.request 微信提供的,直接用,没有跨域这一说
    wx.request({
      url: baseURL + url, // 请求的url
      method, // 请求方式
      data, // 携带数据
      header, // 请求头
      timeout, // 超时时间
      dataType: 'json', // 数据类型是json
      responseType: 'text', // 响应类型是文本
      success: (response) => { // 请求成功之后会执行success回调

        let res = response.data // 拿到响应体(也就是后端返回的数据,包含code、data、message)
        
        if (res && res.code == 200) {
        
          resolve(res.data)

        } else if (res.code == 208) { // 未登录的兜底处理,只要返回code是208都去登录页
          
          wx.showModal({
            title: '警告',
            content: '未登录,请先登录',
            showCancel: true,
            cancelText: '取消',
            cancelColor: '#000000',
            confirmText: '确定',
            confirmColor: '#3CC51F',
            success: (result) => {
              console.log(result)
              if(result.confirm){ // 点击确认跳转登录页
                wx.navigateTo({
                  url: '/pages/login/login'
                });
              }
            }
          });

        } else {

          // 弹出提示框
          wx.showToast({ // 给用户提示
            title: '请求失败',
            icon: 'error', // none success error
            // image: '/static/images/1.png',
            duration: 1500
          });

          console.error(res) // 给程序员看的
          reject(res || '请求失败')
        }
        
      },
      fail: (err) => { // 请求失败执行的回调(断网的时候会走到fail中,超时也会只有fail,url错误(指url不是字符串)也会走fail)
        wx.showToast({ // 给用户提示
          title: '请求失败',
          icon: 'error',
          duration: 1500
        });

        console.error(err) // 给程序员看的
        reject(err)
      },
      complete: () => { // 不管成功失败都会执行的回调
        wx.hideLoading(); // 隐藏loading
      }
    });

  })

}

export default request

4.关于路径映射@★

在 app.json 中配置

{
    "resolveAlias": {
    	"@/*": "/*"
  	},
}

5. 底部tabbar 配置★

地址: https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar

app.json 文件中配置

"tabBar": {
  "color": "#333",
  "selectedColor": "#ff582f",
  "list": [
    {
      "pagePath": "pages/index/index",
      "text": "首页",
      "iconPath": "/static/tabbar/home-icon1.png",
      "selectedIconPath": "/static/tabbar/home-icon1-1.png"
    },
    {
      "pagePath": "pages/category/category",
      "text": "分类",
      "iconPath": "/static/tabbar/home-icon2.png",
      "selectedIconPath": "/static/tabbar/home-icon2-2.png"
    },
    {
      "pagePath": "pages/cart/cart",
      "text": "购物车",
      "iconPath": "/static/tabbar/home-icon3.png",
      "selectedIconPath": "/static/tabbar/home-icon3-3.png"
    },
    {
      "pagePath": "pages/personal/personal",
      "text": "我的",
      "iconPath": "/static/tabbar/home-icon4.png",
      "selectedIconPath": "/static/tabbar/home-icon4-4.png"
    }
  ]
},

6.分页处理★onReachBottom的使用

onReachBottom的使用 页面触底回调

  1. 页面触底的时候要发送请求,需要页面触底的回调(于data配置项同级)

    data: {
      ......
      status: 'more' // 页面发请求的状态,总共有以下几个值:  'more'更多 'no-more'没有更多 'loading'加载中 'error'错误
    },
    // 页面触底回调
    onReachBottom() {
      if (this.data.status == 'no-more') {
        return
      }
      // 翻页
      this.setData({
        page: this.data.page + 1
      })
      this.getGoodsList()
    },
        async getGoodsList() {
      this.setData({ status: 'loading' })
      // 组转数据
      const { page, limit, category2Id } = this.data
      let data = {}
      if (category2Id) {
        data.category2Id = category2Id
      }
      // 发送请求
      try {
        let result = await reqGoodsList(page, limit, data)
        let goodsList = this.data.goodsList.concat(result.records) // 之前列表中的值不能清空
        let status = 'more'
        if (goodsList.length == result.total) { // 当获取到所有的数据之后,状态改为no-more
          status = 'no-more'
        }
      ......
    

这里使用 goosList.length 和 totoal 去判断也可以

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/989491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java封装国密SM4为 jar包,PHP调用

java封装国密SM4为 jar包,PHP调用 创建java工程引入SM4 jar包封装CMD可调用jar包PHP 传参调用刚用java弄了个class给php调用,本以为项目上用到java封装功能的事情就结束了,没想到又来了java的加密需求,这玩意上头,毕竟不是强项,没办法,只好再次封装。 但是这次的有点不…

win10系统配置vmware网络NAT模式

1&#xff0c;查看win10 IP地址&#xff1a;ipconfig 2, vmware设置&#xff1a;编辑>>虚拟网络编辑器>>点击添加网络&#xff08;选择NAT模式&#xff09; 3&#xff0c;虚拟机网络设置&#xff1a;点击VMware虚拟机>>设置>>网络适配器 4&#xff…

【常用代码14】el-input输入框内判断正则,只能输入数字,过滤汉字+字母。

问题描述&#xff1a; el-input输入框&#xff0c;只能输入数字&#xff0c;但是不能显示输入框最右边的上下箭头&#xff0c; <el-input v-model"input" type"number" placeholder"请输入内容" style"width: 200px;margin: 50px 0;&…

YOLO总结,从YOLOv1到YOLOv3

YOLOv1 论文链接&#xff1a;https://arxiv.org/abs/1506.02640 检测原理 将检测问题转换成回归问题&#xff0c;一个CNN就搞定。即得到一个框的中心坐标(x, y)和宽高w&#xff0c;h&#xff0c;然后作回归任务。 B是两个框&#xff0c;5是指参数量&#xff0c;x y w h是确定…

港联证券:综合施策提振信心 资本市场新一轮深化改革拉开帷幕

本钱商场新一轮深化变革开放已拉开帷幕。活泼本钱商场“25条”、北交所“深改19条”、标准股份减持行为规定……这些方针举动从出资端、融资端、买卖端等协同发力&#xff0c;既注重短期痛点问题&#xff0c;又着眼久远、安身变革准则完善&#xff0c;有助于构成活泼商场、提振…

2023-9-8 满足条件的01序列

题目链接&#xff1a;满足条件的01序列 #include <iostream> #include <algorithm>using namespace std;typedef long long LL;const int mod 1e9 7;int qmi(int a, int k, int p) {int res 1;while(k){if(k & 1) res (LL) res * a % p;a (LL) a * a % p;…

2023年软件开发领域的发展趋势

科技趋势引领着软件开发行业的发展。对于开发商来说&#xff0c;将会看到更多的市场增长机会。因此&#xff0c;很多人都想了解软件开发的最新趋势。IT行业正在等待一个范式转变&#xff0c;而科技的好处在于不断发展&#xff0c;势不可挡&#xff0c;并且用途广泛。 很多专业人…

python串口采集数据绘制波形图

这个示例使用 matplotlib 绘制图形&#xff0c;它能够从串口实时读取数据并绘制成波形图。确保你已经替换了 ‘COM11’ 和 9600 为正确的串口号和波特率。 import serial import matplotlib.pyplot as plt from collections import deque import struct# 配置串口参数 ser s…

SpringMVC之CRUD------增删改查

目录 前言 配置文件 pom.xml文件 web.xml文件 spring-context.xml spring-mvc.xml spring-MyBatis.xml jdbc.properties数据库配置文件 generatorConfig.xml log4j2日志文件 后台 PageBaen.java PageTag.java 切面类 biz层 定义一个接口 再写一个实现类 …

vue3嵌套路由keep-alive问题

传统解决方法参考此链接Vue3 嵌套路由中使用 keep-alive缓存多层 - 掘金 我想说的是&#xff1a; 嵌套路由的上级不写componet就行了啊&#xff01;&#xff01;&#xff01;被折磨了两次的顿悟

LeetCode-77-组合

一&#xff1a;题目描述&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 二&#xff1a;示例与提示 示例 1: 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4…

双系统时间问题、虚拟机扩展空间问题

文献阅读计划&#xff1a; 首先要用ChatGPT查文献&#xff0c;用关键字查询&#xff0c;然后去搜索 add cyun 9.8 但是我发现好难搜啊&#xff0c;或者说相关的关键词搜不出来东西啊。不过师兄倒是搜的挺多的&#xff0c;这一点要再去好好学习一下 双系统时间问题&#xff1a…

前缀(波兰式)、中缀、后缀(逆波兰)表达式;中缀转后缀

前缀表达式的计算机求值 注意&#xff1a;在前缀表达式中&#xff0c;遇到运算符时&#xff0c;如“-”&#xff0c;是栈顶元素 - 次顶元素 中缀表达式 后缀表达式 注意&#xff1a;在后缀表达式中&#xff0c;遇到运算符时&#xff0c;如“-”&#xff0c;是次顶元素 - 栈顶元…

【Docker】实现JMeter分布式压测

一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试。如本网站所示&#xff0c;一个JMeter实例将能够控制许多其他的远程JMeter实例&#xff0c;并对你的应用程序产生更大的负载。JMeter使用Java RMI[远程方法调用]来与分布式网络中的对象进行交互。JMeter主站…

Springboot 实践(14)spring config 配置与运用--手动刷新

前文讲解Spring Cloud zuul 实现了SpringbootAction-One和SpringbootAction-two两个项目的路由切换&#xff0c;正确访问到项目中的资源。这两个项目各自拥有一份application.yml项目配置文件&#xff0c;配置文件中有一部分相同的配置参数&#xff0c;如果涉及到修改&#xf…

ajax实现百度一下模糊查询功能

1、效果 如下图所示&#xff0c;我们在输入大学时&#xff0c;程序会到后端查询名字中包含大学的数据&#xff0c;并展示到前端页面。 用户选择一个大学&#xff0c;该大学值会被赋值到input表单&#xff0c;同时关闭下拉表单&#xff1b; 当页面展示的数据都不符合条件时&…

【软考】系统架构设计师 - 知识扩展 - “区块链技术“

目录 一 简介&#x1f451; 1 比特币❤️ 2 区块链的特点❤️ 3 共识算法❤️ 二 练习题&#x1f451; 三 扩展&#x1f451; 1 哈希算法❤️ 2 哈希指针❤️ 3 UTXO❤️ 4 参考资料❤️ 一 简介&#x1f451; 1 比特币❤️ 比特币底层采用了区块链技术。 比特币交易…

android在java代码里面运行shell脚本,使用shell脚本杀死目标进程

android开发中使用shell脚本的比较少&#xff0c;即使使用也是在adb里面直接运行&#xff0c;但是今天我就记录一下怎么在java里面执行shell脚本。 注意&#xff1a;这个需要配置selinux权限&#xff0c;或者你可以直接把selinux权限关闭才能运行 一、写一个shell脚本 这里我…

npm publish包报404,is not in the npm registry错误

1. 指定发布目标2. 登录npm&#xff0c;使用登录名发布包&#xff0c;包名命名原则“登录名/包名”&#xff0c;或 “包名” 3. 删除某一个版本npm unpublish pvfhv/eslint-config-prettier1.0.1 --force 删除后的版本不能重复使用&#xff0c;正式解释&#xff1a; Unfortun…

蓝桥杯官网练习题(凑算式)

类似填空题&#xff1a; ①算式900&#xff1a; https://blog.csdn.net/s44Sc21/article/details/132746513?spm1001.2014.3001.5501https://blog.csdn.net/s44Sc21/article/details/132746513?spm1001.2014.3001.5501 ②九宫幻方③七星填数④幻方填空&#xff1a;https:/…