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...

  • 相关阅读:
    No.1
    JS二叉树的操作
    JS实现快排
    BOM中的各种height
    innerHTML outerHTML innerText value 区别
    【转载】JS中DOM操作汇总
    【转载】轻松理解JS闭包
    【转载】JavaScript模块入门
    【转载】JavaScript模块简介
    【转载】浏览器缓存详解:expires cache-control last-modified
  • 原文地址:https://www.cnblogs.com/10manongit/p/12732397.html
Copyright © 2011-2022 走看看