搭建环境

  1. 官方地址下载开发工具
  2. 构建项目

    1. 可以新建,也可以导入原有项目
    2. 需要去注册一个小程序以获得 AppId,也可以使用测试号

      小程序配置

  3. app.json全局配置文档

  4. 解释 ```json {

    页面路径

    “pages”: [ “pages/index/index”, “pages/cart/cart”, “pages/detail/detail”, “pages/my/my”, “pages/demo/demo” ],

用于设置小程序的状态栏、导航条、标题、窗口背景色

“window”: {

颜色

“navigationBarBackgroundColor”: “#f8f8f8”,

导航栏标题文字内容

“navigationBarTitleText”: “花间”,

导航栏标题颜色,仅支持 black / white

“navigationBarTextStyle”: “black”,

下拉 loading 的样式,仅支持 dark / light

“backgroundTextStyle”: “dark”,

背景颜色

“backgroundColor”: “#f8f8f8” },

底部tab栏

“tabBar”: {

选中的tab颜色

“selectedColor”: “#c03131”,

默认颜色

“color”: “#797d82”,

tab列表配置

“list”: [ { “iconPath”: “./img/home.png”, “selectedIconPath”: “./img/homeing.png”, “pagePath”: “pages/index/index”, “text”: “首页” }, { “iconPath”: “./img/cart.png”, “selectedIconPath”: “./img/carting.png”, “pagePath”: “pages/cart/cart”, “text”: “购物车” }, { “iconPath”: “./img/my.png”, “selectedIconPath”: “./img/mying.png”, “pagePath”: “pages/my/my”, “text”: “个人中心” }, { “iconPath”: “./img/my.png”, “selectedIconPath”: “./img/mying.png”, “pagePath”: “pages/demo/demo”, “text”: “demo” } ] },

使用的组件放在这里

“usingComponents”: {

}, “sitemapLocation”: “sitemap.json” }

  1. <a name="V9wXn"></a>
  2. ## 基础
  3. <a name="us43j"></a>
  4. ### 静态页面
  5. 1. 标签
  6. 1. view => div
  7. 1. text => span
  8. 1. img => [image](https://developers.weixin.qq.com/miniprogram/dev/component/image.html)
  9. 1. 地图,音视频,画布等
  10. 2. 可同时使用px、rpx 作为像素单位,`1px = 2rpx `
  11. 2. page 标签为页面的最外层的容器
  12. 2. [底部 tab 配置](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar)
  13. 2. [开放数据](https://developers.weixin.qq.com/miniprogram/dev/component/open-data.html)
  14. 2. 编译模式
  15. 2. [在小程序中使用 vant-ui](https://vant-contrib.gitee.io/vant-weapp/#/home)
  16. 2. [小程序中使用 less](https://developers.weixin.qq.com/community/develop/article/doc/000e427c49c218e6b9781bfdf5b013)
  17. <a name="Sw2z2"></a>
  18. ### 生命周期
  19. | 周期函数 | 作用 |
  20. | --- | --- |
  21. | onLoad | 监听页面加载 |
  22. | onReady | 监听页面初次渲染完成 |
  23. | onShow | 监听页面显示 |
  24. | onHide | 监听页面隐藏 |
  25. | onUnload | 监听页面卸载 |
  26. | onPullDownRefresh | 监听用户下拉刷新 |
  27. | onReachBottom | 监听用户上拉触底事件 |
  28. | onShareAppMessage | 监听用户点击右上角分享 |
  29. **onLoad 与 onShow 的区别:**
  30. - onLoad 只会在小程序中执行一次;即当前页面执行过 onLoad 函数时,然后切出该页面再切入时,onLoad 函数不再执行
  31. - onShow 每次切回页面时,都会触发这个生命周期函数
  32. <a name="HwtWa"></a>
  33. ### 请求数据
  34. 1. 关闭合法域名检测
  35. - 小程序只支持 https,项目中请求了非 https 和不在域名白名单上的接口会报错
  36. - 需要到小程序后台配置域名白名单,小程序右上角详情 =>本地设置 => 不校验合法域名...
  37. 2. 发送请求[文档地址](https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html)
  38. ```javascript
  39. wx.request({
  40. # 请求地址
  41. url: "test.php",
  42. data: {
  43. x: "",
  44. y: "",
  45. },
  46. # 请求方式
  47. method: "get",
  48. # 默认值,定义响应数据的格式
  49. header: {
  50. "content-type": "application/json",
  51. },
  52. # 成功的回调
  53. success(res) {
  54. console.log(res.data);
  55. };
  56. # 失败的回调
  57. fail(error) {
  58. console.log(error);
  59. };
  60. # 不管是成功还是失败都会调用此方法
  61. complete() {
  62. console.log("done");
  63. };
  64. });
  1. 封装小程序的请求

    • 配置 baseUrl ```javascript

      config.js

      let env = “prod”; let baseUrl = “”; if (env === “dev”) {

    本地地址

    baseUrl = “https://localhost:3009“; } else if (env === “prod”) { baseUrl = “https://huruqing.cn:3009“; }

导出

export { baseUrl };

  1. - reques.js
  2. ```javascript
  3. import { baseUrl } from "./config.js";
  4. /**
  5. * 封装请求
  6. * url:请求地址
  7. * data:请求参数
  8. * method: 请求类型
  9. * */
  10. const request = (url, data, method) => {
  11. # 获取token,登录时存的
  12. let token = wx.getStorageSync("token");
  13. url = baseUrl + url;
  14. return new Promise((resolve, reject) => {
  15. # 请求
  16. wx.request({
  17. url,
  18. method,
  19. data,
  20. header: {
  21. "user-token": token,
  22. },
  23. success: (res) => {
  24. if (res.data.code == 666) {
  25. resolve(res.data);
  26. } else if (res.data.code == 603) {
  27. wx.removeStorageSync("token");
  28. wx.showModal({
  29. title: "提示",
  30. content: "登录已过期,是否重新登录",
  31. success(res) {
  32. if (res.confirm) {
  33. # 跳转到个人中心页面
  34. wx.switchTab({
  35. url: "/pages/my/my",
  36. });
  37. } else if (res.cancel) {
  38. console.log("用户点击取消");
  39. }
  40. },
  41. });
  42. } else {
  43. reject(res.data.msg);
  44. }
  45. },
  46. fail: (err) => {
  47. reject("网络异常");
  48. },
  49. });
  50. });
  51. };
  52. const get = (url, data) => {
  53. return request(url, data, "get");
  54. };
  55. const post = (url, data) => {
  56. return request(url, data, "post");
  57. };
  58. export default {
  59. get,
  60. post,
  61. };

渲染页面

  1. data 和 setData

    1. Page({
    2. data: {
    3. count: 1,
    4. },
    5. changeCount() {
    6. // 获取data里count的值
    7. let count = this.data.count;
    8. // 加1
    9. this.setData({
    10. count: ++count,
    11. });
    12. },
    13. });
  2. 插值表达式 {{}},wxml 中所有的变量都要使用{{}},(除了wx:key)

    1. 如果数组成员是字符串或者数字,wx:key="index"wx:key="*this"
    2. 如果数组成员是对象, 比如:[{name:'zs',id:1}],wx:key="id"
  3. 条件渲染 wx:if
  4. 列表渲染 wx:for 默认有 item 和 index
  5. 双重 wx:for 时需要其中一个指定 item 和 index

    绑定事件

  1. 例子

    1. <view data-username="xxxx" bindtap="tapName"> Click me! </view>
    1. Page({
    2. tapName(event) {
    3. # 小程序事件不能像 vue 那样传参,只能通过自定义属性来传参
    4. let username = event.target.dataset.username;
    5. console.log(username);
    6. },
    7. });
    • 注意:定义的实参名只能小写,大驼峰式需要用 data-user-name="xxxx" 格式
  2. 常见事件类型 | 类型 | 触发条件 | | —- | —- | | touchstart | 手指触摸动作开始 | | touchmove | 手指触摸后移动 | | touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 | | touchend | 手指触摸动作结束 | | tap | 手指触摸后马上离开 | | longpress | 手指触摸后,超过 350ms 再离开,如果该事件被触发,tap 事件将不被触发 | | transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 | | animationstart | 会在一个 WXSS animation 动画开始时触发 | | animationiteration | 会在一个 WXSS animation 一次迭代结束时触发 | | animationend | 会在一个 WXSS animation 动画完成时触发 | | touchforcechange | 在支持 3D Touch 的 iPhone 设备,重按时会触发 |

页面跳转

  1. 非 tab 栏跳转

    • 标签式

      1. <navigator url="/pages/index/index"> 跳转到新页面 </navigator>
    • 函数式

      1. // 普通页面跳转
      2. wx.navigateTo({
      3. url: "/pages/index/index",
      4. });
  2. tab 栏跳转

    • 标签式

      1. <navigator url="/pages/index/index" open-type="switchTab"> 切换 Tab </navigator>
    • 函数式

      1. wx.switchTab({
      2. url: "pages/index/index",
      3. });
  3. 重定向

    • 标签式

      1. <navigator url="/pages/index/index" open-type="redirect"> 在当前页打开 </navigator>
    • 函数式

      1. # 但不允许跳转到 tabbar 页面
      2. wx.redirectTo({
      3. url: "/pages/index/index"
      4. })
  4. 跳转到小程序

    • 标签式 ```html打开绑定的小程序
  1. <a name="vSjkU"></a>
  2. ### 路由传参
  3. - 跳转的 tabBar 页面的路径后不能带参数。
  4. 1. 标签式传参
  5. ```html
  6. <navigator wx:for="{{flowerList}}" url="/pages/detail/detail?flowerId={{item.flowerId}}" wx:key="{{flowerId}}"> 路由传参 </navigator>
  • 接收
    1. onLoad: function (options) {
    2. console.log(options.flowerId);
    3. },
  1. 函数式传参
    • 单个参数 ```javascript wx.navigateTo({ url: ‘/pages/detail/detail?flowerId=213213312fwefef’, })
  1. - 多个参数
  2. ```javascript
  3. let obj = {useranme: 'zs',age:100};
  4. # 将对象转成json字符串
  5. let query = JSON.stringify(obj);
  6. wx.navigateTo({
  7. url: '/pages/detail/detail?query='+query,
  8. })

数据缓存

  1. 异步方法

    • 存储数据

      1. wx.setStorage({
      2. key: "key",
      3. data: "value",
      4. });
    • 获取数据

      1. wx.getStorage({
      2. key: "key",
      3. success(res) {
      4. console.log(res.data);
      5. },
      6. });
  2. 同步方法

    • 存储数据 ```javascript wx.setStorageSync(““, ““);

// 例子 let token = ‘asdfasdfasjdflasdjf;asdf;asdfjsak;ldf’; wx.setStorageSync(‘token’,token);

  1. - 获取数据
  2. ```javascript
  3. let token = wx.getStorageSync('token');

进阶

用户授权

  • 用户授权的功能列表,必须绑定点击事件, 用户去点击才能调起授权, 我想应该是腾讯想提醒用户要慎重
  1. 录音授权

    1. wx.authorize({
    2. # 授权类型
    3. scope: "scope.record",
    4. success() {
    5. # 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
    6. console.log('授权成功');
    7. },
    8. });
  2. 获取用户信息授权

    1. getUserProfile(e) {
    2. wx.getUserProfile({
    3. # 必须要有该授权的描述
    4. desc: '用于完善会员资料',
    5. success: (res) => {
    6. console.log(res);
    7. }
    8. })
    9. },
  3. 获取用户手机号码流程文档地址

    1. <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"> 获取手机号码</button>
    1. getPhoneNumber (e) {
    2. console.log(e.detail.errMsg);
    3. console.log(e.detail.iv);
    4. console.log(e.detail.encryptedData);
    5. }
  • 步骤:

    1. 需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据 (跟上面获取用户信息步骤类似)
    2. 调用wx.login接口, 获得一个code
    3. 拿到加密数据之后, 调用后台服务器接口, 把加密数据和 code 传过去
    4. 服务器获得传过去的加密数据之后,对数据进行解密(调用腾讯相关接口),得到了手机号码,再返回给前端

      登录流程

    5. 获取用户信息(需要授权), 绑定点击事件

    6. 获取用户登录需要的code, 调用wx.login
    7. 调用后台登录接口, 传入参数
      1. iv, encryptedData, userInfo(这几个参数在第1步里获得)
      2. code(这个参数在第2步里获得)
    8. 登录成功后获得token
      1. 重置token信息, 以更新当前页面用户状态
      2. 把token存储在缓存里
      3. 调用的接口的时候把token放在请求头上(详看请求封装)
        1. <text bindtap="login">立即登录</text>
        ```javascript Page({

    页面的初始数据

    data: { token: ‘’ },

    登录

    async login() {

    获取用户信息

    let userData = await this.getUserInfo();

    获取code,这行代码不能放在获取用户信息之前

    let code = await this.getCode(); let data = {

    1. code,
    2. iv: userData.iv,
    3. encryptedData: userData.encryptedData,
    4. userInfo: userData.userInfo,

    }

    调用后台登录接口, 传入数据

    app.$post(‘/user/wxlogin’, data).then(res=> {

    1. let token = res.result.token;
    2. this.setData({
    3. token: token
    4. })
    5. # 把token放入缓存
    6. wx.setStorageSync('token', token);

    }).catch(err=> {

    1. console.log(err);

    }) },

获取code

getCode() { return new Promise((resolve, reject) => {

  1. # 获取code(调用微信接口需要)
  2. wx.login({
  3. success(res) {
  4. # 成功之后, 把code保存起来
  5. resolve(res.code);
  6. },
  7. fail(err) {
  8. reject(err);
  9. }
  10. })
  11. })

},

获取用户信息

getUserInfo() {

  1. # 调起用户授权界面,获取用户信息
  2. return new Promise((resolve, reject) => {
  3. wx.getUserProfile({
  4. desc: '用于完善会员资料',
  5. success: (res) => {
  6. # 成功之后,保存用户信息
  7. resolve(res);
  8. },
  9. fail(err) {
  10. reject(err);
  11. }
  12. })
  13. });

} })

获取缓存里的token, 登录成的时候放入的

let token = wx.getStorageSync(“token”); url = baseUrl + url; return new Promise((resolve, reject) => {

请求

wx.request({ url, method, data,

  1. # 把token放入请求头
  2. header: {
  3. "user-token": token
  4. },

}) }

  1. <a name="iFGbg"></a>
  2. ### 地图选址
  3. - [文档地址](https://lbs.qq.com/miniProgram/plugin/pluginGuide/locationPicker)
  4. - [申请开发者密钥(key)](https://lbs.qq.com/dev/console/key/add)
  5. 1. 在 app.json 里添加插件
  6. - 引入插件包: 地图选点 `appId: wx76a9a06e5b4e693e`
  7. ```json
  8. {
  9. "plugins": {
  10. "chooseLocation": {
  11. "version": "1.0.6",
  12. "provider": "wx76a9a06e5b4e693e"
  13. }
  14. }
  15. }
  • 设置定位授权
    1. {
    2. "permission": {
    3. "scope.userLocation": {
    4. "desc": "你的位置信息将用于小程序定位"
    5. }
    6. }
    7. }
  1. 使用插件

    1. <button bindtap="getAddress">获取地址</button>
    2. <view class="mt-10">{{address}}</view>

    ```javascript const chooseLocation = requirePlugin(‘chooseLocation’); Page({ data: { address: ‘’, latitude: ‘’, longitude:’’ },

    getAddress() {

    使用在腾讯位置服务申请的key

    const key = ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’;

    调用插件的app的名称

    const referer = ‘花间小程序’; const location = JSON.stringify({ latitude: this.data.latitude, longitude: this.data.longitude }); const category = ‘生活服务,娱乐休闲’; wx.navigateTo({ url: ‘plugin://chooseLocation/index?key=’ + key + ‘&referer=’ + referer + ‘&location=’ + location + ‘&category=’ + category }); },

onShow() {

  1. # 获取当前位置
  2. wx.getLocation({
  3. type: 'wgs84',
  4. success :(res)=> {
  5. this.setData({
  6. latitude : res.latitude,
  7. longitude : res.longitude
  8. })
  9. }
  10. })
  11. # 选址结束后, 点击确认返回本页面, 下面的代码就能获取选中的地址信息
  12. const location = chooseLocation.getLocation();
  13. this.setData({
  14. address: location && location.name;
  15. })

} })

  1. <a name="JnYfe"></a>
  2. ### 支付流程
  3. - [csdn 参考文档](https://blog.csdn.net/qq_38378384/article/details/80882980)
  4. - [简书 参考文档](https://www.jianshu.com/p/0835f03c3543)
  5. 1. 步骤:
  6. 1. 小程序端请求后端创建订单,把需要的参数传给后台
  7. 1. 后端调用小程序统一下单的 API,获取预支付订单信息,给前端返回预支付信息
  8. 1. [小程序支付流流程](https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3)
  9. 1. [统一下单 api](https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1)
  10. 1. 给前端返回支付所需参数
  11. 3. 小程序端使用 wx.requestPayment 调起支付窗口
  12. 1. [文档地址](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html)
  13. 1. 举例:
  14. ```javascript
  15. <button bindtap="submit">提价订单</button>
  16. const app = getApp();
  17. Page({
  18. submit() {
  19. app.$post('/order/create').then(res => {
  20. let obj = res.result;
  21. # 调用商户端下单接口成功后, 获取所需参数
  22. # 调起微信支付窗口, 传入所需参数
  23. wx.requestPayment({
  24. # 时间戳
  25. timeStamp: obj.timeStamp,
  26. # 随机字符串
  27. nonceStr: obj.nonceStr,
  28. # 统一下单接口返回的 prepay_id 参数值
  29. package: obj.package,
  30. # 签名类型
  31. signType: obj.signType,
  32. # 签名
  33. paySign: obj.paySign,
  34. # 支付成功的回调
  35. success(res) {
  36. console.log(res);
  37. },
  38. # 支付失败的回调
  39. fail(err) {
  40. console.log(err);
  41. },
  42. });
  43. })
  44. },
  45. })
  1. 小程序端查询支付结果,获取结果后给用户展示支付结果
  • 获取支付结果
    1. 方式1: 小程序端轮询商户端获得支付结果
    2. 方式2: 小程序使用socket监听商户服务器socket接口,商户端给小程序推送接口
    3. 相对而言, 使用轮询会消耗一定的性能, 服务器支持的话, 尽量还是使用socket
  • 展示支付结果
    1. 小程序支付模式图

wxa-7-2.jpg

socket

  • http 请求是单向, 服务器不能给web发信息, 而 socket 的双向的, 可以互发信息
  • 微信支付可以使用 socket 由服务器给前端推送支付结果
  1. 服务器端代码
    • app.js ```javascript const Koa = require(“koa”); const path = require(“path”); const websockify = require(“koa-websocket”); const app = websockify(new Koa()); const serv = require(“koa-static”); app.use(serv(__dirname + “/public”));

app.ws.use((ctx, next) => {

给前端发信息

let count = 1; setInterval(() => { ctx.websocket.send( ${count++}. 万能的朋友圈, 想入手一个机械键盘,有没有推荐的, 我两秒后再来问 ); }, 2000);

监听前端发来的信息

ctx.websocket.on(“message”, function (message) { console.log(message); }); });

app.listen(3000,()=>{ console.log(‘http://localhost:3000‘); });

  1. - 根目录创建 public 目录, 然后创建 index.html 文件
  2. ```javascript
  3. <!DOCTYPE html>
  4. <html lang="en">
  5. <head>
  6. <meta charset="UTF-8">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  8. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  9. <title>Document</title>
  10. </head>
  11. <body>
  12. <script>
  13. // 创建sock
  14. var ws = new WebSocket("ws://localhost:3000");
  15. ws.onopen = function (evt) {
  16. console.log("连接成功");
  17. ws.send("我是张三");
  18. };
  19. // 监听服务器信息
  20. ws.onmessage = function (evt) {
  21. document.write("收到服务器端发来的信息: " + evt.data+'<br/>');
  22. };
  23. ws.onclose = function (evt) {
  24. console.log("Connection closed.");
  25. };
  26. </script>
  27. </body>
  28. </html>
  • 小程序代码

    1. Page({
    2. onShow() {
    3. # 连接socket
    4. wx.connectSocket({
    5. url: 'ws://localhost:3000'
    6. }),
    7. # 监听连接状态
    8. wx.onSocketOpen(function (res) {
    9. console.log('socket 已連接')
    10. }),
    11. # 监听服务器信息
    12. wx.onSocketMessage(res=> {
    13. console.log(res);
    14. }),
    15. }
    16. }

    自定义组件

  • 以购物车的结算栏为例
  1. 创建组件
    1. 右键点击开发工具中的 components => 新建目录 count
    2. 右键 count 目录 => 新建组件 => 输入 count(组件的名称)
  2. 编写静态文件

    • wxml文件 ```html 合计 ¥99.00

    结算

    1. - wxss文件
    2. ```css
    3. page {
    4. background: #ebebeb;
    5. }
    6. .count-box {
    7. height: 45px;
    8. background: #fff;
    9. position: fixed;
    10. bottom: 0;
    11. width: 100%;
    12. display: flex;
    13. justify-content: space-between;
    14. padding-left: 20px;
    15. align-items: center;
    16. font-size: 16px;
    17. }
    18. .count-box .money {
    19. color: #e1544d;
    20. margin-left: 5px;
    21. }
    22. .count-box .total {
    23. color: #666;
    24. }
    25. .count-box .count {
    26. text-align: center;
    27. line-height: 45px;
    28. background: #e1544d;
    29. width: 120px;
    30. color: #fff;
    31. }
  1. // js文件暂且不动
  1. 使用组件

    1. 新建一个页面,名字随意,比如 shopCart,
    2. 编写 shopCart 页面的代码
      1. // shopCart.json代码,注册组件
      2. {
      3. "usingComponents": {
      4. "count": "../../components/count/count"
      5. }
      6. }
      1. <!-- shopCart.wxml 代码 -->
      2. <count></count>
      1. // js也暂时不动
  2. 至此我们已经能在 shopCart 页面看到了 count 组件展示出来的内容了

(四) 父给子传参
  1. shopCart.wxml(父组件) 添加一个总价 totalMoney

    1. <count totalMoney="99.99"></count>
    2. // 如果要传变量,请使用
    3. <count totalMoney="{{xxx}}"></count>
  2. count(子组件) 组件接收参数,需要改动两个地方

    • 修改 count.js 文件,在 properties 里添加 ```javascript properties: { totalMoney: Number },

    // 或者写成这样 properties: { totalMoney: {

    1. type: Number,
    2. default: '0.00'

    } }, ```

  • 修改 count.wxml
  1. <count totalMoney="{{totalMoney}}"></count>

(五) 事件和自组件传参
  1. shopCart.wxml(父组件) 自定义一个事件,同时给这个事件绑定一个函数

    1. <count totalMoney="99.00" bind:submit="onSubmit"></count>
  2. shopCart.js(父组件) 编写 onSubmit 函数,event.detail 接收子组件传来的数据

    1. onSubmit(event) {
    2. console.log(event.detail);
    3. },
  3. 修改 count.wxml(子组件), 绑定点击事件

    1. <!-- wxml -->
    2. <view class="count-box">
    3. <view>
    4. <text class="total">合计</text>
    5. <text class="money">¥{{totalMoney}}</text>
    6. </view>
    7. <view class="count" bindtap="handleClick">
    8. 结算
    9. </view>
    10. </view>
  4. 修改 count.js(子组件), 在 methods 添加 handleClick,使用 triggerEvent 触发父组件的自定义事件

    1. methods: {
    2. handlClick() {
    3. this.triggerEvent('submit',{name:'老胡',age: 100})
    4. }
    5. }
  5. 点击结算的时候,父组件的自定义就被触发,控制台打印出{name:’老胡’,age: 100}

(六) 完整代码

自定义组件(子组件)

  1. // count.xml
  2. <view class="count-box">
  3. <view>
  4. <text class="total">合计</text>
  5. <text class="money">¥{{totalMoney}}</text>
  6. </view>
  7. <view class="count" bindtap="handleClick">
  8. 结算
  9. </view>
  10. </view>
  11. // count.wxss
  12. page {
  13. background: #ebebeb;
  14. }
  15. .count-box {
  16. height: 45px;
  17. background: #fff;
  18. position: fixed;
  19. bottom: 0;
  20. width: 100%;
  21. display: flex;
  22. justify-content: space-between;
  23. padding-left: 20px;
  24. align-items: center;
  25. font-size: 16px;
  26. }
  27. .count-box .money {
  28. color: #e1544d;
  29. margin-left: 5px;
  30. }
  31. .count-box .total {
  32. color: #666;
  33. }
  34. .count-box .count {
  35. text-align: center;
  36. line-height: 45px;
  37. background: #e1544d;
  38. width: 120px;
  39. color: #fff;
  40. }
  41. // count.js
  42. Component({
  43. /**
  44. * 组件的属性列表
  45. */
  46. properties: {
  47. totalMoney: Number
  48. },
  49. /**
  50. * 组件的初始数据
  51. */
  52. data: {},
  53. /**
  54. * 组件的方法列表
  55. */
  56. methods: {
  57. handleClick() {
  58. this.triggerEvent("submit", { name: "老胡", age: 100 });
  59. }
  60. }
  61. });

父组件

  1. // shopCart.wxml
  2. <count totalMoney="{{totalMoney}}" bind:submit="onSubmit" />;
  3. // shopCart.js
  4. Page({
  5. data: {
  6. totalMoney: 10000,
  7. },
  8. onSubmit(data) {
  9. console.log("data", data.detail);
  10. },
  11. });