自定义导航 导航栏样式"navigationBarTitleText": "登录" -----> 自定义文字生命周期回调中onShareAppMessage回调中return 对象设置自定义内容。_switchtab 跳转到另一个tabb">
当前位置:   article > 正文

小程序的使用_switchtab 跳转到另一个tabbar

switchtab 跳转到另一个tabbar

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

基础语法

1.数据绑定

1.1 初始化数据

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

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

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

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

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

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'
        })
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

2.事件绑定

2.1 事件分类

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

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

2.2 绑定事件

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

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

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

2.3 向事件对象传参

  1. 语法: data-key=value
 <button catchtap="changeName" data-name='{{firstName}}'>点击修改名称</button>
  • 1
  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>
  • 1
  • 2
  • 3

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>
  • 1
  • 2
  • 3

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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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.redirectTowx.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
   }
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

10.路由传参query

使用标签和js都可以跳转

  1. 标签跳转

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

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

  2. js跳转

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

    没带参数

11.跳转页面的API

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

12.onPageScroll

查看页面的钩子函数和事件函数
https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html
onPageScroll(Object object)
监听用户滑动页面事件。

进阶知识

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',
    });
    
    • 1
    • 2
    • 3
  2. 获取参数
    a)跳转目标页面的onLoad函数中的options实参中获取
    onLoad(options){
      const {a, b} = options;
    }
    
    • 1
    • 2
    • 3

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": "登录"   -----> 自定义文字
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4.2. 使用组件

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

{
  "usingComponents": {
    "goods-list": "/components/goods-list/goods-list"
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
<goods-list title="猜你喜欢" list="{{ likeList }}"></goods-list>
  • 1

5. 小程序使用npm包

5.1 初始化package.json

npm init
  • 1

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": "./"
   }
],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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"
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

8.7.6 使用组件

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

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"
      }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
  • b)异步加载js文件

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

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获取预支付订单信息
  • b)需要携带参数
    1. 用户openid
    2. 商户id
    3. 商户订单id
    4. 。。。
  1. 商家对预支付信息签名加密后返回给小程序客户端
  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
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html

{
 entryPagePath	string	否	可以用来配置小程序默认启动首页
  "pages":[
    "pages/index/index"   //放在位置为第一个时候 会默认为启动页的首页
  ],
  "window":{
    "navigationBarBackgroundColor": "#9c0211",
    "navigationBarTitleText": "慕尚花坊",
    "navigationBarTextStyle":"white"
  },
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.2. image 组件

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

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

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

注意: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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

4.关于路径映射@★

在 app.json 中配置

{
    "resolveAlias": {
    	"@/*": "/*"
  	},
}
  • 1
  • 2
  • 3
  • 4
  • 5

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"
    }
  ]
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

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'
        }
      ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

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

7.pageScrollTo★

将页面滚动到目标位置,支持选择器和滚动距离两种方式定位

wx.pageScrollTo({ // wx的API
  scrollTop: 0, // 页面到顶部的距离
  duration: 300 // 页面到顶部的时间
})
  • 1
  • 2
  • 3
  • 4

8.onPageScroll

onPageScroll(Object object)
监听用户滑动页面事件。

uni-app中使用

所有小程序中的api在uni中都可以使用但是改变成了uni开头

1.创建项目

npx degit dcloudio/uni-preset-vue#vite-ts uni_course
  • 1

使用的是vite + TS创建的项目,没有依赖

cd uni_course
npm i
  • 1
  • 2

安装好依赖就可以启动项目了,在项目启动之前先了解项目目录结构

2.目录结构

需要注意的:

manifest.json 文件中要配置 微信小程序的 appid

在这里插入图片描述

main.ts

import { createSSRApp } from "vue"; // 引入的是 vue 服务端渲染
import App from "./App.vue"; // 根组件

export function createApp() {
  const app = createSSRApp(App); // 创建一个app实例,把App根组件传进去
  return {
    app, // 把实例抛出去
  };
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

客户端渲染:发请求的时候,拿回来的 html 页面只有一个 <div id="app"></div> 元素,页面中所有的内容都是由 请求回来的css 和 js 生成的。

服务端渲染:发请求的时候,拿回来的 html 页面是一个完整的 html 页面

服务端渲染最大的优点在于 SEO优化 友好,SEO优化是搜索引擎优化,优化的越好,搜索引擎搜出来的时候排名越靠前(不掏钱的前提下)

App.vue

发现App.vue 根组件中只有 script 和 style,没有 template,为什么?
App.vue 的 style 相当于是 小程序中的 app.wxss
App.vue 的 script 相当于是 小程序中的 app.js
pages.json 相当于是小程序的 app.json,同时把每个页面的 json,也放在了 pages.json 中

3.启动项目

npm run dev:mp-weixin
  • 1

在 package.json 中发现启动微信小程序是该指令,执行之后,创建了一个 dist/dev 目录,在这个目录中由 mp-weixin 这个文件夹,这就是将 vue 编译成了小程序代码,使用 “微信开发者工具” 打开该项目,就可以看到了

当执行 npm run dev:mp-weixin 时候,dist/dev/mp-weixin 这个小程序代码每次都会清空掉重新构建

4.配置项目导航

去 pages.json 中配置

	"globalStyle": {
		"navigationBarTextStyle": "white",
		"navigationBarTitleText": "谷粒课堂",
		"navigationBarBackgroundColor": "#00cc99"
	}
  • 1
  • 2
  • 3
  • 4
  • 5

同时需要注意页面的配置项会覆盖全局的配置项,需要改页面的配置项

把首页的内容清空了

5.uni-ui 组件库使用★

官网教程: https://uniapp.dcloud.net.cn/component/uniui/quickstart.html

v-card-list 组件中,用到了一个 icon ,这个 icon 使用 uni-ui 组件库

  1. 安装 sass 和 sass-loader

    npm i sass sass-loader@10.1.1 -D
    
    • 1

    如果安装失败的话,最后加一个 -f 强制安装

  2. 安装 uni-ui

    npm i @dcloudio/uni-ui
    
    • 1
  3. 配置 easycom

    在 pages.json 中配置 easycom

    {
    	"easycom": {
    		"autoscan": true,
    		"custom": {
    			// uni-ui 规则如下配置
    			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
    		}
    	},
    	
    	pages:[]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    接下来就可以在模板中使用了

6.页面通信★

1. navigateTo

A页面跳转B页面,携带参数过去,使用query携带参数,在另一个页面中的onLoad的参数中可以拿到传过来的参数

uni.navigateTo({
    url: `/pages/course/index?courseId=${courseId}`,
});
  • 1
  • 2
  • 3

2. Storage

在 A 页面将数据存储到storage中,跳转到 B 页面再取出来

A页面

wx.setStorageSync("courseId", courseId);
  • 1

B 页面

let courseId = wx.getStorageSync("courseId");
  • 1

3. app 实例传参

在A页面将数据存储到 app 应用实例上,跳转到 B 页面再取出来

A 页面

const app = getApp()
app.courseId = courseId
  • 1
  • 2

B 页面

const app = getApp()
const courseId = app.courseId
  • 1
  • 2

4. pubsub

  1. 安装

    不在界面上显示的第三包使用步骤(工具类的,例如: pubsub、moment、lodash…)

    npm i pubsub-js
    
    • 1

    直接 【工具】 -> 【构建npm】 即可 使用第三方包

  2. 在接收数据的组件中找到 pubsub ,绑定事件(订阅消息),留下回调,接收参数

    使用 index 接收

    Pubsub.subscribe('receiveData', (messagetype, arg) => {
      console.log(messagetype, arg)
    })
    
    • 1
    • 2
    • 3
  3. 在发送数据的组件中找到 pubsub,触发事件(发布消息),传递参数

    使用 logs 页面发送数据

    Pubsub.publish('receiveData', '我爱你')
    
    • 1

注意:这个传参用的是 新打开的页面(logs) 给 被盖住的页面(index) 传参

如果是 被盖住的页面(index) 给 新打开的页面(logs) 去使用 pubsub 传参,注意执行时机,只要触发事件在绑定事件之后,就能接收到参数

5. eventChannel 事件通道

查看案例:https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.navigateTo.html

  1. 被覆盖的页面(index) -> 被打开的页面传参(logs)

    被覆盖的页面(index)

    wx.navigateTo({
      url: '/pages/logs/logs',
      success: (res) => {
        // res.eventChannel 事件通道 - 触发事件事件传递参数
        res.eventChannel.emit('xxx', '你是个好人')
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    被打开的页面(logs)

    onLoad: function (options) {
      // 事件通道
      const eventChannel = this.getOpenerEventChannel() // 拿到事件通道
      // 绑定事件,留下回调,接收参数
      eventChannel.on('xxx', (arg) => {
        console.log('事件通道 logs 接参', arg)
      })
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  2. 被打开的页面传参(logs) -> 被覆盖的页面(index)

    被打开的页面传参(logs)

    onLoad: function (options) {
    
      // 5. 事件通道
      const eventChannel = this.getOpenerEventChannel() // 拿到事件通道
      eventChannel.emit('yyy', '我们不合适')
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    被覆盖的页面(index)

    wx.navigateTo({
      url: '/pages/logs/logs',
      events: {
        yyy: (arg) => {
          console.log('index页面接收log参数', arg)
        }
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

6. uniapp - 事件总线

跳转链接

uni.$on()

uni.$emit()

uni.$once()

uni.$off()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/97115
推荐阅读
相关标签
  

闽ICP备14008679号