🎉🎉🎉
介绍
用原生的微信小程序代码写了一个自我的社交项目。
这是一个自我社交的项目,没有接口,数据存储在本地,可以理解成一个自嗨的树洞。
一个项目的实战是一个不断自我学习的过程,在这个过程中,遇到了很多问题,将面临怎么样的思考,如何解决。
项目演示
下面是部分页面的截图:
知识点合集
话不多说,上干货,以下所有知识点都基于项目:
创建新页面
创建新页面不需要手动一个文件一个文件的创建,在app.json文件里面,当你每输入一个page,系统就会在pages文件夹下面自动创建好所有的文件+文件夹
"pages": [
"pages/message/message",
"pages/pao/pao"
],
底部tab的实现
在app.json文件里面,可以统一配置底部tabbar栏
"tabBar": {
"color": "#999",
"selectedColor": "#444",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/message/message",
"text": "bibi",
"iconPath": "assets/tabs/message.png",
"selectedIconPath": "assets/tabs/message-active.png"
},
{
"pagePath": "pages/pao/pao",
"text": "开炮",
"iconPath": "assets/tabs/pao.png",
"selectedIconPath": "assets/tabs/pao-active.png"
}
]
},
获取微信用户的信息
当我们初始化微信小程序的时候,app.js里面自带了获取微信用户信息的代码:
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
如上面代码可以知道,获取到的用户信息已经存储到了app的globalData里面:
globalData: {
userInfo: null
}
如果我们想要在其他page使用到userInfo
:
const app = getApp()
const userInfo = app.globalData.userInfo
但是:
值得注意的是this.userInfoReadyCallback
因为获取用户信息是异步的,所以我们并不能保证在渲染页面之前就能够拿到用户信息,所以有了这个callback函数供我们使用,比如在home.js页面,我们在生命周期onload函数里面:
onLoad: function (options) {
const userInfo = app.globalData.userInfo;
if (userInfo) {
this.setData({
user: userInfo,
hasUserInfo: true
})
} else {
app.userInfoReadyCallback = res => {
this.setData({
user: res.userInfo,
hasUserInfo: true
})
}
}
},
如果在加载页面之前已经有userInfo了,那太好了,直接设置。如果没有就调用userInfoReadyCallback
回调函数,设置一下。
getStorageSync
这个项目所有的数据都是存储在本地storage里面的,作为一个对内的项目,这个storage的功能是非常好的。在关闭了小程序重新打开,里面的数据也不会丢失!
getStorage
有两个方法
- 一个是
getStorage
wx.getStorage({
key: 'mentions',
success: (res)=>{
const storageList = res
}
})
- 一个是
getStorageSync
(推荐)
const storageList = wx.getStorageSync('mentions');
选择手机相册的图片/拍照
wx.chooseImage({
count: 6, //允许选择的图片数
sizeType: ['original', 'compressed'], //原始的 / compressed压缩过的
sourceType: ['album', 'camera'], // 相册 和 相机
success (res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths
that.setData({
imageList: [...that.data.imageList, ...tempFilePaths]
})
}
})
图片被挤压
在我刚开始做的时候,<image>
里面的图片压缩自己,填充在了image里面,这很难看,并不是我想要的效果,解决办法是:mode="aspectFill"
:
<image mode="aspectFill" class="image" src="{{image}}" bindtap="previewImage" data-src="{{image}}" data-list="{{imageList}}"> </image>
wxml里如何给方法传递参数
data-?="参数"
data-list="{{imageList}}"
wxml:
<image mode="aspectFill" class="image" src="{{image}}" bindtap="previewImage" data-src="{{image}}" data-list="{{imageList}}"> </image>
js:
previewImage: function(e){
const list = e.target.dataset.list;
}
system/sdk
当我想要使用接口wx:animate
,结果发现不能使用,上网一查原来是版本太低,如何查看版本:
wx.getSystemInfoSync()
得知了自己版本低之后,如何升级版本?
在开发者工具里面顶部有一个按钮:详情,点击之后,选择“本地设置”,调试基本库改一下就好!
动画Animation
调好了库,那么wx的animation如何实现呢:
实现一个height
从0到100%:
heightAnimation('#main',0,100)
heightAnimation: function(id, start, end, callback){
this.animate(id, [
{height: `${start}%`},
{height: `${end}%`}
], 500, callback && callback())
}
实现一个opacity
从0到1,从透明变不透明:
opacityAnimation('#main',0,1)
opacityAnimation: function(id, start, end, callback){
this.animate(id, [
{opacity: start},
{opacity: end}
], 500, callback && callback())
},
如何使用component
从最开始的全量page到最后的component拆分,component拆分可以使代码变得不那么臃肿庞大,修改重构的时候,都能够快速定位到某一部分的代码,提升开发效率:
如果要在某一个父组件里面使用xx component,就要在这个父组件的json文件里面定义一下:
{
"component": true,
"usingComponents": {
"user-des": "./components/user-des/user-des",
"user-info":"./components/user-info/user-info",
"user-behaviour":"./components/user-behaviour/user-behaviour"
}
}
在wxml里面引入方式:
<view class="top">
<user-info class="info" user="{{user}}" time="{{item.time}}"></user-info>
<user-behaviour class="behaviour" id="{{item.id}}" list="{{item.images}}" bind:onDelete="onDelete" bind:onUpdate="onUpdate"></user-behaviour>
</view>
父组件与子组件之间的通信传值/传参
1.父组件如何向子组件传值
这是父组件A的代码,向子组件user-info
传递了user
和 time
:
<view class="top">
<user-info class="info" user="{{user}}" time="{{item.time}}"></user-info>
<user-behaviour class="behaviour" id="{{item.id}}" list="{{item.images}}" bind:onDelete="onDelete" bind:onUpdate="onUpdate"></user-behaviour>
</view>
子组件如何接受到父组件传递过来的值:
properties
就是保存父组件传递过来的值,data
就是组件自己的值。这里和React的props和state特别像!
Component({
/**
* 组件的属性列表
*/
properties: {
user:{
type:Object,
value:{}
},
time:{
type: String,
value:''
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
2.子组件如何向父组件传值
在react里面通过的方式,就是通过函数的回调给父组件传值!
子组件js文件:
onDeleteChild: function(){
this.triggerEvent('onDeleteFather',{id: this.properties.id});
}
父组件的wxml文件:
<user-behaviour class="behaviour" id="{{item.id}}" list="{{item.images}}" bind:onDeleteFather="onDeleteFatherSelf" bind:onUpdate="onUpdate"></user-behaviour>
触发了父组件自己的onDeleteFatherSelf方法,获取到了子组件传递过来的id:
onDeleteFatherSelf: function(e){
const id = e.detail.id
}
部分生命周期的执行顺序
在选择图片的时候,弹出手机的相册,这个时候,当前page页面会执行onHide生命周期, 当你关闭了选择图片的框框, 会执行onShow生命周期
生命周期这个东西,光用脑子想还是不行的,很快就忘了,最重要的还是实践!实践!实践!⛽️
wxs:如何在wxml的class里面用函数(传参)
写代码的途中自己有个需求就是,需要在class里面调用函数,并且还可以传递参数,三元表达式已经不能满足我了,于是我找到了一个可以实现的方法,就是wxs:
如何使用wxs:
- 新建一个wxs文件,里面写着你的function, 记得导出
- 在wxml里面引入
<wxs src="./delete-animation.wxs" module="dm" />
md.导出的方法
页面跳转
【注意⚠️】如果是tab页跳转tab页,navigate是失效的,一定要用switchTab!
【注意⚠️】但是switchTab不能传递参数!navigate可以传递参数!
【注意⚠️】又要用switchTab,又要传递参数,可以把数据存储在app的globalData里!