移动端适配方案
1、概念
物理像素(dp)
是显示设备中最小的物理部件,一旦设备出厂后,就不会发生改变。
分辨率
是指屏幕纵横方向上的像素点,单位
px
。设备独立像素(dip)
比如在 iphone 4 中,物理像素比较大,但是在表示的时候会用
2*2
个像素点去表示 1 个像素点。在不对网页进行缩放的时候,一个设备独立像素 = 1 个 css 像素
设备像素比(dpr)
dpr = dp / dip
2、设计稿
一般情况下 UI 设计师是以 iPhone 6 (iPhone se)的大小为原型进行设计,大小为 750*1334
。
3、比例缩放
前端应该使用哪些单位?px、%、em、rem、vm / vh
vm / vh
视窗单位,vm 是指将屏幕宽度分为100份,1 vw 就表示 1 % 的宽度;1vh 就表示 1 % 的屏幕高度。
会存在兼容问题,所以很多时候不是最佳方案。
rem
相对于根标签的字体大小,根标签是 html 。
换句话讲,如果根标签的大小发生改变,那么所有使用 rem 单位的大小都会发生改变。
所以有一种方案,大小单位全部使用 rem ,然后根据当前设备动态修改 html 标签字体大小。
4、lib-flexible(手淘网的过渡方案)
实现的大致思路
第一步、动态设置 viewport 的缩放。
第二步、动态计算 html 的大小:默认情况下会把屏幕分为10份。
第三步、布局的时候,根据设计稿的尺寸比例,映射到代码中来。
例如:设计稿中某个元素的宽度为 300 像素,总宽度是 750 像素
此时
html.fontSize = ‘75px’;
所以每一份的实际大小就是 75 px。在代码中该元素的大小就应该为 = 10rem * 设计稿300像素 / 750像素
每次给元素设置大小都要计算,效率非常低,所以可以引入 postcss-pxtorem
该插件自动帮助我们进行计算。
该方案在 vue 项目中实现步骤:
1)、安装模块
npm i amfe-flexible -S
npm i postcss-pxtorem -D
2)、根目录下修改 .postcssrc.js
或者 postcss.config.js
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue: 75, // 根据设计稿除以10
unitPrecision: 5, // px 转为 rem后需要保留的小数
propList: ['*'], // 允许哪些属性转换
selectorBlackList: [], // 不会被转换的 class 选择器
replace: true,
mediaQuery: false, // 是否允许在媒体查询中使用
minPixelValue: 1, // 小于1个像素就不会被转换
exclude: /node_modules/i // 排除哪些目录
}
}
}
// 在 main.js 中引入 amfe-flexible
import 'amfe-flexible'
// 完成环境创建后,在代码中就不需要计算元素打消了,直接设计稿中标注是多大的,代码中就写多少
微信开放文档
小程序开发
1、移动端开发方案
Native App(原生 APP)
IOS、Android
H5 App(移动端网页)
Hybrid App(混合开发)
ionic、mui、weex、react-native(rn)、Flutter、小程序
2、小程序的理解
不需要下载安装就可以使用的 app ,几乎拥有与原生 app 同样的能力,而且还能做到体积非常小。
3、如何开发小程序
注册账号:一个账号只能绑定一个小程序
小程序后台
创建小程序开发环境
4、小程序数据绑定语法
基本上与 vue 语法相同,只是名字变了。
1)、语法绑定 - 属性和标签之间
{{}}
2)、条件渲染
wx:if
wx:elif
wx:else
3)、列表渲染
wx:for
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
// 对数组中的下标变量和数组元素变量重命名
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
// key 值
<switch wx:for="{{objectArray}}" wx:key="*this" style="display: block;"> {{item.id}} </switch>
wxss 文件
1、文件后缀
.wxss
2、全局 css
根目录下的 app.wxss
3、与 css 的区别
wxss 具有大部分的 css 特性,但是也做一些修改和扩展
支持样式导入,
@import ‘xx.wxss’;
仅支持部分 css 选择器(class、id、element、分组选择器、before、after)
在 wxss 中不能使用本地图片(即使用网络图)
新增加一个单位
rpx
默认情况下屏幕总宽度为
750rpx
,即按照iphone6
手机大小设计。
app.js
1、理解
小程序的入口文件
2、作用
- 可以设置全局数据
- 可以挂载全局方法
- 应用生命周期
3、应用级生命周期
打开小程序后会自动触发的一系列函数。
// 小程序初始化完成,全局触发1次
onLaunch(){}
// 小程序启动或者从后台进入前台就会触发
onShow(){}
// 小程序退到后台
onHide(){}
// 小程序发生脚本错误时会调用
onError(){}
// 打开不存在页面
onPageNotFound(){}
4、APP 函数
该文件必须调用 App(options)
。
所有的生命周期都是挂载在 options
对象中,除此之外,可以在该对象中挂载任意其他方法或者性能。
一般情况下全局数据挂载到 globalData
属性中。
5、获取 App 对象
其他任意页面调用以下方法,可以获取 app 对象,然后访问 app.js 中的方法和数据。
const app = getApp()
app.json
1、理解
小程序的全局设置、包括小程序的应用名字、外观、页面组成、底部导航、分包处理。
2、pages 字段
所有小程序的页面必须在这里注册。
一个个去新建
右击新建文件夹 - 新建 Page
在
app.js
中的pages
添加"pages/me/me"
js"pages":[ "pages/index/index", "pages/logs/logs", "pages/me/me" ]
3、window
小程序窗口表现设置。
"window":{
"backgroundTextStyle": "light", // 下拉 loading 的样式,仅支持 dark / light
"navigationBarBackgroundColor": "#e9d7df", // 导航栏背景颜色
"navigationBarTitleText": "呆呆小程序", // 导航栏标题文字内容
"navigationBarTextStyle":"black", // 导航栏标题文字内容
"navigationStyle": "custom", // 导航栏样式,default:默认样式,custom:自定义导航栏
"enablePullDownRefresh": true // 是否开启全局的下拉刷新
}
4、tabBar
底部导航设置。
"tabBar": {
"color": "#000",
"selectedColor": "#ff0000",
"list": [
{
"pagePath": "pages/index/index", // 页面路径
"text": "首页", // tab 上按钮文字
"iconPath": "images/tabBar/home.png", // 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片
"selectedIconPath": "images/tabBar/home_checked.png" // 选中时的图片路径
},
{
"pagePath": "pages/car/car",
"text": "购物车",
"iconPath": "images/tabBar/car.png",
"selectedIconPath": "images/tabBar/car_checked.png"
}
]
}
页面
1、page.js
1)、理解
当前页面的逻辑处理。
2)、Page(options)
每个 page.js 必须调用该方法,接受一个对象作为参数,该对象中设置页面数据,页面生命周期,页面的其他方法。
3)、data
页面数据,只提供给当前页面使用。
在页面生命周期和页面方法中通过 this.data
来进行访问。
4)、页面生命周期
在应用生命周期之后,访问每个页面时会触发的一系列方法。
>> 监听页面加载,只执行一次
onLoad() {}
>> 监听页面初次渲染完成
onReady() {}
>> 监听页面显示
onShow() {}
>> 监听页面隐藏
onHide() {}
>> 监听页面卸载
onUnload() {}
5)、页面相关事件处理函数
>> 监听用户下拉动作
onPullDownRefresh() {}
>> 页面上拉触底事件的处理函数
onReachBottom() {}
>> 用户点击右上角分享
onShareAppMessage() {}
2、page.wxss
当前页面的css。
3、page.json
当前页面的配置,该配置可以覆盖全局下window相同字段。
4、page.wxml
用于编写标签结构的页面,但是不支持浏览器的标签的,即 div, p, span 等等不支持的。
用 view
相当于 div,用 text
相当于 span。
// 引入图片
<image src="" mode="aspectFill"></image>
注:图片不能用中文命名,否则手机预览不到
事件绑定
1、事件类型
tap:触摸
longpress:长按
touchstart:手指触摸动作开始
touchmove:手指触摸后移动
touchend:手指触摸动作结束
input 等表单事件
2、添加事件的绑定
以 bind
开头,后面接上事件类型
<button bindtap="foo">添加事件</button>
以 catch
开头,后面跟上事件类型,可以阻止事件冒泡
3、传参
当触发事件处理函数时,如何给该函数传参?
// 定义data-
<button bindtap="add" data-idn="123">参数传递</button>
add(e){
e.target.dataset.idn
}
修改data
1、setData
在小程序中修改数据,必须调用该方法修改。
data: {
username: 'admin',
num: 0,
role: {
name: 'admin',
pages: ['权限']
},
}
this.setData({
num: this.data.num - 1
})
// 修改数组或者对象
this.setData({
role: { // 对象名
...this.role,
name: 'superAdmin'
}
})
// 所以可以直接修改其中一个子字段即可,而不需要重新替换
this.setData({
'role.name': 'superAdmin'
})
this.setData({
'role[0].name': 'superAdmin'
})
2、input 的值的绑定
<input type="text" value="{{username}}" bindinput="changeUsername" />
changeUsername(e) {
// e.detail.value 可以获取绑定的表单元素的值
this.setData({
username: e.detail.value
})
}
// 双向绑定
<input type="text" model:value="{{username}}" />
注意:这种写法只能绑定到单一的字段,不能帮到对象下某一个属性的。
小程序路由
1、组件类型
<navigator url="" open-type="">跳转到新页面</navigator>
open-type:
* navigator:普通页面的跳转,跳转时当前页面不会销毁,页面栈只能存在10层
* redirect:重定向,跳转时,当前页面会被销毁
* switchTab:用于切换 tabBar,会销毁其他页面
* navigateBack:返回
2、路由 API
wx.navigateTo()
wx.redirectTo()
wx.switchTab()
wx.navigateBack()
button 组件
<button bindtap="showloading">加载中</button>
<button open-type="contact">客服</button>
<button open-type="share">转发</button>
<button open-type="feedback">反馈</button>
初始化云开发
第一步、创建云开发的项目
第二步、开通云环境
第三步、代码配置
>> 云函数、小程序代码目录设置
// 在 project.config.json 中配置云函数和小程序代码目录
{
"miniprogram/",
"cloudfunctionRoot": "cloudfunctions/",
}
>> 小程序的 app.js 进行云环境的初始化
wx.cloud.init({
// env: 'cloud1', // 添加当前云开发环境名称
traceUser: true,
});
>> 云函数中也必须进行云初始化
const cloud = require('wx-server-sdk');
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV // 使用当前云环境
});
云函数
1、概念
是指在云端运行的代码,该代码是 nodeJS
的写法。
2、云函数的创建
第一步、确认云函数环境,在云函数目录上点击右键 - 当前环境 - 选择
第二步、在云函数目录上点击右键 - 新建云函数
第三步、将本地的云函数上传至云端 - 右键 - 上传并部署-云端安装依赖
第四步、小程序端就可以调用云函数了。
3、云函数天然鉴权
云函数可以获取每一个用户的识别码。
- openid:当前小程序中用户唯一识别码。
- unionid:将公众号、小程序中同一个微信用户进行识别,只有条件符合后的小程序或者公众号才能获取。
const wxContext = cloud.getWXContext();
4、小程序调用云函数(类似请求)
// 写法1 - 回调:
wx.cloud.callFunction() {
name: '云函数名字',
data: { // 传递给云函数的参数
msg: 'Hi'
},
success(res) {}, // 成功
fail(err) {}, // 失败
complete() {} // 无论成功与否
}
// 写法2 - promise:
wx.cloud.callFunction() {
name: '云函数名字',
data: { // 传递给云函数的参数
msg: 'Hi'
},
}
.then()
.catch()
5、如何在云函数中处理多个小程序发送的请求
wx.cloud.callFunction({
name: '云函数名字',
data: { // 传递给云函数的参数
type: '', // 标识
msg: 'Hi'
}
})
云数据库
1、概念
在云端的一个非关系型数据库。
2、数据库类型
关系型数据库
mysql
非关系型数据库
redis、mongodb 等(云数据库基于mongodb封装,类似 JSON 结构)。
3、云数据库结构
- 数据库 - database
- 集合 - collection(可以与 table 作比较)
- 记录 record / doc
- 字段 field
4、数据库数据类型
JS 数据类型(string、number、boolean、null、array、object、date)、geopoint
5、数据创建
直接单条数据创建
导入数据(json 文件)
JSON 数据,每条数据之间不需要逗号隔开
模板插入
由代码生成
6、云数据库环境的初始化
const cloud = require('wx-server-sdk');
cloud.init()
const db = cloud.database();
7、数据库的操作
>> 云函数端
db.collection(集合名)
>> 小程序端(允许小程序直接操作数据库)
const db = wx.cloud.database();
db.collection(集合名)
*注意:
小程序端直接新增数据,会自动加上 openid,而云函数没有。
8、云数据库语法
1)、增
db.collection(集合名).add({
data: {},
success(){},
fail() {}
})
db.collection(集合名).add({
data: {}
})
.then()
.catch()
2)、删
db.collection(集合名).doc(_id).remove()
3)、改
db.collection(集合名).doc(_id).update({
data: {
// 要修改的字段
}
})
4)、查
// 小程序端直接查询最多返回20条数据,云函数最多返回100条数据。
// 基本语法
db.collection(集合名).get()
// 根据条件进行查询
db.collection(集合名).where({
// 字段名
}).get()
// 投影字段
db.collection('w304_users')
.where({
//...
})
.field({
// 默认返回 _id
username: true, // 为true该字段就会返回
// pass: true,
})
.get()
// 其他 - 排序、跳过、限制
db.collection('w304_users')
.where({
// 字段名
})
.field({
name: true,
price: true,
})
.orderBy('price', 'desc')
.skip(1)
.limit(10)
.get()
小程序 - this 问题
Page({
saiHi() {
wx.showToast({
title: '',
success() {
// 回调函数:不可以正常使用 this
that.setData({})
}
})
// 方法1:
const that = this // 缓存
wx.showToast({
title: '',
success() {
that.setData({})
}
})
// 方法2 - 箭头函数
wx.showToast({
title: '',
success: () => {
this.setData({})
}
})
// 方法3 - 显示绑定
wx.showToast({
title: '',
success() {
that.setData({})
}.bind(this)
})
}
})