How many people want to develop a small program and find that their foundation is 0.
Today, I would like to share with you an inspirational case: a girl who reads atmospheric science and teaches herself the front-end development, because she likes to browse and know, she has made a "imitation" small program.
I hope her development experience can help you take the first step in small program development with ease and pleasure.
Author | Rebecca Han
WEB Front End/Unreliable Weather Forecaster/Little Fairy Wanting to Code
from Wechat applet Beginning with internal testing, I have finally finished demo my own micro-program.
It's really finished in ink. Even I admire my procrastination (lazy cancer girl has abandoned treatment (A') in short, it's basically finished (clearly there are many components, API s are not good at all) and I've never written a blog.
For a long time before, I was aware of heavy dependence. So, this demo's mock-up object was chosen by KNOWLEDGE (but half of it found that my decision was in the hole, that's what I said later).
Demo's interface design and interaction design come from the Android version.
- Tool: Using the Wechat web Developer Tool, this tool has been fully open to non-invitation internal test users, and in continuous updates (I code in the process of updating two versions, so IDE version is not unique at the time of development). In fact, after enduring half an hour of Wechat's developer tools, I edited them in Webstorm, and Wechat tools became tools for running previews. But I heard that the effect of preview in IDE can not be guaranteed to be the same as the real one.~
- Design and Functions: Refer to the very easy version of Android, and in order to prevent copyright issues, the Face data in Demo uses my own answers.
Document Construction
1. Basic documents
app.json:
{
"pages": [
"pages/index/index",
"pages/discovery/discovery",
"pages/notify/notify",
"pages/chat/chat",
"pages/more/more",
"pages/answer/answer",
"pages/question/question"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#0068C4",
"navigationBarTitleText": "Know about",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true
},
"tabBar": {
"color": "#626567",
"selectedColor": "#2A8CE5",
"backgroundColor": "#FBFBFB",
"borderStyle": "white"
"list": [{
"pagePath": "pages/index/index",
"text": "",
"iconPath": "images/index.png",
"selectedIconPath": "images/index_focus.png"
}, {
"pagePath": "pages/discovery/discovery",
"text": "",
"iconPath": "images/discovery.png",
"selectedIconPath": "images/discovery_focus.png"
}, {
"pagePath": "pages/notify/notify",
"text": "",
"iconPath": "images/ring.png",
"selectedIconPath": "images/ring_focus.png"
}, {
"pagePath": "pages/chat/chat",
"text": "",
"iconPath": "images/chat.png",
"selectedIconPath": "images/chat_focus.png"
}, {
"pagePath": "pages/more/more"
"text": ""
"iconPath": "images/burger.png"
"selectedIconPath": "images/burger_focus.png"
}]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": true
}
app.json file is the global configuration of the whole applet. The main fields used are pages, window, tabBar, networkTimeout.
- Pages field: Pages of all applets are registered in this field. The first page in the field array defaults to the home page of applets (except tab setting). Pages that have not been registered in pages field seem unable to compile effectively (previous editors did not have this restriction, but only affect the allocation). The editor will report unregistered errors when it updates the files and so on.
- window field: Most of them are about navigationbar settings at the top of the applet.
- Tab Bar Fields: If you need a tabbar style at the bottom of the home page, set each tab corresponding page in the tabBar field, which corresponds left to right in order, including path, tab text, tab icon and selected status icon.
- Network Timeout: Set the network timeout.
- Debug: Open debug mode.
app.wxss file is global style, that is to say, the style in this file can be used in all pages. If the same attributes are defined in WXSS of other page files, the style in the file is overwritten, and the rules are roughly the same as the CSS priority rules.
app.js is used to call logic interfaces, callbacks, periodic functions, local storage, and so on.
2. Page files
Page file consists of four parts.
For example, if we have a homepage called index, we need to create three necessary files with the same file name under the pages folder:
- index.wxml
- index.wxss
- index.js
In addition, the index.json file is optional and has the same function as app.json. It is a configuration file for the page, but its definition function is limited.
3. UI
As usual, code UI is of course the first step.
Except for some new tag and style rules that need to be followed by Wechat, the other UIs are not very different from normal code UIs.
And it should be emphasized that flex layout is easy to use in Wechat applet.
However, as a girl and a programmer, it's not me who is not picky, so here are some pits I encountered, some of which may be incorrect (more inclusive (//)), and some may have been amended in IDE updates:
- There are some CSS styles that are not supported in Wechat IDE, such as font-weight, letter-spacing (and the style of adjusting word spacing).
- Nesting is not supported in <text/>, and the contents in the inner layer will be displayed twice in succession under <text/> two-tier nesting structure (corrected in subsequent IDE updates);
- If < view /> is the same level as < text />, then < view /> will obscure < text /> in actual use. In order to prevent overlapping of content, it is necessary to use <view/> juxtaposition. So unlike some places, you can use <view/> as <div> completely!
- When there is a vertical adjacent margin before the element, the margin of the two elements will be spread out, which does not follow the margin folding rule.
- The label hidden attribute is invalid (corrected in v0.10.101400);
- In some cases, the level element label priority will be problematic. For example, flat labels A and B, when B overlaps with element A through some adjustments, the effect of Wechat IDE resolution is that the content and background color of A will cover the overlapping part of element B (common browser resolution should be B over A);
- If data is rendered by template + list rendering, the {item} rendered by list in template is invalid and cannot be recognized correctly. Therefore, when rendering a list, the reused part should be written in the code block of the list rendering (which belongs to the data rendering part, which will be mentioned later).
Later, some of the problems in the above list have been corrected in the iteration of Wechat IDE, so this list may be outdated. You can also try it on your own according to the actual situation.
Next, I'll explain some of the parts used in demo.
Start actual development
1. List-based data rendering
Similar to "Home Page" and "Discovery Page", which are standard tabular data presentation methods, Wechat offers a good solution: list rendering.
<block wx:for="{{feed}}" wx:for-index="idx" wx:for-item="item" data-idx="{{idx}}">
<view class="feed-item">
<view class="feed-source">
<a class="">
<view class="avatar">
<image src="{{item.feed_source_img}}"> </image>
</view>
<text> {{item.feed_source_name}} {{item.feed_source_txt}} </text>
</a>
<image class="item-more" mode="aspectFit" src="../../images/more.png"></image>
</view>
<view class="feed-content">
<view class="question" qid="{{question_id}}" bindtap="bindQueTap">
<a class="question-link">
<text>{{item.question}}</text>
</a>
</view>
<view class="answer-body">
<view bindtap="bindItemTap">
<text class="answer-txt" aid="{{answer_id}}"> {{item.answer_ctnt}} </text>
</view>
<view class="answer-actions" bindtap="bindItemTap">
<view class="like dot"> <a>{{item.good_num}} agree with </a> </view>
<view class="comments dot"> <a>{{item.comment_num}} comment </a> </view>
<view class="follow-it"> <a>Concerns</a> </view>
</view>
</view>
</view>
</view>
</block>
It can be seen intuitively that a set of data is rendered for recycling repetitive structures:
- The content in for="{}" is a set of data that you want to loop around, with the outermost layer being an array structure.
- for-item Specifies the variable name of the current element in the array
- for-index Specifies the name of the subscript variable for the current element in the array
It also uses custom tabbar s at the top of discovery pages and notification pages for rendering.
2. Top Tabbar Implementation
Wechat only provides the bottom tabbar, so you have to write it yourself at the top.~
The top tab bar is implemented for list rendering and JS coordination.
Instance WXML code:
<view class="top-tab flex-wrp flex-tab ">
<view class="toptab
flex-item {{currentNavtab==idx ? 'active' : ''}}" wx:for="{{navTab}}" wx:for-index="idx" wx:for-item="itemName" data-idx="{{idx}}" bindtap="switchTab"> {{itemName}} </view>
</view>
<scroll-view scroll-y="true" class="container discovery withtab" bindscrolltoupper="upper" bindscrolltolower="lower" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}">
<view class="ctnt0" hidden="{{currentNavtab==0 ? '' : true}}"> </view>
<view class="ctnt1 placehold" hidden="{{currentNavtab==1 ? '' : true}}">
<text>Round table</text>
</view>
<view class="ctnt2 placehold" hidden="{{currentNavtab==2 ? '' : true}}">
<text>Popular</text>
</view>
<view class="ctnt3 placehold" hidden="{{currentNavtab==3 ? '' : true}}">
<text>Collection</text>
</view>
</scroll-view>
JS code:
//discovery.js
Page({
data: {
navTab: ["Recommend", "Round table", "Popular", "Collection"]
, currentNavtab: "0"
}
, onLoad: function () {
console.log('onLoad')
}
, switchTab: function (e) {
this.setData({
currentNavtab: e.currentTarget.dataset.idx
});
}
});
Because Wechat does not support using dom to access objects, that is, dom and window objects, the implementation of tab bar relies on the display logic of view layer provided by Wechat and the binding mechanism between view and data.
Binding click events, by changing the value of a data - attribute, controls the change of the class of the element (thus changing the style, etc.).
3. Rotary Planting Map
The following is the WXML code for implementation:
<swiper class="activity" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
<block wx:for="{{imgUrls}}">
<swiper-item>
<image src="{{item}}" class="slide-image" width="355" height="155" />
</swiper-item>
</block>
</swiper>
JS code:
imgUrls: [
'../../images/24213.jpg'
, '../../images/24280.jpg'
, '../../images/1444983318907-_DSC1826.jpg'
]
, indicatorDots: false
, autoplay: true
, interval: 5000
, duration: 1000
, feed: []
, feed_length: 0
The implementation of the round-robin graph is based on the swiper component provided by Wechat, which provides various attribute choices, such as autoplay, interval time duration, etc.
The swiper-item contains all the rotated images. In order to modify the image data conveniently, the same way is used to render and bind the data.
4. Drop-down refresh, pull-up load, and data request
The action of refreshing and continuing loading depends on scroll-view tags and matching upper and lower events.
Attributes of tags provide bindscrolltoupper and bindscrolltolower to bind events triggered by scrolling to the top and bottom, while upper-threshold and lower-threshold can adjust the distance between triggering time and boundary.
In addition to the above, the API of the applet also provides interfaces for horizontal scrolling, scrolling trigger events, setting scroll bar positions, and so on.
<scroll-view scroll-y="true" class="container" bindscrolltoupper="upper" upper-threshold="10" lower-threshold="5" bindscrolltolower="lower" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}">
<block wx:for="{{feed}}" wx:for-index="idx" wx:for-item="item" data-idx="{{idx}}">
<view class="feed-item">
<view class="feed-source">
<a class="">
<view class="avatar">
<image src="{{item.feed_source_img}}"> </image>
</view>
<text> {{item.feed_source_name}} {{item.feed_source_txt}} </text>
</a>
<image class="item-more" mode="aspectFit" src="../../images/more.png"> </image>
</view>
<view class="feed-content">
<view class="question" qid="{{question_id}}" bindtap="bindQueTap">
<a class="question-link">
<text>{{item.question}}</text>
</a>
</view>
<view class="answer-body">
<view bindtap="bindItemTap">
<text class="answer-txt" aid="{{answer_id}}"> {{item.answer_ctnt}} </text>
</view>
<view class="answer-actions" bindtap="bindItemTap">
<view class="like dot"> <a>{{item.good_num}} agree with </a> </view>
<view class="comments dot"> <a>{{item.comment_num}} comment </a> </view>
<view class="follow-it"> <a>Concerns</a> </view>
</view>
</view>
</view>
</view>
</block>
</scroll-view>
When scrolling to the top or bottom, the event triggered to load data should have invoked the network request API provided by Wechat to obtain data.
However, the pitfall is that when I chose to write a mock demo, I did not notice that the mock demo did not provide an open API, while the Wechat API did not support direct local requests for JSON files.
Unfortunately, we choose to forge a piece of data in the JS file and throw it out with module.exports to request the fake data:
upper: function () {
wx.showNavigationBarLoading()
this.refresh();
console.log("upper");
setTimeout(function () {
wx.hideNavigationBarLoading();
wx.stopPullDownRefresh();
}, 2000);
}, lower: function (e) {
wx.showNavigationBarLoading();
var that = this;
setTimeout(function () {
wx.hideNavigationBarLoading();
that.nextLoad();
}, 1000);
console.log("lower")
}, //scroll: function (e) {
// console.log("scroll")
//},
//Network Request Data to Realize Refresh
refresh0: function () {
var index_api = '';
util.getData(index_api).then(function (data) {
//this.setData({
//
//});
console.log(data);
});
}, //Using local fake data to achieve refresh effect
refresh: function () {
var feed = util.getDiscovery();
console.log("loaddata");
var feed_data = feed.data;
this.setData({
feed: feed_data
, feed_length: feed_data.length
});
}, //Continue loading using local fake data
nextLoad: function () {
var next = util.discoveryNext();
console.log("continueload");
var next_data = next.data;
this.setData({
feed: this.data.feed.concat(next_data)
, feed_length: this.data.feed_length + next_data.length
});
}
Because of the fake data, this demo does not do real functions such as jumping with parameters, querying and so on.
While loading the data, use the loading animation wx. show Navigation BarLoading ();.
5. Other
- In order to realize click-jump page, wx.navigateTo is used for page Jump and click event binding.
- Modularization of some common components;
- Use of input, image, component, etc.
6. Follow-up
There are still a lot of components and API s that haven't been used yet. This demo may be updated in the future, depending on the severity of the condition of the lazy cancer girl.
A little feeling
In fact, as a small front-end, due to the reasons of work, the use of MVVM is very rare.
Nevertheless, after writing the demo program, I have straightened out this aspect of thinking. Of course, there are still too many shortcomings when we look back after writing. It is clear that there are many places where we can change the way of writing.
After all, this is my first attempt to write a demo with something new and hot, and also my first attempt to write a tutorial... Or is it a record? whatever~~
Anyway ~I hope that besides writing code, I can also walk on the road of code writing. After all, I am a code fairy.