新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

医疗急救卡

介绍

该小程序实现了form表单的写入以及对数据的增加,修改,删除,查询的功能。将写入的数据存入小程序的本地缓存Storage中,对缓存数据进行操作,同时对一些表单数据进行了表单验证功能。

要求

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

示例

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

导读指导

1. 什么是本地缓存?

每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage/wx.setStorageSync、 wx.getStorage/wx.getStorageSync、 wx.clearStorage/wx.clearStorageSync
wx.removeStorage/wx.removeStorageSync

对本地缓存进行读写和清理。上面的set和get都有对应的Sync方法,带Sync的方法为同步方法、不带Sync的方法为异步方法。

缓存可以保存数组、数值、字符串、对象。

不懂可以继续看一看官方文档
微信开放文档

2.什么是form表单?

表单。将组件内的用户输入的switch input checkbox slider radio picker 提交。

当点击 form 表单中 form-type 为 submit 的 button 组件时,会将表单组件中的 value 值进行提交,需要在表单组件中加上 name 来作为 key。

先看一下部分代码

    在代码
    <form bindsubmit="{{!create ? 'onSubmit':'Updated'}}" bindreset="
    {{!create ? 'onReset':'Deleted'}}">
    我采取了动态绑定函数。在上一个音乐播放器中也是这样,
    因为这样写可以省略许多的代码,使代码格式简洁。
    因为创建表单信息和修改表单信息,都是通过对整个form进行操作。
    
    当点击完成创建按钮时,表单会调用onSubmit函数,同时拿到整个表单中的值。
    写入的值可以通过 e.detail.value 拿取。
    <view class="demo-box" wx:if="{{!create}}"> 
        <button class="button" formType="submit">完成创建</button> 
        <button class="button" formType="reset">重置医疗急救卡</button> 
    </view> 
    <view class="demo-box" wx:else> 
        <button class="button" bindtap="Callphone">打电话给紧急联系人</button> 
        <button class="button" formType="submit">编辑医疗急救卡</button> 
        <button class="button" formType="reset" bindtap="onReset">删除医疗急救卡 </button> 
        <button class="button" bindtap="Clear">删除所有医疗急救卡</button>
    </view>
wxml
<!--pages/saveCard/saveCard.wxml-->
<view class="container">
  <view class="demo-box">
    <form bindsubmit="{{!create ? 'onSubmit':'Updated'}}" 
    bindreset="{{!create ? 
    'onReset':'Deleted'}}">
      <view class="box center">
        <picker end="{{Time}}" fields="day" name="date" mode="date" 
        bindchange="dateChange">
          <span class="title">出生日期
          </span>
          {{date}}
        </picker>
      </view>
      <view class="box">
        <text class="title">医疗状况</text>
        <scroll-view class="scroll" scroll-y>
          <textarea placeholder="无" name="health" value="{{health}}" />
        </scroll-view>
      </view>
      <view class="box">
        <text class="title">医疗笔记</text>
        <scroll-view class="scroll" scroll-y>
          <textarea placeholder="无" name="note" value="{{note}}" />
        </scroll-view>
      </view>
      <view class="box">
        <text class="title">过敏反应</text>
        <scroll-view class="scroll" scroll-y>
          <textarea placeholder="无" name="action" value="{{action}}" />
        </scroll-view>
      </view>
      <view class="box">
        <text class="title">用药</text>
        <scroll-view class="scroll" scroll-y>
          <textarea placeholder="无" name="medicine" value="{{medicine}}" />
        </scroll-view>
      </view>
      <view class="box center">
        <picker name="blood" class="" mode="selector" range="{{blood}}" 
        bindchange="selectorChange">
          <span class="title">血型
          </span>
          {{selector}}
        </picker>
      </view>
      <view class="box center">
        <span class="title">器官捐赠者
        </span>
        <switch name="switch" bindchange="switchChange" />
      </view>
      <view class="box center">
        <view class="high">
          <view class="title">身高
          </view>
          <input name="high" value="{{high}}" type="number" />厘米
        </view>
        <view class="weight">
          <view class="title">体重
          </view>
          <input name="weight" value="{{weight}}" type="number" />千克
        </view>
      </view>
      <view class="box">
        <span class="title">紧急联系人号码
        </span>
        <input name="phoneNumber" value="{{phoneNumber}}" type="number" />
      </view>
      <view class="demo-box" wx:if="{{!create}}">
        <button class="button" formType="submit">完成创建</button>
        <button class="button" formType="reset">重置医疗急救卡</button>
      </view>
      <view class="demo-box" wx:else>
        <button class="button" bindtap="Callphone">打电话给紧急联系人</button>
        <button class="button" formType="submit">编辑医疗急救卡</button>
        <button class="button" formType="reset" 
        bindtap="onReset">删除医疗急救卡</button>
        <button class="button" bindtap="Clear">删除所有医疗急救卡</button>
      </view>
    </form>
  </view>

</view>

正式开启小程序实战

时间选择器-picker

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

wxml
    // End 是picker 自带的api 可以对时间选择器进行范围控制
    // 我采取了动态绑定 实现了 当前选择器不能选择超过当前日子的时间
    // fields有效值 year,month,day,表示选择器的粒度 
 <view class="box center">
        <picker end="{{Time}}" fields="day" name="date" mode="date" bindchange="dateChange">
          <span class="title">出生日期
          </span>
          {{date}}
        </picker>
 </view>
// 获取当前时间 并转换格式 year-month-day
let month = Number(new Date().getMonth() + 1) < 10 ? '0' + 
Number(new Date().getMonth() + 
1) : Number(new Date().getMonth() + 1)
let day = new Date().getDate() < 10 ? '0' + new Date().getDate() 
: new Date().getDate()
var Time = new Date().getFullYear() + '-' + month + '-' + day
// 确保时间 是动态 的数据
onLoad(options) {
    this.setData({
      Time: Time
    })
  },

// 动态改变选择器的值
dateChange: function (e) {
    let value = e.detail.value;
    this.setData({
      date: value
    })
  },

textarea文本输入框

文本输入框只能有一行显示,并且带有滚动效果。

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

wxml
利用scroll-y 实现滚动效果 不过要设置一个固定的高度。
<view class="box">
        <text class="title">医疗状况</text>
        <scroll-view class="scroll" scroll-y>
          <textarea placeholder="无" name="health" value="{{health}}" />
        </scroll-view>
</view>

单列选择器-血型-picker

注意这里的selector通过表单拿到的数据为blood的一个下标

因为 blood: [‘未知’, ‘A型’, ‘B型’, ‘C型’, ‘AB型’, ‘O型’]

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

wxml
 <view class="box center">
        <picker name="blood" class="" mode="selector" range="{{blood}}" 
        bindchange="selectorChange">
          <span class="title">血型
          </span>
          {{selector}}
        </picker>
 </view>
js
// 动态改变选择器的值
// 将拿到的i进行重新获取 血型再继续赋值
 selectorChange: function (e) {
    let i = e.detail.value;
    let value = this.data.blood[i];
    this.setData({
      selector: value
    })
  },

switch选择器

注意事项,就是在管理页面显示的时候我们是以 是,否 显示,所以要创建一个键值对对象包含该值
而创建页中,我们只是单纯以switch 开关显示。

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

wxml
创建页
  <view class="box center">
        <span class="title">器官捐赠者
        </span>
        <switch checked="{{Donated}} name="switch" bindchange="switchChange" />
  </view>
  
  
  
  管理页
  显示
  
   <view class="box center">
          <view class="small-box">
            <span class="title">是否是器官捐赠者 </span>
            {{Donated[switch]}}
          </view>
    </view>
    修改
    //  checked 动态绑定
   <view class="box center">
          <span class="title">器官捐赠者
          </span>
          <switch checked="{{switch}}" name="switch" bindchange="switchChange" />
    </view>
js
// 创建页
 Donated: false,
 
 switchChange: function (e) {4
    let value = e.detail.value;
    this.setData({
      Donated: value
    })
  }
  
  
  // 管理页
   Donated: {
      false: '否',
      true: '是'
    },
    switch: '',

单文本输入框

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

wxml
<view class="box center">
        <view class="high">
          <view class="title">身高
          </view>
          <input name="high" value="{{high}}" type="number" />厘米
        </view>
        <view class="weight">
          <view class="title">体重
          </view>
          <input name="weight" value="{{weight}}" type="number" />千克
        </view>
</view>

创建功能实现

实现了表单验证功能,保证出生日期,血型,以及电话号码为必填项,且非必填会自动默认为空。
将表单提交中拿到的血型的下标 重新拿取血型值,并赋值给缓存中的blood,将数据存入到本地缓存,并创建一个独特的key。

js
 onSubmit(e) {
    // console.log(e.detail);
    var that = this;
    
    // 实现表单验证
    if (e.detail.value.date === '') {
      wx.showToast({
        title: '出生日期为空',
        duration: 500,
        icon: 'none'
      })
    } else if (e.detail.value.blood === '') {
      wx.showToast({
        title: '血型未选择',
        duration: 500,
        icon: 'none'
      })
    } else if (e.detail.value.phoneNumber === '') {
      wx.showToast({
        title: '电话号码为空',
        duration: 500,
        icon: 'none'
      })
    } else {
        // 非必填项 默认为空
      if (this.data.health === '') {
        e.detail.value.health = '空'
      }
      if (this.data.note === '') {
        e.detail.value.note = '空'
      }
      if (this.data.action === '') {
        e.detail.value.action = '空'
      }
      if (this.data.medicine === '') {
        e.detail.value.medicine = '空'
      }
      
     //  将表单提交的数据进行赋值 
      that.setData({
        create: true,
        date: e.detail.value.date,
        health: e.detail.value.health,
        note: e.detail.value.note,
        action: e.detail.value.action,
        medicine: e.detail.value.medicine,
        Donated: e.detail.value.switch,
        high: e.detail.value.high,
        weight: e.detail.value.weight,
        phoneNumber: e.detail.value.phoneNumber
      })
      // console.log(e.detail.value);
      
      let i = e.detail.value.blood
      e.detail.value.blood = that.data.blood[i]
      // console.log('form发生了submit事件,携带数据为:', e.detail.value)
      // console.log(this.data);
      // 最后进行介绍
      if (!app.globalData.Number.includes(app.globalData.count)) {
        app.globalData.Number.push(app.globalData.count)
        app.globalData.count++;
      } else {
       
        app.globalData.count++;
        if(app.globalData.Number.includes(app.globalData.count)){
          for(let i=1;i<app.globalData.Number.length;i++){
            if(!app.globalData.Number.includes(i)){
              app.globalData.Number.push(i)
            }
          }
        }
        else{
          app.globalData.Number.push(app.globalData.count)
        }
      }



      // console.log(app.globalData.count, '???', app.globalData.Number);
      wx.setStorage({
        key: myCard + app.globalData.Number[app.globalData.Number.length-1],
        data: e.detail.value,
        // 若开启加密存储,setStorage 和 getStorage 需要同时声明 encrypt 的值为 true
        success: function (res) {
          wx.showToast({
            title: myCard + app.globalData.Number[app.globalData.Number.length-1] + '创建成功',
            icon: 'none',
            duration: 500
          })
        }
        
      })

    }
  },

删除功能

部分删除

删除当前正在编辑的数据,如果删除完后,按弹窗的取消将返回首页,按确定将再次进行一次删除操作。如果数据被删完了,则弹出数据为0,无法删除的提示,并且返回首页。

js
Deleted: function (e) {
    if (app.globalData.count === 0 && app.globalData.Number[app.globalData.Number.length - 1] === 0) {
      wx.showToast({
        title: '数据为0,无法删除',
        icon: 'none'
      })
      setTimeout(() => {
        wx.navigateBack({
          url: '/pages/index/index',
        })
      }, 1000)

    } else {
      let name = myCard + app.globalData.Number[app.globalData.Number.length-1]
      wx.removeStorage({
        key: name,
        success: function (res) {
          // wx.showToast({
          //   title: name+'删除成功',
          //   icon: 'none'
          // })
         
          wx.showModal({
            title: '是否要继续删除',
            content: '',
            complete: (res) => {
              if (res.cancel) {
                wx.showToast({
                  title: myCard + app.globalData.Number[app.globalData.Number.length-1] + '删除成功',
                  icon: 'none'
                })
                setTimeout(() => {
                  wx.navigateBack({
                    url: '/pages/index/index',
                  })
                }, 1000)
                app.globalData.count--;
                app.globalData.Number.pop()
                // console.log(app.globalData.count, '!!!', app.globalData.Number);
              }

              if (res.confirm) {
                if (app.globalData.count === 0 && app.globalData.Number[app.globalData.Number.length - 1]) {
                  wx.showToast({
                    title: '数据为0,无法删除,请先创建数据',
                    icon: 'none'
                  })
                  setTimeout(() => {
                    wx.navigateBack({
                      url: '/pages/index/index',
                    })
                  }, 1000)
                } else {

                  wx.removeStorage({
                    key: myCard + app.globalData.Number[app.globalData.Number.length - 1],
                    success: function (res) {
                      wx.showToast({
                        title: myCard + app.globalData.Number[app.globalData.Number.length - 1] + '删除成功',
                        icon: 'none'
                      })
                      app.globalData.count--;
                      app.globalData.Number.pop();
                      // console.log(app.globalData.count, '!!!', app.globalData.Number);
                    }
                  })
                }
              }
            }
          })
        }
      })
    }
  
  },
  
  
全部删除

将本地缓存的数据利用wx.clearStorage();全部删除。同时将数据重新置空,并且返回首页

js
Clear: function (e) {
    this.setData({
      date: '',
      health: '',
      note: '',
      action: '',
      medicine: '',
      selector: '',
      Donated: false,
      high: '',
      weight: '',
      phoneNumber: ''
    })
    wx.clearStorage();
    app.globalData.count = 0;
    app.globalData.Number = [0];
    wx.showToast({
      title: '所有数据已全部删除',
      icon: 'none',
      duration: 500
    })
    setTimeout(() => {
      wx.navigateBack({
        url: '/pages/index/index',
      })
    }, 1000)
  }

由于文章篇幅问题,还有数据编辑函数,以及管理页面,按患者的序号进行管理的代码先不介绍了。大致与创建差不多。

不过有一个前面留下的难点。

难点就是实现管理页对数据进行删除,而不影响创建页创建数据。

换个说法。就是比如我们创建了四个患者的数据,当我们在管理页时对患者1的数据进行删除。当我们重新回到创建页时,创建数据,系统默认我们创建的内容是患者1。也就是不会让数据存在空档。

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

首先我在app.js中
全局创建了两个属性
 globalData: {
    count : 0, // 患者数量
    // 其中Number 更像是一个栈,栈底每次存的都是当前要处理数据的患者的序号
    // 添加数据 就将该序号进栈,删除数据 就将该数据进行出栈。
    Number:[0] // 当前要处理数据的患者的序号
    
  }
其次在创建页拿取app.js中的数据

const app = getApp()
  // 判断 是否 经过了管理数据 对数据进行选择型删除
  // 按照正常顺序对数据进行删除 那么 个数 刚好与对应的 序号一致
  // 创建 0 [0]  1 [0,1]  2 [0,1,2]
  //删除 1 [0,1]
if (!app.globalData.Number.includes(app.globalData.count)) {
    // 非正常删除
    // 2 [0,1,2]  删除了序号为1的数据
    // 1 [0,2]  因为栈里面没有1 于是将1先入栈 当前要管理的数据序号为1
    // 然后数量+1 count++
        app.globalData.Number.push(app.globalData.count)
        app.globalData.count++;
   } 
      
else {
     
        // 非正常删除的另一种情况
        // 3 [0,1,2,3]
        // 对1 进行删除
        // 2 [0,2,3]
        栈里面包含 序号为2的患者
        于是我们就要重新给新的患者取序号,可是如果我们继续count++,
        然后赋值发现去掉患者序号为3 发现又重复了。
        于是我们开始从1开始遍历,直到找到一个栈里面不存在且靠前的一个序号。1将它入栈
        // 3 [0,2,3,1]
        app.globalData.count++;
        if(app.globalData.Number.includes(app.globalData.count)){
          for(let i=1;i<app.globalData.Number.length;i++){
            if(!app.globalData.Number.includes(i)){
              app.globalData.Number.push(i)
            }
          }
        }
        // 正常删除
        // 按照正常顺序对数据进行删除 那么 个数 刚好与对应的 序号一致
        // 创建 0 [0]  1 [0,1]  2 [0,1,2]
        //删除 1 [0,1]
        // 添加 2 [0,1,2]
        else{
          app.globalData.Number.push(app.globalData.count)
            }
      }
      
      删除栈里面指定序号的序号
      // 个数先进行减1
       app.globalData.count--;
    // console.log(num);
    // 特别注意因为count 为数字 存到数组里也是数字 
    //但是 输入的number 为字符串 要转换格式 才能删除
    // 拿到指定元素 在栈里的下标 删除1个
    let  i = app.globalData.Number.indexOf(Number(num));
    app.globalData.Number.splice(i,1);

源码链接

源码点这里

文章不易,希望大佬给动动小手,给我点个赞。谢谢!!!

新手入门微信小程序简单项目实战二 —— 表单form+本地缓存 详细教学

原文链接:https://juejin.cn/post/7218208891707752485 作者:Mr-Wang-Y-P

(1)
上一篇 2023年4月5日 下午4:20
下一篇 2023年4月5日 下午4:31

相关推荐

发表回复

登录后才能评论