TodoList practice

After reading the official documentation, I want to find a simple example to verify the implementation, TodoList MVC is very good, simple and easy.

JQ, Backbone, vue, etc.

  • Add a todo
  • Stored in the application cache
  • The list shows
  • Distinguish status display: complete, incomplete, completed
  • Change the toDO state
  • Delete todo

According to the above functions, the small program is completed as follows:

Making: github.com/CH563/TodoL…

Here’s how I did it:

Download small program development tools: developer tools download

After the installation is complete, use wechat to scan and log in, select a folder and create it. The development tool will automatically generate the following directories:

pages/

app.js

app.json

app.wxss

Wen Lu salt structure and specific configuration to see the official document: mp.weixin.qq.com/debug/wxado…

The basic configuration

As usual development habits with Less, if in direct use of small program WXSS to write, it will restore the native way, greatly inconvenient, so the direct use of GULp Less real-time compilation, and modify the file name WXSS. Small program development tools do not support Less, directly use VSCode to develop, small program development tools are real-time preview and debugging can be used, VSCode also has a rich plug-in support for small program syntax tips.

// gulpfile.js
var gulp = require('gulp')
var less = require('gulp-less')
var plumber = require('gulp-plumber')
var rename = require('gulp-rename')

gulp.task('less'.function () {
  return gulp.src('./app.less')
    .pipe(plumber())  // Error handling
    .pipe(less()) / / compile less
    .pipe(rename((path) = > path.extname = '.wxss')) // Change the suffix of the generated file to.wxss
    .pipe(gulp.dest('/'));
});
gulp.watch('./app.less'['less']); // Monitor the change of app.less file in real time and run the task
Copy the code

The UI component also directly references the weUi-WXSS supported by the applet

@import "./weui.wxss";
Copy the code

Define the applet page routing and color matching in app.json:

{
  "pages": ["pages/index/index"]."window": {"backgroundTextStyle":"light"."navigationBarBackgroundColor": "#ca2100"."navigationBarTitleText": "TodoList"."navigationBarTextStyle":"white"}}Copy the code

Page development

Page files are stored in the pages/ directory, each feature page creates a folder, TodoList now only needs one page to complete

Data binding uses Mustache syntax (double braces) to wrap variables

<text class="userinfo-nickname">{{userInfo.nickName}}</text>
<! -- Ternary operation -->
<text class="{{status === '1'? 'active':''}}" data-status="1" bindtap="showStatus">all</text>
Copy the code

Add a todo

Use the field addShow to determine whether to add the input layer show hide

This is not a two-way binding, so add an event bindinPUT =”setInput” to assign the value to change in real time

<view class="addForm {{addShow? '':'hide'}}">
    <view class="addForm-div">
      <input class="weui-input" placeholder="Please enter todo" value="{{addText}}" bindinput="setInput" focus="{{focus}}" />
      <view class="addForm-btn">
        <button class="weui-btn mini-btn" type="warn" bindtap="addTodo" size="mini">Sure to add</button>
        <button class="weui-btn mini-btn" type="default" bindtap="addTodoHide" size="mini">cancel</button>
      </view>
    </view>
  </view>
Copy the code

Real-time assignment event handling

setInput: function (e) {
    this.setData({
      addText: e.detail.value
    })
}
Copy the code

Value =”{{addText}}”;

Page({
 data: {/ /...
 }, 
 / /...
 addTodoHide: function () {
    this.setData({
      addShow: false.// Control add input panel hidden
      focus: false.// Lose focus
      addText: ' ' / / to empty values})}/ /...
})
Copy the code

Add a todo

Page({
 data: {/ /...
 }, 
 / /...
 addTodo: function () {
    // Check for input
    if (!this.data.addText.trim()) {
      return
    }
    var temp = this.data.lists / / remove the lists
    var addT = {
      id: new Date().getTime(), // Take the current time
      title: this.data.addText,
      status: '0'
    }
    temp.push(addT) // Add new todo
    this.showCur(temp) // How to handle the current state
    this.addTodoHide() // After the panel is added, hide the method of adding panel
    wx.setStorage({ // Small program asynchronous cache
      key:"lists".data: temp
    })
    wx.showToast({ // The weui toast component
      title: 'Added successfully! '.icon: 'success'.duration: 1000
    });
 }
 / /...
})
Copy the code

List some

Scroll – scroll within the view

List rendering, event triggering, data passing, bind binding event

<scroll-view class="lists" scroll-y>
    <! -- Check whether the list is empty -->
    <block wx:if="{{curLists.length < 1}}">
      <view class="nodata">Temporarily no data</view>
    </block>
    <! -- List rendering -->
    <view class="item" wx:for="{{curLists}}" wx:key="index">
      <! -- Content view, bind touch -->
      <view class="content" style="{{item.txtStyle}}" data-index="{{index}}" bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE">
        <! -- Checkbox icon, changeTodo event to control state switching -->
        <icon class="icon-small" type="{{item.status === '0'? 'circle':'success'}}" size="23" data-item="{{item.id}}" bindtap="changeTodo"></icon>
        <text class="title {{item.status === '1'? 'over':''}}">{{item.title}}</text>
        <! -- API. FormatTime is a module written using WXS modularity -->
        <text class="time">{{api.formatTime(item.id)}}</text>
      </view>
      <! -- Delete button, bind delete event -->
      <view class="del" data-item="{{item.id}}" bindtap="delTodo"><text>delete</text></view>
    </view>
  </scroll-view>
Copy the code

Sliding delete

Effect: When swiping to the left, content follows the finger as it moves to the left, while the del button appears on the right; When the sliding distance is greater than half of the width of the button, the finger will automatically slide to the left and display the button. When the finger is less than half, it will automatically return to the original position and hide the button.

Content and del buttons are absolute positioning, using z-index layer to control the content to cover del, when content to the left swipe, del button will be exposed.

Wechat small program API provides the touch object and 3 finger touch functions (TouchStart, touchmove, touchend) to achieve content with finger movement

Detailed API specification, please check: mp.weixin.qq.com/debug/wxado…

The content of the list is bound to these three events: bindTouchStart =”touchS” bindTouchMove =”touchM” bindTouchEnd =”touchE”

Implementation method:

Note that txtStyle, in the content in the binding of this property, implements the following finger movement style=”{{item.txtstyle}}”

DelBtnWidth is the width of the del button, in RPX

Page({
 data: {/ /...
 }, 
 / /...
  touchS: function (e) {
    // console.log(' start: '+ json.stringify (e))
    // Whether there is only one touch point
    if(e.touches.length === 1) {this.setData({
        // Touch the starting X coordinate
        startX: e.touches[0].clientX
      })
    }
  },
  touchM: function (e) {
    // console.log(' move: '+ json.stringify (e))
    var _this = this
    if(e.touches.length === 1) {// The X coordinate of the touch point
      var moveX = e.touches[0].clientX
      // Calculate the difference between the X coordinate of the finger's starting point and the X coordinate of the current touch point
      var disX = _this.data.startX - moveX
     // delBtnWidth is the width of the button area on the right
      var delBtnWidth = _this.data.delBtnWidth
      var txtStyle = ' '
      if (disX == 0 || disX < 0) {// If the move distance is less than or equal to 0, the position of the text layer is unchanged
        txtStyle = 'left:0'
      } else if (disX > 0) {// If the movement distance is greater than 0, the left value of the text layer is equal to the movement distance of the finger
        txtStyle = 'left:-' + disX + 'rpx'
        if(disX >= delBtnWidth){
          // Control the maximum movement distance of the finger to the width of the delete button
          txtStyle = 'left:-' + delBtnWidth + 'rpx'}}// Retrieve the item touched by the finger
      var index = e.currentTarget.dataset.index;
      var list = _this.data.curLists
      // Set the concatenated style to the current item
      list[index].txtStyle = txtStyle
      // Update the status of the list
      this.setData({
        curLists: list }); }},touchE: function (e) {
    // console.log(' stop: '+ json.stringify (e))
    var _this = this
    if(e.changedTouches.length === 1) {// Touch the X coordinate of the point after the finger moves
      var endX = e.changedTouches[0].clientX
      // Touch begins and ends, the distance the finger moves
      var disX = _this.data.startX - endX
      var delBtnWidth = _this.data.delBtnWidth
      // If the distance is less than 1/2 of the delete button, the delete button is not displayed
      var txtStyle = disX > delBtnWidth/2 ? 'left:-' + delBtnWidth + 'rpx' : 'left:0'
      // Get which item the finger touches
      var index = e.currentTarget.dataset.index
      var list = _this.data.curLists
      list[index].txtStyle = txtStyle
      // Update the status of the list
      _this.setData({
        curLists: list }); }}/ /...
})
Copy the code

WXS implements the time format

The results are as follows:

Here I’m using WXS for the applet

WXS (WeiXin Script) is a set of small program scripting language, combined with WXML, you can build the structure of the page. With a detailed

Create a new api.wxs file and reference it in index.wxml, defining the module name to reference:

<! -- index.wxml -->
<wxs src="./api.wxs" module="api" />.<text class="time">{{api.formatTime(item.id)}}</text>
Copy the code

Each WXS module has a built-in Module object

API. WXS file and time format

var formatTime = function(time){
  // Get the current time
  var getUnix = function () {
    var date = getDate()
    return date.getTime()
  }
  // Obtain today's zero hour
  var getTodayUnix = function () {
    var date = getDate()
    date.setHours(0)
    date.setMinutes(0)
    date.setSeconds(0)
    date.setMilliseconds(0)
    return date.getTime()
  }
  // Obtain the time of 00:00 on January 1 of this year
  var getYearUnix = function () {
    var date = getDate()
    date.setMonth(0)
    date.setDate(1)
    date.setHours(0)
    date.setMinutes(0)
    date.setSeconds(0)
    date.setMilliseconds(0)
    return date.getTime()
  }
  // Get the standard time
  var getLastDate = function (time) {
    var date = getDate(time)
    var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
    var day = date.getDay() < 10 ? '0' + (date.getDay()) : date.getDay()
    return date.getFullYear() + The '-' + month + The '-' + day
  }
  // Convert time
  var getFormatTime = function (timestamp) {
    var now = getUnix()
    var today = getTodayUnix()
    var year = getYearUnix()
    var timer = (now - timestamp) / 1000
    var tip = ' '
    if (timer <= 0) {
      tip = 'just'
    } else if (Math.floor(timer / 60) < =0) {
      tip = 'just'
    } else if (timer < 3600) {
      tip = Math.floor(timer / 60) + 'Minutes ago'
    } else if (timer >= 3600 && (timestamp - today >= 0)) {
      tip = Math.floor(timer / 3600) + 'Hours ago'
    } else if (timer / 86400< =31) {
      tip = Math.ceil(timer / 86400) + 'days ago'
    } else {
      tip = getLastDate(timestamp)
    }
    return tip
  }
  return getFormatTime(+time)
}

// Export formatTime as in es6
module.exports.formatTime = formatTime;
Copy the code

Note that to get the current time, WXS does not support new Date(), it has its own method getDate(). Use it the same way as new Date().

So far has been completed, TodoList practice examples, simple function, good example of getting started.

Hope to be helpful to you, insufficient place please guide you, just finished the example of the official document.

Download: github.com/CH563/TodoL…

May everyone get a promotion and a raise!