开发文档 |
开发者工具 |
前端weui |
我师网源码 |
视频
注册为个人用户,获取AppID(小程序ID,在开发管理的功能中),在“添加开发者”中由管理员将同一小组成员设为开发者。
由一个个组件来构成页面的样式,好比房子的地基、墙体、门、窗等。
常用的组件是 view、 text、 image、 video、 map
输入时:view,然后按 tab, 会智能补全代码。
<text>这是文本</text>
<view> hello world! </view>
<image src="https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg"></image>
<icon class="icon-box-img" type="success" size="93"></icon>
<icon class="icon-box-img" type="warn" size="93" color="#C9C9C9"></icon>
<input class="weui-input" auto-focus placeholder="请输入"/>
页面从产生到销毁的过程,主要是生命周期函数(钩子函数),是自动调用的。
onLoad: 页面加载,一个页面只会调用一次,常用于获取调用的query参数、数据库访问。
eg:
onLoad: function (options) {
console.log(1, "onload, 加载数据")
},
onShow: 页面显示,每次打开页面都会调用一次。
onReady: 页面初次渲染完成,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。详见生命周期
onHide: 页面隐藏,当navigateTo或底部tab切换时调用。
onUnload: 页面卸载,当redirectTo或navigateBack的时候调用。
可以通过 tabBar 配置项切换显示不同的对应页面。
app.json中配置(框架-> 配置),最少两个,最多五个
图片使用png格式,背景透明,81px * 81px
背影色:#f7f7fa,图标色:选中时"#ff6600",没选中时#999999
"tabBar": {
"selectedColor":"#ff6600",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "images/logo2.png",
"selectedIconPath": "images/logo.png"
},
{
"pagePath": "pages/courses/courses",
"text": "课程",
"iconPath": "images/logo2.png",
"selectedIconPath": "images/logo.png"
}] }
在页面中布局可以看成是在一个空间中摆放一个个盒子,每一个元素可以看成是在一个盒子内,层层叠放和层套。
在盒子布局的最外层还有一层“page”,可以对它做一些全局的设局。
page{
background-color: red;
}
盒子外边距是margin, 内边距padding,有四种定义方法(以margin为例,padding类似):
margin: 25rpx; //上下左右边距都是25rpx
margin: 25rpx 15rpx; //上下边距是25rpx, 左右边距是15rpx
margin: 25rpx 15rpx 10rpx 5rpx; //顺时针定义,上边距是25rpx 右边距是15rpx,下边距是10rpx,左边距是5rpx
margin-top: 25rpx; //还有margin-right, margin-bottom, margin-left
display:flex;
flex-direction: row; //水平
justify-content: center; //水平中心对齐
flex-direction: column //竖直
align-items:center; //竖直单行对齐
align-content:center; //竖直多行对齐
margin:0 auto; //子容器在父容器中居中,可用于图片居中
两端对齐
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
小程度开课啦 2021.4.17
《微信小程序开发与设计》已在链课上推出。
链课:https://moochain.net
.news{
font-size: 19px;
border-bottom: 1px solid rgb(36, 28, 28);
/* background-color: red; */
margin: 20rpx 20rpx;
padding-bottom: 5rpx;
}
.news-title{
font-size: 17px;
color: rgb(196, 173, 48);
padding-bottom: 15rpx;
margin-bottom: 15rpx;
border-bottom: 1px solid rgb(133, 131, 131);
}
使用方法一(直接使用样式):
前端样式参考weui |
github
weui.wxss(style中,WeUI v1.1)到项目根目录中(app.wxss同级目录)使用方法二(以组件的形式):
1. app.json中注册
"useExtendedLib": {
"weui": true
},
2. app.wxss引用weui.wxss(全局引用)
/**app.wxss**/
@import "weui.wxss";
3. 当前页面注册(例如test.json)
"usingComponents": {
"mp-dialog": "weui-miniprogram/dialog/dialog",
"mp-cells": "weui-miniprogram/cells/cells",
"mp-cell": "weui-miniprogram/cell/cell",
"mp-badge": "weui-miniprogram/badge/badge"
}
4. 当前页面使用
<mp-cell link>
<view style="display: inline-block; vertical-align: middle">单行列表</view>
<mp-badge content="8" style="margin-left: 5px;"/>
</mp-cell>
weui--wxcss -> example中的组件包,每个文件都包含对应的wxml、wxss和js文件,把它们拷贝到相应的位置。class="page__title title2"WXSS主要控制页面的样式,比如页面的布局,字体大小、颜色、阴影等。
单位:盒子用rpx, 文字用px单位。
字体属性
字体大小:一级标题19px ,二级标题17px。(其中文本15px,可以在app.wxss中统一设置)
font-size: 15px; //字体大小
line-height: 22px; //行间距
color: rgb(66, 66, 66); //字体颜色
font-family: 微软雅黑,宋体; //一般就用默认字体
text-align: center; //文本居中
text-shadow: 2px 2px 5px red; //阴影
图片属性
设计图大小为:750*1334 px(12.7*22.6cm 300dpi)
mode='widthFix' 宽度占满,高度自动变化,保持原图宽高比不变
<image src='' mode='widthFix'></image>
image{
display:flex;
width: 100%;
margin: 0 auto; //盒子居中
}
盒子属性
width: 200rpx;
height: 150rpx;
background-color: aqua; //背景色
border: 1px solid red; //边框, border-bottem
border-radius: 25rpx; //圆角
box-shadow: 2px 2px 5px red; //阴影
margin: 20rpx 20rpx; //外边距
padding-bottom: 5rpx; //内边距
margin: 0 auto; //盒子居中
JavaScript(简称js),是一种动态类型语言,已发展成全栈的语言:既可以做前端,又可以做编程,还可以做服务器。
小程序中js主要起到前端样式、数据绑定以及连接数据库的作用。
//变量,JavaScript 也就是说,变量的类型没有限制,变量可以随时更改类型。
var a = 1 + 3;
let a = 4 //es6 新版写法,语句后可以无分号
const VALUE = 30
//函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。
function print(s) {
console.log(s)
}
//箭头函数,es6 新版写法
let print = (s) => {
console.log(s)
}
eg:
var obj = {
foo: 'Hello',
bar: 'World'
};
var obj = {
p: 123,
m: function () { ... },
}
有三种方法,可以确定一个值到底是什么类型。
typeof运算符
instanceof运算符
Object.prototype.toString方法
this就是属性或方法“当前”所在的对象。
函数都是在某个对象之中运行,this就是函数运行时所在的对象(环境)。
函数f在全局环境执行,this.x指向全局环境的x;在obj环境执行,this.x指向obj.x。
var person = {
name: '张三',
describe: function () {
return '姓名:'+ this.name;
}
};
作用:使后台的数据显示到前端,这也是js的主要功能
数据绑定 ,列表渲染,条件渲染,模板引用
1. 数据绑定
<text>{{message}}</text>
//js 直接赋值
date:{message:“hello world!”}
或者是使用this.setData赋值:从数据库读取然后展示
onLoad: function (options) {
//(onLoad是页面自动加载的,里面的函数会自动调用)
this.setData({
title: 'Set some data for updating view.'
})
//this.data.title = 'Set some data for updating view.'
},
2. 点击事件
<view bindtap="viewTap">点击</view>
//js
Page({
viewTap() {
console.log('view tap')
}
})
3. 列表重复渲染
<block wx:for="{{news}}" wx:for-item="item" wx:key="index">
<view class='news-item'>
<view>{{index}}:{{item.name}}</view>
</view>
</block>
简写:
<view wx:for="{{news}}">
{{ item.name }}
</view>
.js
data:{
news: [
{ name: "商品1" },
{ name: "商品2"}
]
}
eg:
列表重复嵌套渲染(有两层以上循环)
<block wx:for="{{video}}" wx:for-item="item" xw:key="index">
<view class='chaptertitle'>{{item.chapter}}</view>
<view class='video'>
<block wx:for="{{video[index].section}}" wx:for-item="item" xw:key="index">
<view class='chapter'>
{{item.name}}
</view>
</view>
</block>
</view>
</block>
//js
onLoad: function (options) {
let db = wx.cloud.database();
db.collection("course").where({
title: options.title
}).get().then(res => {
console.log(778, res);
this.setData({
course:res.data[0],
video: res.data[0].video
});
console.log(779, res.data[0].video)
})
},
eg1:
<input bindinput="accountInput" placeholder="用户名/邮箱/手机号"/>
//js
accountInput:function(e){
let content = e.detail.value
console.log(content)
},
//数据双向绑定
<input model:value="{{title}}" placeholder="标题"/>
<textarea model:value="{{body}}" placeholder="内容" auto-height/>
eg2:
<input bindblur="pwdBlur" placeholder="请输入密码" password />
//js
pwdBlur:function(e){
let password = e.detail.value
if(password != ''){
this.setData({password:password})
}
}
第一种方法
<navigator url="../detail/detail">跳转页面</navigator>
//注意:不能跳转到tabBar索引的页面
//路径的另一种写法:url="/pages/detail/detail"
// ./ 表示当前目录 ../ 表示上一级目录 / 表示根目录
第二种方法
使用点击事件,bindtap会出现冒泡,用catchtap可阻止冒泡事件
<view bindtap="clickA">点击</view>
//js
Page({
clickA: function() {
wx.navigateTo({//跳转到普通页面,父页面隐藏
url: '../detail/detail'
})
},
wx.redirectTo({
url: '../detail/detail' ////跳转到普通页面,父页面关闭
})
clickA: function () {
wx.switchTab({ //跳转到tab页面
url: '../reader/reader'
})
},
})
如果要传递参数,比如id
<navigator url="../courses-detail/courses-detail?id=1">
<view class='course-title'>photoshop研习社</view>
</navigator>
在对应的页面(courses-detail)js中接受在onLoad 的options中:
onLoad: function (options) {
this.setData({
id:options['id'] //或者option.id
})
},
也可以使用点击函数传递参数(id)
<view bindtap='changePost' data-id='2'>这一篇</view>
//js
changePost: function (event) {
var id = event.currentTarget.dataset.id;
wx.navigateTo({
url: '../detail/detail?id=' + id
});
console.log(666, event.currentTarget.dataset.id)
},
代码复用率较高的部分可以制成模板,重复使用。
1、创建文件夹(template),创建文件course_template.wxml,将重复的代码拷贝过去。
<template name="course">
<view class='course-item'>
<view class='course-text'>
<view class='course-title'>{{title}}</view>
<view>老师:{{teacher}}</view>
</view>
</view>
</template>
2、在需要使用的地方引用即可。需要注意的是数据的传递(item)。
<import src='../../template/course_template.wxml'/>
<block wx:for="{{courses}}" wx:for-item="item" xw:key="index">
<template is="course" data="{{...item}}" />
</block>
云开发提供了一个 JSON 数据库(类似MongoDB)。数据库中的每条记录都是一个 JSON 格式的对象。一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。
云开发数据库提供以下几种数据类型:
String:字符串
Number:数字
Object:对象
Array:数组
Bool:布尔值
Date:时间
Geo:多种地理位置类型,详见下
Null
1. app.js中初始化
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
env: 'cloud1-1gtoo4qib16a1e69',
traceUser: true,
})
2. 手动创建集合collection: "test1"
3. 增加数据 Promise 风格
let db = wx.cloud.database();
db.collection('test1').add({
// data 字段表示需新增的 JSON 数据
data: {
title:"小程序开课啦",
time:"2021.3.12",
section1:"微信小程序开发与设计已在链课上推出。",
section2:" 链课: https://moochain.net",
id:"008"
}
})
.then(res => {
console.log(123, res)
})
//回调的写法
addData(){
let db = wx.cloud.database();
db.collection('test1').add({
data:{
name: "c#",
time: "2019",
long: "325648"
},success(res){console.log(111,res);},
fail(err){console.log(222,err);},
complete(res){console.log(333,res);}
});
},
//async-await写法 推荐写法
addData: async function(){
let db = wx.cloud.database()
let res = await db.collection('test1').add({
data: {
title:"小程序开课啦",
time:"2021.3.12",
section1:"微信小程序开发与设计已在链课上推出。",
section2:" 链课: https://moochain.net",
id:"008"
}
})
console.log(567, res)
},
getData: async function(){
let db = wx.cloud.database()
let res = await db.collection("test1").get() //整个集合
console.log(68, res)
},
//查询数据 where( ) 获取一条数据,赋值如: title:res.data[0].title
let res = await db.collection("test1").where({title:"不错不错"}).get()
db.collection("course").where({age:_.gt(30)}).get()
查询数据排序
orderBy('id', 'asc') 升序排列
orderBy('id', 'desc') 降序排列
查询数据限制 limit()
let res = await db.collection("test1").limit(2).get() //只查前2条数据
let db = wx.cloud.database()
let res = await db.collection('test1').doc('b00064a760a4741a189326627972808d').update({
// data 传入需要局部更新的数据
data: {
// 表示更新title字段
title: "我无怨无悔"
}
})
console.log(633, res)
let db = wx.cloud.database()
let res = await db.collection('test1').doc('b00064a760a4741a189326627972808d').remove()
console.log(633, res)
//删除多条
db.collection('todos').where({
done: true
}).remove()
如果可能会有错误发生,可以使用try... catch来捕捉错误
try{
let res = await db.collection('test1').doc('b00064a760a4741a189326627972808d').remove()
console.log(6233, res)
}catch(e){
console.error(11, e)
}
云存储提供高可用、高稳定、强安全的云端存储服务,支持任意数量和形式的非结构化数据存储,如视频和图片,并在控制台进行可视化管理。
//上传图片
uploadImage: async function(){
//第一步,选择图片
let res = await wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera']
})
console.log(11, res)
//第二步,上传到云端
let res2 = await wx.cloud.uploadFile({
filePath: res.tempFilePaths[0], // 小程序临时文件路径
cloudPath:'images/'+new Date().getTime()
// 上传至云端的路径
//new Date().getTime() 获取当前时间戳
})
console.log(22, res2)
//第三步,展示在前端
this.setData({
imgURL:res2.fileID
})
}
//展示 ,注意此处的rich-text是原生组件,不用导入包。
<rich-text nodes="{{content}}"></rich-text>
abstractFn(res){
if(!res){
return ''
}else{
let str=res.replace(/(\*\*|__)(.*?)(\*\*|__)/g,'') //全局匹配内粗体
.replace(/\!\[[\s\S]*?\]\([\s\S]*?\)/g,'') //全局匹配图片
.replace(/\([\s\S]*?\)/g,'') //全局匹配连接
.replace(//g,'') //全局匹配内html标签
.replace(/(\*)(.*?)(\*)/g,'') //全局匹配内联代码块
.replace(/`{1,2}[^`](.*?)`{1,2}/g,'') //全局匹配内联代码块
.replace(/```([\s\S]*?)```[\s]*/g,'') //全局匹配代码块
.replace(/\~\~(.*?)\~\~/g,'') //全局匹配删除线
.replace(/[\s]*[-\*\+]+(.*)/g,'') //全局匹配无序列表
.replace(/[\s]*[0-9]+\.(.*)/g,'') //全局匹配有序列表
.replace(/(#+)(.*)/g,'') //全局匹配标题
.replace(/(>+)(.*)/g,'') //全局匹配摘要
.replace(/\r\n/g,"") //全局匹配换行
.replace(/\n/g,"") //全局匹配换行
.replace(/\s/g,"") //全局匹配空字符;
return str.slice(0,180)
}
}
rich-text中的图片中没有属性的,在显示时会变得很大,超出显示的范围。需要使用正则对其更改。
res.data[0].content = res.data[0].content.replace(/\<img/gi, '<img style="width:100%;height:auto" ')
将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
wx.setStorage({
key:"key",
data:"value"
})
try {
wx.setStorageSync('key', 'value')
} catch (e) { }
wx.getStorage({
key: 'key',
success (res) {
console.log(res.data)
}
})