Практика TodoList
Прочитав официальное введение в документ, я хочу найти простой пример для проверки реализации.TodoList MVC очень хорош, прост и удобен.
Раньше я использовал JQ, Backbone и vue, чтобы просто играть.Примерные функции следующие:
- добавить дело
- Хранить в кеше приложения
- Отображение списка
- Дифференциальное отображение состояния: все, незавершенное, завершенное
- изменить состояние дел
- удалить задачу
В соответствии с вышеперечисленными функциями апплет комплектуется следующим образом:
GitHub: GitHub.com/CH563/в ДОЛ…
Вот запись моего процесса завершения:
Скачать средства разработки утверждения:Скачать инструменты разработчика
После завершения установки используйте WeChat для сканирования и входа в систему, выберите папку и создайте ее.Инструмент разработки автоматически создаст следующий каталог:
pages/
app.js
app.json
app.wxss
Описание структуры и конкретной конфигурации смотрите в официальной документации:Билеты.WeChat.QQ.com/debug/WX ADO…
базовая конфигурация
Из-за обычных привычек разработки Less, если вы напрямую используете wxss апплета для записи, будет восстановлен исходный метод записи, что очень неудобно, поэтому вы напрямую используете gulp для компиляции Less в реальном времени и изменения файла имя wxss. Инструмент разработки апплета не поддерживает Less и разработан непосредственно с помощью vscode. Инструмент разработки апплета можно просматривать и отлаживать в режиме реального времени. vscode также имеет множество подключаемых модулей для поддержки подсказок синтаксиса апплета.
// 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()) // 错误处理
.pipe(less()) // 编译less
.pipe(rename((path) => path.extname = '.wxss')) // 编译后生成文件修改后缀为.wxss
.pipe(gulp.dest('./'));
});
gulp.watch('./app.less', ['less']); // 实时监控app.less文件变化,运行任务
Компоненты пользовательского интерфейса также напрямую относятся к компонентам, поддерживаемым апплетом.weui-wxss
@import "./weui.wxss";
Определите маршрутизацию страницы апплета и сопоставление цветов в app.json:
{
"pages":[
"pages/index/index"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#ca2100",
"navigationBarTitleText": "TodoList",
"navigationBarTextStyle":"white"
}
}
разработка страницы
Файлы страниц хранятся в каталоге pages/. Каждая функциональная страница будет создавать папку. TodoList теперь нужна только одна страница для ее завершения.
Привязка данных использует синтаксис Mustache (двойные фигурные скобки) для переноса переменных.
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
<!-- 三元运算 -->
<text class="{{status === '1'?'active':''}}" data-status="1" bindtap="showStatus">全部</text>
добавить дело
использовать поляaddShow
Чтобы судить о добавлении входного слоя для отображения и скрытия
Поле ввода-вывода не является двусторонним, поэтому добавьте сюда событие.bindinput="setInput"
для назначения изменений в реальном времени
<view class="addForm {{addShow?'':'hide'}}">
<view class="addForm-div">
<input class="weui-input" placeholder="请输入todo" value="{{addText}}" bindinput="setInput" focus="{{focus}}" />
<view class="addForm-btn">
<button class="weui-btn mini-btn" type="warn" bindtap="addTodo" size="mini">确定添加</button>
<button class="weui-btn mini-btn" type="default" bindtap="addTodoHide" size="mini">取消</button>
</view>
</view>
</view>
Обработка событий назначения в реальном времени
setInput: function (e) {
this.setData({
addText: e.detail.value
})
}
При отмене значение ввода необходимо очистить, а ввод необходимо привязатьvalue="{{addText}}"
Page({
data:{
//...
},
//...
addTodoHide: function () {
this.setData({
addShow: false, // 控制添加输入面板隐藏
focus: false, // 失去焦点
addText: '' // 清空值
})
}
//...
})
добавить дело
Page({
data:{
//...
},
//...
addTodo: function () {
// 检查有没有输入
if (!this.data.addText.trim()) {
return
}
var temp = this.data.lists // 取出lists
var addT = {
id: new Date().getTime(), // 取当前时间
title: this.data.addText,
status: '0'
}
temp.push(addT) // 添加新的todo
this.showCur(temp) // 处理当前状态的方法
this.addTodoHide() // 添加成功后,隐藏添加面板方法
wx.setStorage({ // 小程序异步缓存
key:"lists",
data: temp
})
wx.showToast({ // weui toast组件
title: '添加成功!',
icon: 'success',
duration: 1000
});
}
//...
})
Раздел списка
прокрутить внутри прокрутки
Отображение списка, запуск событий, использование данных для передачи параметров, привязка событий привязки
<scroll-view class="lists" scroll-y>
<!-- 判断列表是否为空 -->
<block wx:if="{{curLists.length < 1}}">
<view class="nodata">暂无数据</view>
</block>
<!-- 列表渲染 -->
<view class="item" wx:for="{{curLists}}" wx:key="index">
<!-- 内容view,绑定touch三个件事,来实现滑动册除 -->
<view class="content" style="{{item.txtStyle}}" data-index="{{index}}" bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE">
<!-- checkbox图标,changeTodo事件来控制状态切换 -->
<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是使用了wxs模块化编写的模块 -->
<text class="time">{{api.formatTime(item.id)}}</text>
</view>
<!-- 删除按钮,绑定删除事件 -->
<view class="del" data-item="{{item.id}}" bindtap="delTodo"><text>删除</text></view>
</view>
</scroll-view>
Проведите, чтобы удалить
Эффект: При скольжении влево содержимое перемещается пальцем влево, а кнопка del появляется справа; когда расстояние скольжения больше половины ширины кнопки, при отпускании пальца оно автоматически скользит влево, чтобы отобразить кнопку, а когда она меньше половины, она автоматически возвращается в исходное положение, скрывает кнопку.
Идеи реализации:Кнопки содержимого и удаления имеют абсолютное позиционирование соответственно. Слой z-index используется для управления содержимым, закрывающим удаление. Когда содержимое перемещается влево, кнопка удаления становится видимой.
Сенсорный объект, предоставляемый API-интерфейсом апплета WeChat, и 3 функции, связанные с касанием пальца (touchstart, touchmove, touchend), для реализации перемещения содержимого пальцем.
Для получения подробных инструкций API, пожалуйста, проверьте:Билеты.WeChat.QQ.com/debug/WX ADO…
Содержимое списка было привязано к этим трем событиям:bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE"
Реализация:
УведомлениеtxtStyle
, который привязан к этому свойству в содержании, чтобы следовать за движением пальцаstyle="{{item.txtStyle}}"
delBtnWidth
Для ширины кнопки del здесь в rpx
Page({
data:{
//...
},
//...
touchS: function (e) {
// console.log('开始:' + JSON.stringify(e))
// 是否只有一个触摸点
if(e.touches.length === 1){
this.setData({
// 触摸起始的X坐标
startX: e.touches[0].clientX
})
}
},
touchM: function (e) {
// console.log('移动:' + JSON.stringify(e))
var _this = this
if(e.touches.length === 1){
// 触摸点的X坐标
var moveX = e.touches[0].clientX
// 计算手指起始点的X坐标与当前触摸点的X坐标的差值
var disX = _this.data.startX - moveX
// delBtnWidth 为右侧按钮区域的宽度
var delBtnWidth = _this.data.delBtnWidth
var txtStyle = ''
if (disX == 0 || disX < 0){ // 如果移动距离小于等于0,文本层位置不变
txtStyle = 'left:0'
} else if (disX > 0 ){ // 移动距离大于0,文本层left值等于手指移动距离
txtStyle = 'left:-' + disX + 'rpx'
if(disX >= delBtnWidth){
// 控制手指移动距离最大值为删除按钮的宽度
txtStyle = 'left:-' + delBtnWidth + 'rpx'
}
}
// 获取手指触摸的是哪一个item
var index = e.currentTarget.dataset.index;
var list = _this.data.curLists
// 将拼接好的样式设置到当前item中
list[index].txtStyle = txtStyle
// 更新列表的状态
this.setData({
curLists: list
});
}
},
touchE: function (e) {
// console.log('停止:' + JSON.stringify(e))
var _this = this
if(e.changedTouches.length === 1){
// 手指移动结束后触摸点位置的X坐标
var endX = e.changedTouches[0].clientX
// 触摸开始与结束,手指移动的距离
var disX = _this.data.startX - endX
var delBtnWidth = _this.data.delBtnWidth
// 如果距离小于删除按钮的1/2,不显示删除按钮
var txtStyle = disX > delBtnWidth/2 ? 'left:-' + delBtnWidth + 'rpx' : 'left:0'
// 获取手指触摸的是哪一项
var index = e.currentTarget.dataset.index
var list = _this.data.curLists
list[index].txtStyle = txtStyle
// 更新列表的状态
_this.setData({
curLists: list
});
}
}
//...
})
WXS реализует формат времени
Эффект следующий:
Здесь я использую WXS апплета
WXS (WeiXin Script) представляет собой набор языков сценариев для небольших программ.В сочетании с WXML можно построить структуру страницы.Узнать больше
Создайте новый файл api.wxs, а затем укажите его в index.wxml, определите имя модуля для ссылки:
<!-- index.wxml -->
<wxs src="./api.wxs" module="api" />
...
<text class="time">{{api.formatTime(item.id)}}</text>
Каждый модуль wxs имеет встроенный объект модуля.
Файл api.wxs и метод реализации формата времени:
var formatTime = function(time){
// 获取当前时间
var getUnix = function () {
var date = getDate()
return date.getTime()
}
// 获取今天零点时间
var getTodayUnix = function () {
var date = getDate()
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0)
date.setMilliseconds(0)
return date.getTime()
}
// 获取今年的1月1日零点时间
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()
}
// 获取标准时间
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() + '-' + month + '-' + day
}
// 转换时间
var getFormatTime = function (timestamp) {
var now = getUnix()
var today = getTodayUnix()
var year = getYearUnix()
var timer = (now - timestamp) / 1000
var tip = ''
if (timer <= 0) {
tip = '刚刚'
} else if (Math.floor(timer / 60) <= 0) {
tip = '刚刚'
} else if (timer < 3600) {
tip = Math.floor(timer / 60) + '分钟前'
} else if (timer >= 3600 && (timestamp - today >= 0)) {
tip = Math.floor(timer / 3600) + '小时前'
} else if (timer / 86400 <= 31) {
tip = Math.ceil(timer / 86400) + '天前'
} else {
tip = getLastDate(timestamp)
}
return tip
}
return getFormatTime(+time)
}
// es6方法一样,导出formatTime方法
module.exports.formatTime = formatTime;
Здесь следует отметить, что получение текущего времени WXS не поддерживаетnew Date()
, который имеет свой собственный методgetDate()
. как использоватьnew Date()
Такой же.
На данный момент это завершено, практический пример TodoList, простая функция, хороший пример для начала.
Я надеюсь, что это будет полезно для вас.Пожалуйста, подскажите мне некоторые недостатки.Я только что закончил читать примеры официальной документации.
Загрузка исходного кода:GitHub.com/CH563/в ДОЛ…
Пусть все получат повышение!