IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 从零开始快速搭建SpringBoot+Mybatis+小程序应用--微信小程序的入门和前后端的联调 -> 正文阅读

[移动开发]从零开始快速搭建SpringBoot+Mybatis+小程序应用--微信小程序的入门和前后端的联调

目录

项目介绍

?vx小程序简介

VX开发工具介绍

列表页开发

list的编写?

?列表页前后端联调

?信息编辑页开发

operation的编写

区域信息编辑页的联调


项目介绍

从0搭建后端的Springboot+mybatis框架

实现后端的业务功能

实现本地微信小程序的前端开发

前端与后端的调控

技术储备要求

1.基础的java知识

2.基础的前端开发知识(简单了解HTML,JS等)

3.Spring,Mybatis基础知识(不会也没关系)


?vx小程序简介

是一种连接用户服务的方式,小程序是vx内嵌的微小程序。

?根目录有一个app.json和project.json,是用来做全职配置的

?

每生成一个页面,就在pages上写一个路由?。

工具配置 project.config.json(vx会自动,透明的完成)

页面配置 page.json

xxx.json就是针对xxx页面下的风格、配色等相关的配置

?WXML模板 充当HTML的角色

具体不同参照vx开发者文档

WXSS模板 充当CSS的角色?

JS交互文件


VX开发工具介绍

集成了公众号网页调试和小程序调试两种开发模式

打开我们的开发工具:

?vx的开发者工具主要由模拟器,编辑器和调试器

模拟器就类似我们的页面UI,我们对页面做的任何改变都能看到我们小程序的样子。

?编辑器就是我们能够在里面写我们的wxml,wxss,还有js等,

?调试器就类似我们网页Chrome里面的开发者工具,我们能够在控制台里看见报错的信息。


3.创建新的小程序

创建新的小程序,指定项目的目录

?项目一旦启动,就会初始化两个界面出来

?


列表页开发

1.列表展示

2.删除功能

最终效果:

首先我们要掌握一些主键的功能:

?view与div一样是个视图容器

?scroll-view可滚动视图区

?text文本

?navigator类似html的a标签(超链接)

?button 按钮

?block区块 可以在里面写逻辑


项目准备:

index.js:

//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    motto: 'Hello World',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({//导航到list页面下
      url: '../list/list'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          //
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  }
})

index.wxml:

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>

index.wxss:

/**index.wxss**/
.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.userinfo-avatar {
  width: 128rpx;
  height: 128rpx;
  margin: 20rpx;
  border-radius: 50%;
}

.userinfo-nickname {
  color: #aaa;
}

.usermotto {
  margin-top: 200px;
}


list的编写?

list.wxml:

<!-- pages/list/list.wxml -->

<view class="container">
  <view class="widget">
    <text class="column">ID</text>
    <text class="column">区域名</text>
    <text class="column">优先级</text>
    <text class="link-column">操作</text>
  </view>
   <!-- 滚动 -->
  <scroll-view scroll-y="true">
    <view>
    <!-- 循环,list任意命名 -->
      <block wx:for="{{list}}">
        <view class="widget">
          <view>
          <!-- 取每一个的元素 -->
            <text class="column">{{item.areaId}}</text>
            <text class="column">{{item.areaName}}</text>
            <text class="column">{{item.priority}}</text>
            <view class="link-column">
            <!-- 操作是固定的 url:是链接到我们需要的界面区域信息表单 -->
            <!--传递了参数,areaId-->
              <navigator class="link" url="../operation/operation?areaId={{item.areaId}}">编辑</navigator>|
              <!-- 点击删除,会启动事件deleteArea 它会读取控件里的areaId 还有 areaName ,删除之后也要删除界面里的一条信息-->
              <text class="link" bindtap="deleteArea" data-areaid="{{item.areaId}}" data-areaname="{{item.areaName}}" data-index="{{index}}">删除</text>
            </view>
          </view>
        </view>
      </block>
    </view>
  </scroll-view>
  <!-- tap与点击相关 -->
  <button type="primary" bindtap="addArea">添加区域信息</button>
</view>

?list.wxss:

/* pages/list/list.wxss */

.widget {
  position: relative;
  margin-top: 5rpx;
  margin-bottom: 5rpx;
  padding-top: 10rpx;
  padding-bottom: 10rpx;
  padding-left: 40rpx;
  padding-right: 40rpx;
  border: #ddd 1px solid;
}

.container {
  height: 100%;
  display: table;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
  padding-top: 10rpx;
  padding-bottom: 10rpx;
  text-align: center;
}

.column {
  width: 4rem;
  display: table-cell;
}

.link-column {
  width: 6rem;
  display: table-cell;
}

.link {
  color: blue;
  display: inline-table;
}

list.js

// pages/list/list.js
Page({

  /**
   * 页面的初始数据,wxml想读取的list,就是从data中获取
   */
  data: {
    list: []
  },

  /**
   * 生命周期函数--监听页面加载
   * -当页面加载时,就会触发里面的方法
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   * 当页面显示时,就会触发里面的方法
   */
  onShow: function () {
    var that = this;
    //第一个this,表示的是整个页面
    // 访问后台,获取区域信息
    wx.request({
      //url去访问后台的方法,获取它的areaList的值,127.0.0.1,端口8080,生效的是demo/superadmin/listarea
      url: "http://127.0.0.1:8080/demo/superadmin/listarea",
      data: {},
      //访问方法
      method: 'GET',
      //访问成功之后需要做的事情
      success: function (res) {
        var list = res.data.areaList;
        if (list == null) {
          //弹出获取失败
          var toastText = '获取数据失败' + res.data.errMsg;
          wx.showToast({
            title: toastText,
            icon: '',
            // 出错窗口,弹出两秒钟
            duration: 2000
          });
        } else {
          //此时this变化,所以要用最开始的this(that)才能够设置上data里面的list
          that.setData({
            list: list
          });
        }
      }
    })
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  addArea: function () {
    //跳转界面,但是没有传参
    wx.navigateTo({
      url: '../operation/operation',
    })
  },
  deleteArea: function (e) {    
    //保存窗口
    var that = this;
    //判断是否进行操作
    wx.showModal({
      title: '提示',
      //区域名的获取通过,这里传入的参数是e,e代表的是控键text
      content: '确定要删除[' + e.target.dataset.areaname + ']吗?',
      //用户点击确认就能访问后台
      success: function (sm) {
        if (sm.confirm) {
          // 用户点击了确定 可以调用删除方法了
          wx.request({
            url: "http://127.0.0.1:8080/demo/superadmin/removearea",
            //传入areaId
            data: { "areaId": e.target.dataset.areaid },
            method: 'GET',
           
            success: function (res) {
              //一旦返回获取result,获取success的字段
              var result = res.data.success
              var toastText = "删除成功!";
              if (result != true) {
                toastText = "删除失败" + res.data.errMsg;
              } else{
                //删除成功也需要将list原来的数据删除,index表示数组的第几行,删除1个
                that.data.list.splice(e.target.dataset.index, 1)
                //渲染数据
                //删除成功之后,重新setData
                that.setData({
                  list: that.data.list
                });
              }
              //不管删除是否成功,都会弹出我们之前提前设定好的toastText
              wx.showToast({
                title: toastText,
                icon: '',
                //弹出两秒钟
                duration: 2000
              });
            }
          })
        }
      }
    })
  }
})

onLoad与onShow的区别,即页面的加载与显示的区别:

当我们从operation返回list界面时,不会触发onLoad,只会触发onShow,通过触发列表访问方法,来更新此时我们页面最新的信息。所以我们要在onShow里面编写我们的方法。

勾选上:不校验合法域名等,此时我们才能使url有效,因为vx不会默认端口访问?


?列表页前后端联调

选择list.js,打开调试器,进行断点调试

第一个断点设置在deleteArea方法内

?我们还要在后台进行调试,即removerarea,这里设置一个断点,注意用debug的形式启动

启动好之后,回到我们的页面,选择删除东苑,它就会进入到我们deleteArea里设置好的断点,

我们可以查看this里面就是页面句柄。

?点击F10进入下一步,这里它就会弹出窗口,提示你是否删除东苑。

第二步将断点打在97行,就是if里面,如果用户操作点击了确定,点击F8跳入我们的下一个断点,

如果没有跳断点,就执行完所有的。它通过判断confirm,我们这里是true,所以就会wx.request去访问我们的后台。

接着我们要在在success方法里设置断点,因为它这时候会访问我们的后台,断点就会进入我们的后台方法中,执行完之后,才会返回来。

这里进入到我们idea的断点中,我们在idea中做调试,此时areaId传进来了,为1.

我们直接点击step over(F8)

我们可以看见modelMap,?key为success,value为true,表示删除操作成功。我们完成了验证。接着我们跳出后台,就能发现我们的断点来到了103行,这里的success为true。

点击F10下一步删除成功,我们调用setData更新List,之后showToast,它将删除成功的弹窗弹出。

这里就完成了我们区域列表的开发。


?信息编辑页开发

区域信息添加

区域信息更新

operation的编写

?operation.wxml:

<!--pages/operation.wxml-->
<view class="container">
<!-- 属性绑定formSubmit方法,bindreset绑定框架默认自带的formReset,会自动清空里面的内容,包括区域名 -->
<!-- formSubmit需要我们自己去编写 -->
  <form bindsubmit="formSubmit" bindreset="formReset">
    <view class="row">
      <text>区域名:</text>
      <input type="text" name="areaName" placeholder="请输入区域名" value="{{areaName}}" />
    </view>
    <view class="row">
      <text>优先级:</text>
      <input type="number" name="priority" placeholder="数值越大越靠前" value="{{priority}}" />
    </view>
    <view class="row">
    
      <button type="primary" form-type="submit">提交</button>
      <!-- 点击,框架自带的formReset就会清空 -->
      <button type="primary" form-type="reset">清空</button>
    </view>

  </form>
</view>

?operation.js:

// pages/operation.js
Page({

  /**
   * 页面的初始数据
   * 需要用到的全局变量放在这里
   */
  data: {
    // list里面我们会通过点击添加或者点击编辑进入到这个界面,我们通过有没有携带areaId参数来判断。
    areaId: undefined,
    areaName: '',
    priority: '',
    // 访问我们后台区域和修改区域的url
    addUrl: "http://127.0.0.1:8080/demo/superadmin/addarea",
    modifyUrl: "http://127.0.0.1:8080/demo/superadmin/modifyarea"

  },
  /**
   * 生命周期函数--监听页面加载
   */
  //这里用onLoad是因为这个界面没有返回按钮,每次打开它都是重新加载,当然用onShow也可以
  onLoad: function (options) {
    var that = this;
    // 页面初始化 options为页面跳转所带来的参数
    this.setData({
      areaId: options.areaId
    });
    if (options.areaId == undefined) {
      return;
    }
    wx.request({
      url: "http://127.0.0.1:8080/demo/superadmin/getareabyid",
      data: { "areaId": options.areaId },
      method: 'GET',
      success: function (res) {
        var area = res.data.area;
        if (area == undefined) {
          var toastText = '获取数据失败' + res.data.errMsg;
          wx.showToast({
            title: toastText,
            icon: '',
            duration: 2000
          });
        } else {
          that.setData({
            areaName: area.areaName,
            priority: area.priority
          });
        }
      }
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  //参数e表示表单
  formSubmit: function (e) {
    var that = this;
    //这个formData的json数据就是表单里的areaName,priorty的值
    var formData = e.detail.value;
    var url = that.data.addUrl;
    if (that.data.areaId != undefined) {
      //不为undefined,就是编辑的
      formData.areaId = that.data.areaId;
      url = that.data.modifyUrl;
    }
    //进入后台
    wx.request({
      url: url,
      //通过JSON.stringify将json转化为字符串的形式
      //formData如果为添加,仅有areaName和priority,如果是更改,还多了一个areaId
      data: JSON.stringify(formData),
      method: 'POST',
      header: {
        'Content-Type': 'application/json'
      },
      //添加或者更改成功就会返回一给success
      success: function (res) {
        var result = res.data.success
        var toastText = "操作成功!";
        if (result != true) {
          toastText = "操作失败" + res.data.errMsg;
        }
        wx.showToast({
          title: toastText,
          icon: '',
          duration: 2000
        });
        //这里一旦提交成功,它就会返回我们的list页面
        if (that.data.areaId == undefined) {
          wx.redirectTo({
            url: '../list/list',
          })
        }
      }
    })
  }
})

operation.wxss:

/* pages/operation/operation.wxss */
.container{
    padding: 1rem;
    font-size: 0.9rem;
    line-height: 1.5rem;
}
.row{
    display: flex;
    align-items: center;
    margin-bottom: 0.8rem;
}
.row text{
    flex-grow: 1;
    text-align: right;
}
.row input{
    font-size: 0.7rem;
    flex-grow: 3;
    border: 1px solid #0099CC;
    display: inline-block;
    border-radius: 0.3rem;
    box-shadow: 0 0 0.15rem #aaa;
    padding: 0.3rem;
}
.row button{
    padding: 0 2rem;
    margin: 3rem 1rem;
}

区域信息编辑页的联调

设置断点

?

?后台也要设置想应断点

?开始调试:

?获取到了area信息

?f8获取,发现数据被填充进来

?修改优先级为3,

?

?后台接收到了。最后f8,发现更新成功。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:53:18  更:2022-10-08 20:57:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:31:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码