项目目录理解
components | 自定义组件库 |
config | 一个公用的数据配置 |
images | 本地、上传的图片放置 |
pages | pages目录存储小程序的每个页面,每个页面包含四个文档.json为配置文件.wxml 为模板文件,相当于HTML模板.wxss 为样式文件,相当于HTML的CSS样式表.js 为JS 脚本逻辑文件,相当于HTML的js脚本 |
utils | 一个共用程序逻辑库公共的js函数文件,通过module.exports的方式暴露pages下的每个页面使用不需要每个页面编写重复的Js代码。 |
app.js | 必填,小程序逻辑 |
app.json | 必填,小程序公共配置 |
app.wxss | 选填,小程序公共样式表 |
project.config.json | 项目配置文件或称为项目IDE配置文件在“微信开发者工具”上做的任何配置都会写入到这个文件 |
绝对路径和相对路径
“/”表示根目录
"…"表示返回上一级
区别:相对路径习惯用“…/”表示上一级
尺寸
rpx
换算:1px = 1rpx 要求:设计搞宽高满足750X1334 ipone6
px与rpx的区别:rpx可以自适应。让元素宽高根据不同屏幕自适应,px是固定大小的尺寸
元素偏移量
<view class="parent">
<view>hello</view>
<view class="child"></view>
</view>
.parent{
display:inline-flex; /* 自适应宽度 */
width:90rpx;
padding:10rpx; /* 解决子元素偏移量超出不显示问题,让子元素正常显示 */
}
.child{
position:relative;
top:-10rpx;
left:6rpx
}
字体
eg:font-family:“PingFangSC-Thin” 设置平方细体 ,只在ios上有效
消除字体上下间距:eg:font-size:24rpx;line-height:24rpx;
数据来源
wxml
js——>wxml
服务器——>js——>wxml
数据绑定
“{{}}”插值
属性中同样使用“{{}}”
组件中存储数据有两个地方:properties存储其他外部引用的数据;data里存储组件中单独使用的数据
三元表达式:{{key? ‘yes’:‘no’}}。在双大括号“{{}}”中使用
生命周期函数
onLoad:function(options){ } //监听页面加载
onReady:function(){ } //监听页面初次渲染完成
onShow:function(){ } //监听页面显示
onHide:function(){ } //监听页面隐藏
onUnload:function(){ } //监听页面卸载
组件性的封装性、开放性、粒度:小组件灵活、大组件放方便
封装性:data里存储组件封装的数据供组件内部使用
开放性:properties存储组件开放的数据供其他外部使用;
粒度:组件功能的封装开放性
properties详解:
properties下的属性:对象形式
三个属性:eg:
like:{
type:String //类型,必须
value: '' //初始值,
observer:function(){}
}
<view class="like-box" bindtap="onLike">
<image src="{{islike?isimg:notimg}}" class="like-img"></image>
<text class="like-text">{{count}}</text>
</view>
//开放属性:为了可以从外部设置的属性
properties: {
islike: { // javascript对象:属性type(属性类型,必填)、value(初始默认值)、observer()
type: Boolean,
value: false,
observer:function(){...}
},
count: {
type: Number,
value: 9
}
},
//封闭属性:内部属性
data:{
isLike:true,
yesImg:'/images/yes.png',
noImg:'/images/no.png'
}
//粒度
methods: {
onLike:function(event){
let islike = this.properties.islike
let count = this.properties.count
count = islike ? count - 1 : count + 1
this.setData({
count: count,
islike: !islike
})
}
}
组件事件应用:
访问properties中的属性:this.properties.islike
methods: {
onLike:function(event){ //自定义事件
let islike = this.properties.islike //访问properties中的属性
let count = this.properties.count
count = islike ? count - 1 : count + 1
this.setData({
count: count,
islike: !islike
})
}
}
js中取data、properties中的数据
this.data.数据属性
this.properties.数据属性
js中改变data、properties中的数据:
data:{
like:false
}
this.setData({
like:!this.data.like
})
@TOC
url | 服务器接口地址,必须 |
data | 请求的参数 |
header | 请求的头部 |
method | 请求方式:POST(请求数据)、GET(提交数据)、PUT(更新数据)… |
success | 成功的回调参数 |
fail | 失败的回调参数(一般的失败不包括返回失败状态吗之类的错误,而是网络错误等错误) |
HTTP状态码
200 请求成功
201 创建成功
202 更新成功
204 删除成功
301 永久重定向
400 请求包含不支持的参数
401 未授权
403 被禁止访问
404 请求的资源不存在
413 上传的file文件体积过大
500 服务器错误
wx:request二次封装
wx.request(object):发起网络http请求
属性参数:
url:'' //开发者服务器接口地址
data:'' //请求的参数
header:'' //设置请求的 header,header 中不能设置 Referer。content-type 默认为 application/json
method:'' //HTTP 请求方法(GET\POST\PUt\DELETE\HEAD\OPTIONS\TRACT\CONNECT)
dataType :'' //返回的数据格式(JSON\其他)
responseType: '' //响应的数据类型
success: //接口调用成功的回调函数
fail : //接口调用失败的回调函数
complete : //接口调用结束的回调函数(调用成功、失败都会执行)
wx.request({
url: '',
data:'',
header:'',
method:'',
dataType:'',
success:
})
a) 根目录下的config.js做一些常量配置
b) http.js请求方法写请求方法,并引用常量配置文件
c) module配置页面请求方法接口模型
d) 页面导入实例化使用
// config.js
const config = {
api_base_url: 'http://bl.7yue.pro/v1/',
appkey: "AbhC31IG7ruCDp57",
}
export { config }
// http.js
import {config} from '../config.js'
const tips = {
// 自定义错误码提示
1: '抱歉,出现了一个错误',
1005:'appkey无效,请前往www.7yue.pro申请',
3000:'期刊不存在'
}
class HTTP{
request(params){
// url, data, method,
if(!params.method){
params.method="GET"
}
wx.request({
url:config.api_base_url + params.url,
method:params.method,
data:params.data,
header:{
'content-type':'application/json',
'appkey':config.appkey
},
success:(res)=>{
// 获取http状态码
let code = res.statusCode.toString()
if (code.startsWith('2')){
//请求回调函数,把请求结果通过success回调函数传递回去
params.success && params.success(res.data)
}
else{
// 服务器异常调用
let error_code = res.data.error_code
this._show_error(error_code)
}
},
fail:(err)=>{
this._show_error(1)
}
})
}
// 服务器异常方法
_show_error(error_code){
if(!error_code){
error_code = 1
}
const tip = tips[error_code]
wx.showToast({
title: tip?tip:tips[1],
icon:'none',
duration:2000
})
}
}
export {HTTP}
// module/classic.js
import { HTTP } from '../utils/http.js'
// 继承
class Classic extends HTTP {
getLatest(sCallback) {
this.request({
url: 'classic/latest',
method: 'GET',
success: (res) => {
sCallback(res)
}
})
}
}
export { Classic }
// index.js
import { Classic } from '../../models/classic.js'
let classicModel = new Classic()
data: {
classicData:null,
},
onLoad: function (options) {
classicModel.getLatest((res)=>{
console.log(res)
this.setData({
classicData:res
})
})
},
export与import
export导出模块
import导入模块
注意事项:(1)import导入的名字必须与export的一样(2)使用 as重命名
全局使用:app.js
App({
// 全局数据对象
globalData: {
isIphoneX: false,
isIos: false,
screenHeight: 667,
screenWidth: 375,
windowHeight: 667,
windowWidth: 375,
rpx: 0.5,
user_id: '',
open_id: '',
},
// 应用程序启动时触发一次
onLaunch() {
//获取系统信息,获取手机型号
//screenWidth 、screenHeight(屏幕宽、高)
//windowWidth 、windowHeight (可使用窗口宽、高)
//windowWidth 、windowHeight (可使用窗口宽、高)
// model(型号)
// platform (客户端平台)
var that = this;
wx.getSystemInfo({
success(res){
that.globalData.screenHeight = res.screenHeight;
that.globalData.screenWidth = res.screenWidth;
that.globalData.windowHeight = res.windowHeight;
that.globalData.windowWidth = res.windowWidth;
that.globalData.rpx = Number((res.windowWidth / 750).toFixed(4));
if (res.model.search('iPhone X') != -1) {
that.globalData.isIphoneX = true
}
if (res.platform == 'ios') {
that.globalData.isIos = true;
}
}
});
},
// 全局方法,具体的把一些后面页面操作公共数据的公共方法写在这里
onHide() {
this.data.webShowed = false
},
setOpenId(open_id) {
this.globalData.open_id = open_id;
},
getOpenId() {
return this.globalData.open_id;
},
setUserId(user_id) {
this.globalData.user_id = user_id;
},
getUserId() {
return this.globalData.user_id;
}
});
组件的定义与使用
- 定义
a) 组件存储目录:components
b) 新建组件:新建目录——>新建component
c) 组件名字两级名字不需要都一样,可以目录外层命名,页面都定义为index
- 使用
a) 定义
组件存储目录:components
新建组件:新建目录——>新建component
组件名字两级名字不需要都一样,可以目录外层命名,页面都定义为index
b) 引用和使用
组件定义完没有任何突出,只需要在page页面中引用就可以使用了
引用:首先在要引用组件的页面的.json里,找到“usingComponents”属性,把要引用的组件通过对象键值对配置好就好;组件引用要使用绝对路径(/斜杠表示根目录);“key”:“components/like/index”,key为自定义组件名,为了容易看出是组件,推荐v-开头,eg: “v-like”
使用:
c) 从外部设置组件propeties中的属性值:
把数据从页面js绑定到页面中的组件上
d) 自定义事件的激活与监听:
组件上:bind:islike=“onLike”
js:激活islike事件this.triggerEvent(‘islike’,{behavior: behavior },{});第一个参数是自定义事件名称,第二个是传递的参数,第三个…
页面自定义事件监听:onLike(e){console.log(e.detail.behavior)} 从中就能取到事件传递的参数
<!--components/like/index.wxml-->
<view class="like-box" bindtap="onLike">
<image src="{{islike?isimg:notimg}}" class="like-img"></image>
<text class="like-text">{{count}}</text>
</view>
// components/like/index.js
Component({
properties: {
islike:{
type:Boolean,
value:false
},
count:{
type:Number,
value:9
}
},
data: {
isimg:"/images/shouye/islike.png",
notimg:"/images/shouye/notlike.png"
},
methods: {
onLike:function(event){
//自定义事件
let islike = this.properties.islike
let count= this.properties.count
count = islike?count-1:count+1
this.setData({
count:count,
islike:!islike
})
//激活一个事件 this.triggerEvent
let behavior = this.properties.islike?'islike':'notlike'
this.triggerEvent('islike',{
behavior: behavior
},{})
}
}
})
// index.json
{
"usingComponents":{
"v-like":"/components/like/index",
}
}
// index.wxml使用组件
<v-like like="{{classicData.like_status}}" count="{{classicData.fav_nums}}" bind:islike="onLike" />
// index.js
onLike:function(event){
let behavior=event.detail.behavior
let id = this.data.classicData.id
let types = this.data.classicData.type
likeModel.like(behavior, id,types)
},
// module/like.js
import { HTTP } from '../utils/http.js'
class Like extends HTTP {
like(behavior,artId,category){
let url = behavior == 'islike' ? 'like' :'like/cancel'
console.log(behavior, artId, category)
this.request({
url:url,
method:"POST",
data:{
index:artId,
type:category
}
})
}
}
export {Like}
- 组件图片的使用: 建议放在comonents下的images里
初始化授权
<button open-type="getUserInfo" bindgetuserinfo="goBegin">开始</button>
goBegin: function (e) {
console.log(e)
if (e.detail.errMsg == 'getUserInfo:ok') {
// 授权成功,提交用户信息到后台,重定向到首页
}
},