preface
Every programmer, at the beginning of time is a little white, bit by bit accumulation, step by step, slowly grow up. I believe that for the big guys, it is not difficult to write a small program, but for me this kind of learning is not long for people, every step is in the mud, do not know where there is a pit in the mud, of course, this for the novice, is a kind of growth, step on the pit, the road will gradually smooth up.
So still want to refuel struggle.
This is the first small program project I wrote, because it is with others, I wrote part of it, I want to write this article, record my first small program project, at the same time to write their own small program, share with you, I hope to help people in the effort.
Applets sharing
Bilibili_appellate P
Overall effect display
Take a look at the results:
These are some of the tools used to write applets.
There are like vant components
Official documents of wechat applets
Fiddler packet capture tool
Alibaba Font Library
page
As a whole
Start to write small procedures, the first is to cut the page, first look at the home page
What do we use when we write pages?
-
External styles, such as WeUI styles
-
External components, such as Vant
-
Since the writing component
-
The writing style
-
Font library, such as Alibaba font library
Some common styles, such as search boxes, navigation bars, etc., or components, can be introduced to external direct use, usage is documented, look at the use of the page, but without similar components and styles, you have to write your own page to use ICONS in many places, ICONS also reference external font libraryCopy the code
Page architecture
- van-search-van-tabs - hot - hot_item - chase_date_item - day_of_week - chase_index - chase_recommend - chase_recommendCopy the code
Use the Vant components Search and van-tabs to quickly assemble the entire page
And then under the popular TAB, it’s all a list of videos in one style, so I’ll just use a Wx: for loop, and I’ll wrap the TAB in a Scroll view for easy scrolling
Chase_date_item is obviously a van-tabs, but each TAB looks like a van-tabs. You can also use a wx: for loop with a list of tabs
The rest is the same, using the wx: for loop list
The following is the video player page and the drama player page. The search page only has a van-search, so it is not shown
Video player page:
Play page:
Styles (experience trample pit sharing)
Simple style we will write, so I will not post out, there is a need to go to my Gitee source code, link in the back of the article, if you like, you can point a collection
Here I will describe my experience and the pits I have stepped on
1. Flexible layout
Most layouts can be handled with elastic layouts. Horizontal layouts, which cannot be represented by elastic layouts, can be replaced with margins, using special selectors such as:
.chase_date_item__content:nth-child(4n+1){
margin-left: 0;
}
Copy the code
It’s 4n plus 1
Some special needs, use absolute positioning, other times less positioning, affect performance
2. One problem with elastic layout is that margin and padding defined on a box with elastic layout will increase the width and height of the box. Using a width and height limit will not work, but you can solve this problem by adding a style:
box-sizing: border-box;
Copy the code
3. One or more lines of text beyond display…
We all have one line of text that displays beyond… , the style is:
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
Copy the code
But to achieve more than one line of text display… How do you do that? :
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
Copy the code
We know we can do animations with transition. Here’s a quick introduction to the video
This looks like the transition height, but the length of the profile message is variable, so it can’t fix the height. If height is auto, the transition doesn’t work, so you have to use max-height instead. Set max-height to a value that can’t be higher than height, but it’s not too high, so it doesn’t work
.drop_content{
max-height: 40vh;
overflow: hidden;
transition: all 0.5s;
}
.drop_content_on{
max-height: 0;
overflow: hidden;
transition: all 0.5s;
}
Copy the code
5. An unruly button
Button has a lot of uses in small programs, but when we use it, its style is always not what we want, so we need to reset it
button::after { border: none; }
button {
display: inline;
padding: 0! important; margin:0! important; font-weight: normal ! important; color: #000! important; background-color: #fff ! important; }Copy the code
Here I need a button as a container for functionality, so I add styles! Important, some attributes will not take effect unless the level is raised. This is also some operations inside the button component of wechat small program, there is no way. These attributes can also be overridden by writing another class if necessary
6. Animation implementation of wechat applets
The cSS3 animation effect in the applet will not take effect. If you want to achieve the animation effect, you must use JS, and the animation property and API of the applet
Let’s see what happens
wxml
js
let animation = wx.createAnimation({ // Create an animation
duration: 300.timingFunction: 'linear'.delay: 0
});
animation.rotate(180).step(); // Add animation
this.setData({
ani:animation.export() // Add animation to data to drive the page
});
Copy the code
When you’re done, you’ll notice that the animation will only run once. It’s a Bandtap event, but it doesn’t execute every time it clicks
Of course, you can add an animation to make it go back to the previous state, click again to work
animation.rotate(180).step();
animation.rotate(0).step(); // Add an animation to return to the previous state
Copy the code
But it’s not pretty, you can see my animation is click and turn and see what happens
Rotate(n){ // Pass in a parameter
let animation = wx.createAnimation({
duration: 300.timingFunction: 'linear'.delay: 0
});
animation.rotate(180*n).step(); // Each click changes the rotation Angle of the animation according to the incoming n
this.setData({
ani:animation.export()
});
},
Copy the code
Because this button also has the ability to change page data, more on this later
7. Component style: component is written by others, he will provide you with style interface, but often not up to the effect you want, in fact, this is the same as button, appropriate addition! Important increases the priority to work, for example:
Here's the Van-Tab component, I want to design the selected style, it provides the interface, but once I write the style, the original style is broken. You want to write your own style, but the built-in style of the component prevents you, use it properly! Important makes your style workCopy the code
.tab_active{ background-color: #FB7299; margin-top: 10rpx ! important; border-radius: 60rpx; color: #fff ! important; height: 70rpx; line-height: 70rpx ! important; }Copy the code
External components have a number of properties to set different styles, this is more documentation, I used the component: van-search van-tab
Function –
Once you’re done with your pages, start writing your features. Working with your pages is exhausting, but it’s going to get even more exhausting
data
To write a complete page, a very important one is the data, no data can not see the effect, we will use a static data when writing the page to better see the effect, there is no way to design some functions, and the micro channel small program page is data-driven, it is also very important
Having said that, I did not make real data and used some fake data. I tried to find the API interface of Bilibili, but I did not find a simple and easy interface, and some other complex interfaces could not be used, so I had to find other methods. If you have a good idea also hope to leave a message
I used The Fiddler packet capture tool to capture data. For details, please refer to this article
Captured JSON data can also be imported directly into the cloud database
In addition, some uncaptured handwritten data was placed in the data folder along with some unfixed data, that is, data that changes over time.
Module. exports + require is introduced in JS when needed
Function is introduced
1. Page, style switch
Small programs often need to switch pages, of course, there is no actual jump page, just hidden, we usually use wx: if:
<view wx:if="{{... }}"><view>Copy the code
However, this method is not good for frequent switching, because Wx: if will render when needed and will destroy when not needed. Frequent switching will render and destroy frequently. Instead, we can use hidden, really hidden:
<view hidden="{{currentId! =0}}"></view> <view hidden="{{currentId! =1}}"></view>Copy the code
Style switching can be done using ternary operators:
<view class="play-information__title {{isDrop ? 'detail_drop':'detail_nodrop'}}"></view>
Copy the code
2. Load data from top to bottom
In fact this is not difficult, because the scroll - the view component itself with these two events, can see [documents] (https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html)Copy the code
<scroll-view class="hot_item-scroll" scroll-y
bindscrolltolower="addmoreAfter"
bindscrolltoupper="addmoreBefore"
upper-threshold="0"
lower-threshold="20"
>
Copy the code
The last two properties indicate the distance at which the event is triggered, with the top set to 0 and the bottom set to 20
Link the specified set in the database, only take 20 of them into data, at the same time get all the data length of the set
const db=wx.cloud.database();
const plays=db.collection('plays');
async setvoicedata(){
let res=await plays
.limit(20)
.get();
this.voiceList=res.data;
this.total=(await plays.count()).total;
this.setData({
voiceList:this.voiceList
})
},
Copy the code
Two event functions
Judge the data length of the page. If it exceeds the total length of all data, no more data will be displayed and returned; otherwise, 20 data will be pulled from all data (skip() is used to skip the data already pulled and get the new data), and then the data will be put into the data using the expansion operator, paying attention to asynchrony
async addmoreAfter(){
const index=this.data.voiceList.length;
if(index>=this.total){
wx.showToast({
title: 'No more data'.icon:'none'
})
return ;
}
wx.showToast({
title: 'Loading'.icon:'loading'.duration:1000
})
let {data:voiceList}=await plays
.skip(index)
.limit(20)
.get()
this.setData({
voiceList:[...this.data.voiceList,...voiceList]
})
},
async addmoreBefore(){
const index=this.data.voiceList.length;
if(index>=this.total){
wx.showToast({
title: 'No more data'.icon:'none'
})
return ;
}
wx.showToast({
title: 'Loading'.icon:'loading'.duration:1000
})
let {data:voiceList}=await plays
.skip(index)
.limit(20)
.get()
this.setData({
voiceList:[...voiceList,...this.data.voiceList]
})
},
Copy the code
3. Sharing
Wechat applet has built-in API, button open-type set to share;
<button open-type="share"><text class="iconfont icon-weixin1"></text></button>Copy the code
If necessary, set up some data to transmit video information
<button open-type="share"><text class="iconfont icon-weixin1" data-id="{{... }}"></text></button>Copy the code
Set the style of sharing. Js has an onShareAppMessage function that handles this event and returns an object containing the title, image, and address to jump to when opened, which can pass the ID of the video
onShareAppMessage: function () {
return{
title:this.data.playInformation.title,
imageUrl:this.data.playInformation.video_cover,
path:"/pages/play/play? id="+this.data.playInformation.playid
}
}
Copy the code
4. Collection function
I’m going to connect to the database set and change the data, and I’m going to change the user data, but because I’m not responsible for the user, I’m not going to write, same principle, change the database data and change the local data at the same time
const db=wx.cloud.database();
const _=db.command; / / cloud function
async collectPlay(){
if(this.data.isCollect){
this.playInformation.collect--;
this.setData({
isCollect:false.// Use to determine whether to collect data
playInformation:this.playInformation
});
playCollection
.where({
playid:this.data.playInformation.playid
})
.update({
data: {collect:_.inc(-1) / / the decrement}})}else{
this.playInformation.collect++;
this.setData({
isCollect:true.playInformation:this.playInformation
})
playCollection
.where({
playid:this.data.playInformation.playid
})
.update({
data: {collect:_.inc(1) / / since the increase}}}}),Copy the code
5. Search function search is to the database search, so the last function is similar, but to use the regular, fuzzy search
<van-search value="{{value}}"
show-action
shape="round"
bind:search="onSearch"
clearable="true"
/>
Copy the code
onSearch(e){
wx.showToast({
title: 'Query in progress'.icon:'loading'
});
let keyword=e.detail; // The keyword passed when the event is triggered on the search component
if(! keyword.trim()){// trim removes whitespace
wx.showToast({
title: 'Please enter the keyword you want to enter'.icon:'error'
})
return ;
}
posterCollection
.where({
title:db.RegExp({ // Regular expressions
regexp:keyword,
options:'i' // Ignore case
})
})
.orderBy('ts'.'desc') / / sorting
.get()
.then(res= >{
console.log(res);
this.setData({
result:res.data
})
})
},
Copy the code
6. Change
The animation style of the change has been introduced before, and the data of the change is also limited. At the end of the change, it will return to the first recommendation, so this is a round robin, click to go to the next one, and at the end, return to the first one
const {result}=require('.. /.. /data/recommend'); // Globally import the required data. This file can be replaced as needed
const recommend = require('.. /.. /data/recommend');
Copy the code
changeRecommend(e){
let id=e.currentTarget.dataset.id;
let [n1,n2]=this.data.n;
// n is an array for counting, because there are two identical swaps, so we define an array to count separately, and merge the two together
let n=this.data.n[id-1]; // Use the passed Id to determine which swap is triggered
if(n>6){
n=0;
} // Determine if the round is last, if so, jump to the first
const recommend=modules[id].items; // Data is stored as an array
let recommendShow=recommend.slice(n*3,n*3+3); // Get the current round data
this.Rotate(n); // Trigger animation
if(id==1) {this.setData({
recommendShow,
n:[n+1,n2] // Update data})}else{
this.setData({
recommendShowMy:recommendShow, // Update data
n:[n1,n+1]})}},Copy the code
7. Display data by date
It wasn’t hard, but it took a while to design the data, and here’s the code
chaseWeek:['一'.'二'.'三'.'four'.'five'.'六'.'day'].episodes: [{dayofweek:1.data: {... },... ]// Same array, sorted by week
// Prepare data
Copy the code
// Change the sort of data according to the date
datebar(){
const firstepisodes=this.data.episodes; // Get the initial data
let episodes=[];
let todayOfWeek=new Date().getDay(); // Get today this week
for(let i=0; i<7; i++){// Loop to change the data order
let j=(i+todayOfWeek+4) %7;
episodes.push(firstepisodes[j]);
}
this.setData({
episodes
}) // Set the data
},
Copy the code
For asynchronous reasons, I put this function in the onReady cycle, and using wx: for on the page changes the output based on the date
other
As for the components and the ability to generate posters from the canvas, it is not completely solved yet, but I need to practice for a few more days, maybe there will be a next article, if you have a share, please comment
conclusion
The above is all my share content, my small step, I do not know whether to bring you help or entertainment, I hope you can like it, like if you point a thumb-up oh
The source code
Finally, I would like to support bilibili_appellate