• 微信小程序前后端交互与WXS的应用


    目录

    前言

    一、后台数据交互

    1.数据表

    2.后端代码的实现

    3.前后端交互

    3.1.后端接口URL管理

    3.2.发送后端请求

    3.3.请求方式的封装

    4.前端代码的编写

    二、WXS的使用

    1、.wxs 文件

    2.综合运用


    前言

    当今社交媒体的普及使得微信小程序成为了一种流行的应用开发形式。微信小程序不仅可以提供丰富的用户体验,还能与后台进行交互,实现更多的功能和数据处理。本篇博客将介绍微信小程序如何与后台进行交互,并展示WXS在实际开发中的应用。

    一、后台数据交互

    1.数据表

    2.后端代码的实现

    代码实现也比较简单,这里博主就不过多讲解了 !

    1. package com.ctb.minoa.wxcontroller;
    2. import com.ctb.minoa.mapper.InfoMapper;
    3. import com.ctb.minoa.model.Info;
    4. import com.ctb.minoa.util.ResponseUtil;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import org.springframework.web.bind.annotation.RestController;
    8. import java.util.HashMap;
    9. import java.util.List;
    10. import java.util.Map;
    11. /**
    12. * @Autho biao
    13. *
    14. */
    15. @RestController
    16. @RequestMapping("/wx/home")
    17. public class WxHomeController {
    18. @Autowired
    19. private InfoMapper infoMapper;
    20. @RequestMapping("/index")
    21. public Object index(Info info) {
    22. List infoList = infoMapper.list(info);
    23. Map data = new HashMap();
    24. data.put("infoList",infoList);
    25. return ResponseUtil.ok(data);
    26. }
    27. }

    3.前后端交互

    3.1.后端接口URL管理

    为了方便代码的可维护性,我们将所有接口通过一个文件去保存,我们可以新建一个文件夹config,在文件夹下新建一个api.js的文件

    api.js

    1. // 以下是业务服务器API地址
    2. // 本机开发API地址
    3. var WxApiRoot = 'http://localhost:8080/wx/';
    4. // 测试环境部署api地址
    5. // var WxApiRoot = 'http://192.168.0.101:8070/wx/';
    6. // 线上平台api地址
    7. //var WxApiRoot = 'https://www.oa-mini.com/wx/';
    8. module.exports = {
    9. IndexUrl: WxApiRoot + 'home/index', //首页数据接口
    10. SwiperImgs: WxApiRoot+'swiperImgs', //轮播图
    11. MettingInfos: WxApiRoot+'meeting/list', //会议信息
    12. };

    3.2.发送后端请求

    在所需发送请求的js页面中需引用我们的接口管理api.js

    const api = require("../../config/api")

    发送请求

    1. loadMeetingInfos(){
    2. let that=this;
    3. wx.request({
    4. url: api.IndexUrl,
    5. dataType: 'json',
    6. success(res) {
    7. console.log(res)
    8. that.setData({
    9. lists:res.data.data.infoList
    10. })
    11. }
    12. })
    13. },

    这里我们会有个问题,上述发送后端请求的代码在我们每次发送时都需编写这一长串的代码,会显得代码非常冗余,接下来我们将可以对其进行一个封装,提高代码的复用性

    3.3.请求方式的封装

    我们可以将我们封装的代码写入到我们的utils/util.js文件夹中

    编写请求方式封装方法并将其导出

    1. /**
    2. * 封装微信的request请求
    3. */
    4. function request(url, data = {}, method = "GET") {
    5. return new Promise(function (resolve, reject) {
    6. wx.request({
    7. url: url,
    8. data: data,
    9. method: method,
    10. header: {
    11. 'Content-Type': 'application/json',
    12. },
    13. success: function (res) {
    14. if (res.statusCode == 200) {
    15. resolve(res.data);//会把进行中改变成已成功
    16. } else {
    17. reject(res.errMsg);//会把进行中改变成已失败
    18. }
    19. },
    20. fail: function (err) {
    21. reject(err)
    22. }
    23. })
    24. });
    25. }
    26. module.exports = {
    27. request
    28. }

    注意:在我们所需要使用的js页面中也需进行引入

    const utils = require("../../utils/util.js")
    

    加下来我们将通过我们的封装类重新编写发送请求方式的方法

    1. loadMeetingInfos(){
    2. utils.request(api.IndexUrl).then(res=>{
    3. this.setData({
    4. lists:res.data.infoList
    5. })
    6. }).catch(res=>{
    7. console.log('服器没有开启!')
    8. })
    9. },

    这样代码不仅更简洁明了,还提高了代码的复用性,可为后期实现其它与后台数据交互的效率

    4.前端代码的编写

    wxml

    1. <!--pages/index/index.wxml-->
    2. <!-- <text>pages/index/index.wxml</text> -->
    3. <!-- 轮播图 -->
    4. <view>
    5. <swiper autoplay="true" indicator-dots="true" indicator-color="#fff" indicator-active-color="#00f">
    6. <block wx:for="{{imgSrcs}}" wx:key="text">
    7. <swiper-item>
    8. <view>
    9. <image src="{{item.img}}" class="swiper-item" />
    10. </view>
    11. </swiper-item>
    12. </block>
    13. </swiper>
    14. </view>
    15. <!-- 首页会议信息 -->
    16. <view class="mobi-title">
    17. <text class="mobi-icon"></text>
    18. <text>会议信息</text>
    19. </view>
    20. <block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id">
    21. <view class="list" data-id="{{item.id}}">
    22. <view class="list-img">
    23. <image class="video-img" mode="scaleToFill" src="{{item.seatpic}}"></image>
    24. </view>
    25. <view class="list-detail">
    26. <view class="list-title"><text>{{item.title}}</text></view>
    27. <view class="list-tag">
    28. <view class="state">{{item.state}}</view>
    29. <view class="join"><text class="list-num">{{item.num}}</text>人报名</view>
    30. </view>
    31. <view class="list-info"><text>{{item.location}}</text>|<text>{{item.starttime}}</text></view>
    32. </view>
    33. </view>
    34. </block>
    35. <view class="section bottom-line">
    36. <text>到底啦</text>
    37. </view>

    wxss

    1. /* pages/index/index.wxss */
    2. page{
    3. height: 100%;
    4. background-color: #efeff4;
    5. }
    6. .swiper-item {
    7. height: 300rpx;
    8. width: 100%;
    9. border-radius: 10rpx;
    10. }
    11. .list{
    12. background-color: #fff;
    13. display: flex;
    14. margin: 10rpx;
    15. padding: 10rpx;
    16. }
    17. .list-img,.video-img{
    18. height: 150rpx;
    19. width: 150rpx;
    20. }
    21. .list-img{
    22. margin: 20rpx 0 0 0;
    23. }
    24. .list-detail{
    25. margin: 0 0 0 15rpx;
    26. }
    27. .list-title{
    28. font-weight: 700;
    29. }
    30. .list-tag{
    31. display: flex;
    32. margin: 10px 0;
    33. }
    34. .state{
    35. border: 2px solid lightskyblue;
    36. padding: 2px;
    37. color: lightskyblue;
    38. }
    39. .join{
    40. border: 2px solid #fff;
    41. padding: 2px;
    42. margin: 0 0 0 20rpx;
    43. color: gray;
    44. }
    45. .list-num{
    46. color: red;
    47. }
    48. .list-info{
    49. color: gray;
    50. }
    51. .bottom-line{
    52. text-align: center;
    53. margin-bottom: 10px;
    54. }

    js

    1. // pages/index/index.js
    2. const api = require("../../config/app")
    3. const utils = require("../../utils/util.js")
    4. Page({
    5. /**
    6. * 页面的初始数据
    7. */
    8. data: {
    9. imgSrcs:[
    10. {
    11. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner1.png",
    12. "text": "1"
    13. },
    14. {
    15. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner2.png",
    16. "text": "2"
    17. },
    18. {
    19. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner3.png",
    20. "text": "3"
    21. },
    22. {
    23. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner4.png",
    24. "text": "4"
    25. },
    26. {
    27. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner5.png",
    28. "text": "5"
    29. },
    30. {
    31. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner6.png",
    32. "text": "6"
    33. }]
    34. ,lists:[]
    35. },
    36. // loadSwiperImgs(){
    37. // let that=this;
    38. // // http://localhost:8080/demo/wx/swiperImgs
    39. // wx.request({
    40. // url: api.SwiperImgs,
    41. // dataType: 'json',
    42. // success(res) {
    43. // console.log(res)
    44. // that.setData({
    45. // imgSrcs:res.data.images
    46. // })
    47. // }
    48. // })
    49. // },
    50. loadMeetingInfos(){
    51. // let that=this;
    52. // wx.request({
    53. // url: api.IndexUrl,
    54. // dataType: 'json',
    55. // success(res) {
    56. // console.log(res)
    57. // that.setData({
    58. // lists:res.data.data.infoList
    59. // })
    60. // }
    61. // })
    62. utils.request(api.IndexUrl).then(res=>{
    63. this.setData({
    64. lists:res.data.infoList
    65. })
    66. }).catch(res=>{
    67. console.log('服器没有开启!')
    68. })
    69. },
    70. /**
    71. * 生命周期函数--监听页面加载
    72. */
    73. onLoad(options) {
    74. // this.loadSwiperImgs();
    75. this.loadMeetingInfos();
    76. },
    77. /**
    78. * 生命周期函数--监听页面初次渲染完成
    79. */
    80. onReady() {
    81. },
    82. /**
    83. * 生命周期函数--监听页面显示
    84. */
    85. onShow() {
    86. },
    87. /**
    88. * 生命周期函数--监听页面隐藏
    89. */
    90. onHide() {
    91. },
    92. /**
    93. * 生命周期函数--监听页面卸载
    94. */
    95. onUnload() {
    96. },
    97. /**
    98. * 页面相关事件处理函数--监听用户下拉动作
    99. */
    100. onPullDownRefresh() {
    101. },
    102. /**
    103. * 页面上拉触底事件的处理函数
    104. */
    105. onReachBottom() {
    106. },
    107. /**
    108. * 用户点击右上角分享
    109. */
    110. onShareAppMessage() {
    111. },
    112. })

    效果演示

    通过数据表与效果演示,我们可以看出一些问题,比如状态值不应该显示数字,而是所对应的状态,报名人数的显示,时间的格则等接下来我们将通过WXS给大家解决一些诸如此类的问题

    二、WXS的使用

    WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。

    WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。

    WXS模块

    每一个 .wxs 文件和  标签都是一个单独的模块。

    每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。

    一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现

    1、.wxs 文件

    微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。

    示例代码:

    1. // /pages/comm.wxs
    2. var foo = "'hello world' from comm.wxs";
    3. var bar = function(d) {
    4. return d;
    5. }
    6. module.exports = {
    7. foo: foo,
    8. bar: bar
    9. };

    上述例子在 /pages/comm.wxs 的文件里面编写了 WXS 代码。该 .wxs 文件可以被其他的 .wxs 文件 或 WXML 中的  标签引用。

    module 对象

    每个 wxs 模块均有一个内置的 module 对象。

    属性

    • exports: 通过该属性,可以对外共享本模块的私有变量与函数。

    示例代码:

    1. // /pages/tools.wxs
    2. var foo = "'hello world' from tools.wxs";
    3. var bar = function (d) {
    4. return d;
    5. }
    6. module.exports = {
    7. FOO: foo,
    8. bar: bar,
    9. };
    10. module.exports.msg = "some msg";

    在需要使用的wxml页面中引用 

    1. <wxs src="./../tools.wxs" module="tools" />
    2. <view> {{tools.msg}} view>
    3. <view> {{tools.bar(tools.FOO)}} view>

    页面输出:

    1. some msg
    2. 'hello world' from tools.wxs

    2.综合运用

    下面我们将对上面前后端数据交互后所遇到的一些问题进行解决

    数字转换问题

    1. //将状态值赋值为中文
    2. function getState(state){
    3. // 状态:0取消会议1待审核2驳回3待开4进行中5开启投票6结束会议,默认值为1
    4. if(state == 0 ){
    5. return '取消会议';
    6. }else if(state == 1 ){
    7. return '待审核';
    8. }else if(state == 2 ){
    9. return '驳回';
    10. }else if(state == 3 ){
    11. return '待开';
    12. }else if(state == 4 ){
    13. return '进行中';
    14. }else if(state == 5 ){
    15. return '开启投票';
    16. }else if(state == 6 ){
    17. return '结束会议';
    18. }
    19. return '其它';
    20. }

    通过状态值去判断会议状态内容 

    人数计算问题

    1. // 将参与者,列席者,主持人---参与会议的人数进行统计
    2. function getNumber(canyuze, liexize, zhuchiren) {
    3. var person = canyuze + "," + liexize + "," + zhuchiren;
    4. var arr = person.split(",");
    5. // 进行数组去重
    6. var res = [];
    7. for (var i = 0; i < arr.length; i++) {
    8. if (res.indexOf(arr[i]) === -1) {
    9. res.push(arr[i]);
    10. }
    11. }
    12. return res.length;
    13. }

    将所有参会人员统计并进行截取和去重

    时间格式问题

    1. // 将时间格式化---调成想要相对应的格式
    2. function formatDate(ts, option) {
    3. var date = getDate(ts)
    4. var year = date.getFullYear()
    5. var month = date.getMonth() + 1
    6. var day = date.getDate()
    7. var week = date.getDay()
    8. var hour = date.getHours()
    9. var minute = date.getMinutes()
    10. var second = date.getSeconds()
    11. //获取 年月日
    12. if (option == 'YY-MM-DD') return [year, month, day].map(formatNumber).join('-')
    13. //获取 年月
    14. if (option == 'YY-MM') return [year, month].map(formatNumber).join('-')
    15. //获取 年
    16. if (option == 'YY') return [year].map(formatNumber).toString()
    17. //获取 月
    18. if (option == 'MM') return [mont].map(formatNumber).toString()
    19. //获取 日
    20. if (option == 'DD') return [day].map(formatNumber).toString()
    21. //获取 年月日 周一 至 周日
    22. if (option == 'YY-MM-DD Week') return [year, month, day].map(formatNumber).join('-') + ' ' + getWeek(week)
    23. //获取 月日 周一 至 周日
    24. if (option == 'MM-DD Week') return [month, day].map(formatNumber).join('-') + ' ' + getWeek(week)
    25. //获取 周一 至 周日
    26. if (option == 'Week') return getWeek(week)
    27. //获取 时分秒
    28. if (option == 'hh-mm-ss') return [hour, minute, second].map(formatNumber).join(':')
    29. //获取 时分
    30. if (option == 'hh-mm') return [hour, minute].map(formatNumber).join(':')
    31. //获取 分秒
    32. if (option == 'mm-dd') return [minute, second].map(formatNumber).join(':')
    33. //获取 时
    34. if (option == 'hh') return [hour].map(formatNumber).toString()
    35. //获取 分
    36. if (option == 'mm') return [minute].map(formatNumber).toString()
    37. //获取 秒
    38. if (option == 'ss') return [second].map(formatNumber).toString()
    39. //默认 时分秒 年月日
    40. return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
    41. }
    42. function formatNumber(n) {
    43. n = n.toString()
    44. return n[1] ? n : '0' + n
    45. }
    46. function getWeek(n) {
    47. switch(n) {
    48. case 1:
    49. return '星期一'
    50. case 2:
    51. return '星期二'
    52. case 3:
    53. return '星期三'
    54. case 4:
    55. return '星期四'
    56. case 5:
    57. return '星期五'
    58. case 6:
    59. return '星期六'
    60. case 7:
    61. return '星期日'
    62. }
    63. }

    将日期格式进行转换

    注:最后需要将所有方法进行导出

    1. module.exports = {
    2. getState: getState,
    3. getNumber:getNumber,
    4. formatDate:formatDate
    5. };

    在wxml中引用

    1. <!--pages/index/index.wxml-->
    2. <!-- <text>pages/index/index.wxml</text> -->
    3. <!-- 轮播图 -->
    4. <view>
    5. <swiper autoplay="true" indicator-dots="true" indicator-color="#fff" indicator-active-color="#00f">
    6. <block wx:for="{{imgSrcs}}" wx:key="text">
    7. <swiper-item>
    8. <view>
    9. <image src="{{item.img}}" class="swiper-item" />
    10. </view>
    11. </swiper-item>
    12. </block>
    13. </swiper>
    14. </view>
    15. <!-- 首页会议信息 -->
    16. <wxs src="/utils/comm.wxs" module="tools" />
    17. <view class="mobi-title">
    18. <text class="mobi-icon"></text>
    19. <text>会议信息</text>
    20. </view>
    21. <block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id">
    22. <view class="list" data-id="{{item.id}}">
    23. <view class="list-img">
    24. <image class="video-img" mode="scaleToFill" src="{{item.seatpic}}"></image>
    25. </view>
    26. <view class="list-detail">
    27. <view class="list-title"><text>{{item.title}}</text></view>
    28. <view class="list-tag">
    29. <view class="state">{{tools.getState(item.state)}}</view>
    30. <view class="join"><text class="list-num">{{tools.getNumber(item.canyuze,item.liexize,item.zhuchiren)}}</text>人报名</view>
    31. </view>
    32. <view class="list-info"><text>{{item.location}}</text>|<text>{{tools.formatDate(item.starttime)}}</text></view>
    33. </view>
    34. </view>
    35. </block>
    36. <view class="section bottom-line">
    37. <text>到底啦</text>
    38. </view>

    效果演示

  • 相关阅读:
    Nacos安装使用
    【农业生产模拟】WOFOST模型与PCSE模型实践
    通过Dynamo批量打印PDF图纸
    TypeScript 最细项目实践:四步走高效改造现有的 JavaScript 项目
    6.qml中js的object,array数据更新不通知页面刷新问题解析
    国内近五年人工智能教育的研究热点及趋势——基于多维尺度和社会网络分析的方法
    C/C++随笔:指针与const、const数组
    静态HTML旅行主题网页作业——青岛民俗7页html+css+javascript+jquery 地方民俗网页设计与实现
    在springboot中整合mybatis配置流程!
    《家的温暖,国庆团圆》
  • 原文地址:https://blog.csdn.net/weixin_74268571/article/details/133952389