Learn More About Todo App Demo
Overview
We will introduce the development of a Mini Program in detail through the Todo App Demo.
Global Configuration
The app.js
is the entry point to a Mini Program, you can configure the lifecycle of a Mini Program, declare global variables, and perform app initialization in this file. The following code snippet shows an example of calling APIs for storage and getting user information. For more APIs, see API document.
// Call the storage API to get the stored data
const todos = my.getStorageSync({key:'todos'}).data || [
{ text: 'Learning Javascript', completed: true },
{ text: 'Learning ES2016', completed: true },
{ text: 'Learning Mini Program ', completed: false },
];
App({
// Declare global data
todos,
userInfo: null,
// Declare global method
setTodos(todos) {
this.todos = todos;
// Call storage API to store data
my.setStorageSync({key:'todos', data:todos});
},
getUserInfo() {
return new Promise((resolve, reject) => {
if (this.userInfo) resolve(this.userInfo);
// Call user authorization API to get user info
my.getAuthCode({
success: (authcode) => {
console.info(authcode);
my.getAuthUserInfo({
scopes: ['auth_user'],
success: (res) => {
this.userInfo = res;
resolve(this.userInfo);
},
fail: () => {
reject({});
},
});
},
fail: () => {
reject({});
},
});
});
},
});
The app.json
is the global configuration file of the Mini Program, where it is possible to configure the general navigation bar title, window background color and other configurations of the Mini Program. For more configurations, see global configuration documentation.
{
"pages": [
"pages/todos/todos",
"pages/add-todo/add-todo"
],
"window": {
"defaultTitle": "Todo App"
}
}
The app.acss
is the global style of a Mini Program. The selectors defined in the app.acss can be applied to all pages in the Mini Program project.
page {
flex: 1;
display: flex;
}
The page selector is a special selector supported by the framework, which works with the page root node container available in the framework.
Mini Program Page
We have two pages in this demo project: Todo List page and Add Todo page, both reside in the pages
directory. All page paths of the Mini Program must be declared in the app.json
, and a page path starts from the project root directory and should omit the filename extension. The very first path declared app.json
is the home page of a Mini Program.
Each Mini Program page consists of four types of files under the same directory:
- JS logic script file with the
.js
extension
- Configuration file with the
.json
extension
- Style file with the
.acss
extension
- UI Layout file with the
.axml
extension.
Todo List Page
The todos.axml is the structure template file of the page:
<view class="page-todos">
<view class="user">
<image class="avatar" src="{{user.avatar}}" background-size="cover"></image>
<view class="nickname">{{user.nickName}}'s Todo List</view>
</view>
<view class="todo-items">
<checkbox-group class="todo-items-group" onChange="onTodoChanged">
<label class="todo-item" a:for="{{todos}}">
<checkbox value="{{item.text}}" checked="{{item.completed}}" />
<text class="{{item.completed ? 'checked' : ''}}">{{item.text}}</text>
</label>
</checkbox-group>
<view class="todo-item">
<button onTap="addTodo">Add Todo</button>
</view>
</view>
</view>
This UI layout have built-in UI components such as <view/>
,<image/>
,<text/>
,<button/>
,<label/>
and <checkbox/>
to build up the page structure, and we use a:for
attribute to perform list rendering which iterates the todos list and render a label
for each todo data respectively.
For binding data, see Data binding document. For binding event, see event handling document.
The todos.js
is the logic script file of the page:
// Get global app instance
const app = getApp();
Page({
data: {},
onLoad() {
// Get user information and render
app.getUserInfo().then(
user => this.setData({
user,
}),
);
},
// Listen to lifecycle
onShow() {
// Render global data to current page
this.setData({ todos: app.todos });
},
// Event handler
onTodoChanged(e) {
// Modify global data and re-render
const checkedTodos = e.detail.value;
app.setTodos(app.todos.map(todo => ({
...todo,
completed: checkedTodos.indexOf(todo.text) > -1,
})));
this.setData({ todos: app.todos });
},
addTodo() {
// Call page jump API for page jump
my.navigateTo({ url: '../add-todo/add-todo' });
},
});
In this file, we have:
- Listen to and process the lifecycle function of the page (
onHide
,onShow
,onLoad
,onUnload
,onReady
).
- Get Mini Program app instance and other page instances (
getApp
,getCurrentPages
).
- Declare and process data
- Respond to page interaction events, call APIs, etc.
- Attention here: the
app.todos
object is the global variable defined inapp.js
.
The todos.acss
is the style file of the page:
.page-todos {
flex: 1;
display: flex;
flex-direction: column;
}
.user {
display: flex;
padding: 30px 30px 0 30px;
}
.avatar {
width: 128rpx;
height: 128rpx;
margin-right: 40rpx;
border-radius: 50%;
}
.nickname {
display: flex;
flex-direction: column;
justify-content: center;
font-size: 40rpx;
}
.todo-items {
padding: 80rpx;
}
.todo-items-group {
display: flex;
flex-direction: column;
}
.checked {
color: #d9d9d9;
text-decoration: line-through;
}
.todo-item {
margin-bottom: 15px;
}
The acss
styling file is not mandatory. See Style document for acss
file syntax. When a page has the style sheet, the style rule in the page style sheet overrides the style rules in the app.acss
. if the style sheet is not specified for the page, it is also possible to directly use the style rules specified in app.acss
.
The todos.json
is the configuration file of the page. Here it is an empty file.
The configuration file is not mandatory. When a page has the configuration file, the configuration item overwrites the same configuration items in the window of app.json. If no page configuration file is specified, the page directly uses the default configuration in app.json. Therefore, the index page title is the Todo App specified for app.json.
Add Todo Page
The add-todo.axml
is the structure template file of the page:
<view class="page-add-todo">
<view class="add-todo">
<input
class="add-todo-input"
placeholder="What needs to be done?"
onBlur="onBlur"
value="{{inputValue}}"
/>
</view>
<view class="todo-footer">
<add-button text="Add Todo" onClickMe="add" ></add-button>
</view>
</view>
There are two core functions in the page:
- Use the
<input/>
component to accept user input.
- The
<add-button>
is a custom component. We can wrap the whole codes of some function into a custom component for easy reuse elsewhere.
add-todo.js
page logic code:
const app = getApp();
Page({
data: {
inputValue: '',
},
onBlur(e) {
this.setData({
inputValue: e.detail.value,
});
},
add() {
app.todos = app.todos.concat([
{
text: this.data.inputValue,
compeleted: false,
},
]);
my.navigateBack();
},
});
add-todo.acss
is consistent with todos.acss
usage and will not be described again.
Since the add-todo.json
refers to a custom component, it should be declared in json, otherwise error will be reported:
"usingComponents": {
"add-button": "/components/add-button/add-button"
}
We will learn how to publish a Mini Program in the next tutorial.