zoukankan      html  css  js  c++  java
  • 微信小程序入门之构建一个简单TODOS应用

    最近,由于工作需要开始了解微信小程序,虽然小程序已经出了很久了,刚出的那段时间很火,看到很多关于小程序的技术文章,不过现在似乎没那么火了,anyway,我们还是可以学习下的。

    一、了解微信小程序

    1.理念:小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。
    2.框架:框架的核心是一个响应的数据绑定系统。整个系统分为两块视图层(View)和逻辑层(App Service),框架可以让数据与视图非常简单地保持同步。当做数据修改的时候,只需要在逻辑层修改数据,视图层就会做相应的更新。
    3.相关资料:调试工具下载,简易教程

    初步了解这些基本信息后,我们先来看下TODOS这个应用做出来的最终效果

    二、TODOS应用功能演示及目录结构

    功能演示:
    preview.gif

    目录结构:
    2.gif

    主要功能模块为:

    • index页面,新建任务,可完成增删等操作

    • los页面,记录在index页面的操作

    下面我们详细介绍下

    三、代码详解

    1.简单配置app.json文件:

    {
          "pages":[
            "pages/index/index", // 设置页面路径,项目打开后找到这个路径下的文件
            "pages/logs/logs"
          ],
          "window":{ // 设置默认页面的窗口表现
            "backgroundTextStyle":"light",
            "navigationBarBackgroundColor": "#fff",
            "navigationBarTitleText": "TODOS",
            "navigationBarTextStyle":"black"
          },
          "tabBar": { // 设置底部tab的表现
            "borderStyle": "white",
            "backgroundColor": "#f5f5f5",
            "selectedColor": "#222",
            "list": [ // 对应底部下面两个菜单项;TODOS和LOGS
              {
                "pagePath": "pages/index/index",
                "text": "TODOS",
                "iconPath": "images/home.png",
                "selectedIconPath": "images/home-actived.png"
              },
              {
                "pagePath": "pages/logs/logs",
                "text": "LOGS",
                "iconPath": "images/note.png",
                "selectedIconPath": "images/note-actived.png"
              }
            ]
          }
        }

    2.app.js和app.wxss文件

    App() 函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。App() 必须在 app.js 中注册,且不能注册多个
    示例代码

    App({
          onLaunch: function() { 
            // Do something initial when launch.
          },
          onShow: function() {
              // Do something when show.
          },
          onHide: function() {
              // Do something when hide.
          },
          onError: function(msg) {
            console.log(msg)
          },
          globalData: 'I am global data'
        })

    在这个项目中不需要加什么代码在App({})中,所以文件中只有一个App({})

    app.wxss文件主要可以设置一些全局样式

        page {
          height: 100%;
          font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }

    3.注册页面Page

    Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。

    一.初始化数据

         // ===== 页面数据对象 =====
          data: {
            input: '',
            todos: [],
            leftCount: 0,
            allCompleted: false,
            logs: [],
            addOneLoading: false,
            loadingHidden: true,
            loadingText: '',
            toastHidden: true,
            toastText: '',
            clearAllLoading: false
          },

    初始化数据作为页面的第一次渲染。data将会以JSON的形式由逻辑层传至渲染层,其数据可以是:字符串,数字,布尔值,对象,数组。
    渲染层可以通过WXML对数据进行绑定。

    <input class="new-todo" value="{{ input }}" placeholder="Anything here..." auto-focus bindinput="inputChangeHandle" bindchange="addTodoHandle"/>

    如上述代码中的input.

    二.生命周期函数

         // ===== 页面生命周期方法 =====
          onLoad: function () {
            // 从缓存获取任务列表数据,并用setData设置
            var todos = wx.getStorageSync('todo_list') // 调用 WX API 从本地缓存中获取数据
            if (todos) {
              var leftCount = todos.filter(function (item) {
                return !item.completed
              }).length
              this.setData({ todos: todos, leftCount: leftCount })
            }
            // 设置logs数据
            var logs = wx.getStorageSync('todo_logs')
            if (logs) {
              this.setData({ logs: logs })
            }
          },
    
    • onLoad: 页面加载

      一个页面只会调用一次。接收页面参数可以获取wx.navigateTo和wx.redirectTo及<navigator/>中的 query。
    • setData: 接受一个对象,以 key,value 的形式表示将 this.data 中的 key 对应的值改变成 value。

    三.事件处理函数

    • 新增任务处理函数:

        addTodoHandle: function (e) {
            if (!this.data.input || !this.data.input.trim()) return
            this.setData( {
                addOneLoading: true
            });
            //open loading
            this.setData( {
                loadingHidden: false,
                loadingText: 'Waiting...'
            });
            var todos = this.data.todos
            todos.push({ name: this.data.input, completed: false })
            var logs = this.data.logs
            logs.push({ timestamp: new Date().toLocaleString(), action: '新增', name: this.data.input })
            this.setData({
              input: '',
              todos: todos,
              leftCount: this.data.leftCount + 1,
              logs: logs
            })
            this.save()
          },
          save: function () {
            wx.setStorageSync('todo_list', this.data.todos)
            wx.setStorageSync('todo_logs', this.data.logs)
            //close loading and toggle button loading status
            var self = this;
            setTimeout( function() {
              self.setData( {
                  loadingHidden: true,
                  addOneLoading: false,
                  loadingText: ''
              });
            }, 100);
          },

    主要把时间new Date().toLocaleString(), action:'新增',事件名 name: this.data.input这三个字段push到todos这个data数据中;然后在save()中通过wx.setStorageSync('todo_list', this.data.todos)设置缓存。

    • 任务项点击状态切换函数:

    toggleTodoHandle: function (e) {
        var index = e.currentTarget.dataset.index
        var todos = this.data.todos
        todos[index].completed = !todos[index].completed
        var logs = this.data.logs
        logs.push({
          timestamp: new Date().toLocaleString(),
          action: todos[index].completed ? '标记完成' : '标记未完成',
          name: todos[index].name
        })
        this.setData({
          todos: todos,
          leftCount: this.data.leftCount + (todos[index].completed ? -1 : 1),
          logs: logs
        })
        this.save()
      },

    var index = e.currentTarget.dataset.index 获取当前索引,对应的wxml代码为:

    <view class="item{{ item.completed ? ' completed' : '' }}" wx:for="{{ todos }}" wx:key="{{ index }}" bindtap="toggleTodoHandle" data-index="{{ index }}">
            <!-- completed: success, todo: circle -->
            <icon class="checkbox" type="{{ item.completed ? 'success' : 'circle' }}"/>
            <text class="name">{{ item.name }}</text>
            <icon class="remove" type="clear" size="16" catchtap="removeTodoHandle" data-index="{{ index }}"/>
    </view>

    bindtap: 当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数

    最后考虑到了loading的效果,要利用button组件的loading属性来实现。但是loading仅仅是一个样式的控制,它不会控制这个按钮是否能重复点击。所以还要利用button的disabled属性,防止重复点击。

    <button type="primary" size="mini" bindtap="addTodoHandle" loading="{{addOneLoading}}" disabled="{{addOneLoading}}">
                + Add
    </button>
    

    js:

      loadingChange: function() {
        this.setData({
          loadingHidden: true,
          loadingText: ''
        });
      },
      toastChange: function() {
        this.setData( {
            toastHidden: true,
            toastText: ''
        });
      }
    

    LOGS页面比较简单,主要通过var logs = wx.getStorageSync('todo_logs')
    获取logs列表,然后在页面渲染,这里就不贴代码了。

    至此,基本了解了TODOS应用的构建过程,通过代码详解、参考微信小程序官方文档了解了微信自家开发的视图层描述语言WXML和WXSS,以及基于 JavaScript 的逻辑层框架;与HTML页面结构相似,对应HTML,CSS,JAVASCRIPT;所以学习起来比较容易。不过仅仅通过这个TODOS应用,还只是了解小程序这个平台的一些基本用法。复杂一点,页面跳转,网络请求等都需要我们去实践,才能对小程序了解得更多。

    完整代码:
    源代码

    参考资料:
    1.https://github.com/zce/weapp-...
    2.http://www.cnblogs.com/lyzg/p...

  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/10manongit/p/12732397.html
Copyright © 2011-2022 走看看