微信小程序 - 实际例子
通过一个完整的"待办事项"小程序例子,展示微信小程序的开发流程和核心用法。
项目结构
├── pages
│ ├── index
│ │ ├── index.js // 页面逻辑
│ │ ├── index.json // 页面配置
│ │ ├── index.wxml // 页面结构
│ │ └── index.wxss // 页面样式
├── app.js // 应用逻辑
├── app.json // 应用配置
└── app.wxss // 全局样式
app.json - 全局配置
{
"pages": [
"pages/index/index"
],
"window": {
"navigationBarTitleText": "待办事项",
"navigationBarBackgroundColor": "#1890ff",
"navigationBarTextStyle": "white"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
pages/index/index.wxml - 页面结构
<view class="container">
<view class="header">
<input
class="input"
placeholder="添加新任务..."
bindinput="onInput"
value="{{newTask}}"
/>
<button class="add-btn" bindtap="addTask">添加</button>
</view>
<view class="tabs">
<text class="{{currentTab===0?'active':''}}" bindtap="switchTab" data-index="0">全部</text>
<text class="{{currentTab===1?'active':''}}" bindtap="switchTab" data-index="1">待完成</text>
<text class="{{currentTab===2?'active':''}}" bindtap="switchTab" data-index="2">已完成</text>
</view>
<view class="task-list">
<block wx:for="{{filteredTasks}}" wx:key="id">
<view class="task-item {{item.done?'done':''}}">
<checkbox checked="{{item.done}}" bindtap="toggleTask" data-id="{{item.id}}"/>
<text>{{item.text}}</text>
<text class="delete-btn" bindtap="deleteTask" data-id="{{item.id}}">×</text>
</view>
</block>
</view>
</view>
pages/index/index.js - 页面逻辑
Page({
data: {
newTask: '',
tasks: [],
currentTab: 0,
filteredTasks: []
},
onLoad() {
const tasks = wx.getStorageSync('tasks') || []
this.setData({ tasks })
this.filterTasks()
},
onInput(e) {
this.setData({ newTask: e.detail.value })
},
addTask() {
if (!this.data.newTask.trim()) return
const newTask = {
id: Date.now(),
text: this.data.newTask,
done: false
}
const tasks = [...this.data.tasks, newTask]
this.setData({ tasks, newTask: '' })
this.saveAndFilter()
},
toggleTask(e) {
const id = e.currentTarget.dataset.id
const tasks = this.data.tasks.map(t =>
t.id === id ? { ...t, done: !t.done } : t
)
thisthis.saveAndFilter()
},
deleteTask(e) {
const id = e.currentTarget.dataset.id
const tasks = this.data.tasks.filter(t => t.id !== id)
this.setData({ tasks })
this.saveAndFilter()
},
switchTab(e) {
const index = parseInt(e.currentTarget.dataset.index)
this.setData({ currentTab: index })
this.filterTasks()
},
filterTasks() {
let tasks = this.data.tasks
if (this.data.currentTab === 1) {
tasks = tasks.filter(t => !t.done)
} else if (this.data.currentTab === 2) {
tasks = tasks.filter(t => t.done)
}
this.setData({ filteredTasks: tasks })
},
saveAndFilter() {
wx.setStorageSync('tasks', this.data.tasks)
this.filterTasks()
}
})
pages/index/index.wxss - 页面样式
.container {
padding: 20rpx;
}
.header {
display: flex;
gap: 10rpx;
margin-bottom: 30rpx;
}
.input {
flex: 1;
border: 1rpx solid #ddd;
border-radius: 8rpx;
padding: 20rpx;
}
.add-btn {
background: #1890ff;
color: white;
}
.tabs {
display: flex;
margin-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
}
.tabs text {
padding: 20rpx 30rpx;
color: #666;
}
.tabs text.active {
color: #1890ff;
border-bottom: 2rpx solid #1890ff;
}
.task-item {
display: flex;
align-items: center;
padding: 24rpx;
background: #f9f9f9;
margin-bottom: 10rpx;
border-radius: 8rpx;
}
.task-item.done text {
text-decoration: line-through;
color: #999;
}
.delete-btn {
margin-left: auto;
color: #ff4d4f;
font-size: 36rpx;
}