app
和多个描述各自页面的 page
组成目录
pages
:小程序的页面放在该目录,一般一个目录就是一个页面
utils
:放置的是项目模块化的公共代码(模块文件,可以做一些功能模块封装)
common
:公共的样式,
components
:公共的组件
static
:公共的资源,图片,视屏,音频文件
文件
app
和多个描述各自页面的 page
。文件 | 必需 | 作用 |
---|---|---|
app.js | 是 | 小程序逻辑 |
app.json | 是 | 小程序公共配置 |
app.wxss | 否 | 小程序公共样式表 |
文件类型 | 必需 | 作用 |
---|---|---|
js | 是 | 页面逻辑 |
wxml | 是 | 页面结构 |
json | 否 | 页面配置 |
wxss | 否 | 页面样式表 |
在项目目录中,以下文件会经过编译,因此上传之后无法直接访问到:.js、app.json、.wxml、*.wxss(其中 wxml 和 wxss 文件仅针对在 app.json 中配置了的页面)。除此之外,只有后缀名在白名单内的文件可以被上传,不在白名单列表内文件在开发工具能被访问到,但无法被上传。具体白名单列表如下:
"pages": [
"pages/index/index",
"pages/cart/cart",
"pages/my/my",
"pages/cate/cate"
],
"entryPagePath": "pages/index/index",
{
"pages": [
"pages/index/index",
"pages/a/a",
"pages/logs/logs",
"pages/b/b"
],
"window": {
"navigationBarBackgroundColor": "#f00",
"navigationBarTitleText": "我的",
"navigationBarTextStyle": "black",
// 下拉刷新界面的背景颜色,需要开启enablePullDownRefresh,才能看见效果
"backgroundColor": "#ccc",
"enablePullDownRefresh": true,
"backgroundTextStyle": "light",
// 设置导航栏 如果设置custom 设置自定义导航栏 之前做的导航栏样式都不会再有效果
"navigationStyle": "custom"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
"tabBar": {
"color":"#ccc",
"selectedColor": "#f00",
"backgroundColor": "#fff",
"borderStyle": "white",
"position": "top",
"custom": false,
"list": [
{
"pagePath": "pages/index/index",
"text":"首页",
"iconPath": "./images/index.png",
"selectedIconPath": "./images/indexFull.png"
},
{
"pagePath": "pages/car/car",
"text":"购物车",
"iconPath": "./images/cart.png",
"selectedIconPath": "./images/cartFull.png"
}
,
{
"pagePath": "pages/mine/mine",
"text":"个人中心",
"iconPath": "./images/my.png",
"selectedIconPath": "./images/myFull.png"
}
]
},
注意
.json
文件来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.json
的 window
中相同的配置项。页面配置的作用范围只作用于该页面。 "navigationBarBackgroundColor": "#ff0000",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "小u商城",
"backgroundColor": "#00ff00",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": true
sitemap.json
配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中打开小程序的管理后台----页面内容收录
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
rules | Object[] | 是 | 索引规则列表 |
{
"rules": [{
"action": "disallow",
"page":"/pages/cart/cart"
},{
"action": "disallow",
"page":"/pages/my/my"
},{
"action": "allow",
"page":"/pages/detail/detail",
"params": ["price","info"],
"matching": "partial"
}]
}
onLaunch: function (option) {
if(option.scene==1035){
console.log("发放优惠券")
}
if(option.scene==1011){
console.log("点餐")
}
},
App
的 onLaunch
和 onShow
,或wx.getLaunchOptionsSync 中获取上述场景值。App({
// 小程序初始化完成走的生命周期
onLaunch(a){
// console.log("onlaunch",a)
// 同步
let b = wx.getLaunchOptionsSync();
console.log(b)
if(b.scene==1011){
console.log("活动详情")
}
},
onShow(e){
console.log("onshow",e)
}
})
对于小游戏,可以在 wx.getLaunchOptionsSync 和 wx.onShow 中获取上述场景值
小程序的配置
JavaScript
引擎为小程序提供开发者 JavaScript
代码的运行环境以及微信小程序的特有功能。App({
/**
\* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {
console.log("app launch")
},
/**
\* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
console.log("app show")
},
/**
\* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
console.log("app hide")
},
/**
\* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息(当小程序有报错信息,无论是页面文件还是全局文件,只要有报错信息,就会触发onerror函数)
*/
onError: function (msg) {
//调用记录日志接口
},
onPageNotFound:function(){
wx.navigateTo({
url: './pages/notfound/notfound',
})
}
})
App({
globalData:{
token:"",
userinfo:""
},
/**
\* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {
this._login()
},
_login:function(){
//判断用户有没有登录过
//如果登录过
//调用登录的接口,返回对应的token
//将token存储到缓存中,再将token放到globalData中,这里globalData就是全局变量
console.log("login ok")
this.globalData.token="abcdefgh124343242"
this.globalData.userInfo={
name:"zhangsan"
}
console.log(this.globalData)
},
/**
\* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
console.log("app show")
},
/**
\* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
console.log("app hide")
},
/**
\* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {
//调用记录日志接口
},
onPageNotFound:function(){
wx.navigateTo({
url: './pages/notfound/notfound',
})
}
})
//app.js
App({
// 小程序启动或者切前台
onShow(){
console.log("onshow")
},
// 小程序初始化完成 全局只触发一次
onLaunch(){
console.log("onlaunch")
console.log(this.userInfo.name)
console.log(this.userInfo.age)
console.log(this.say())
},
// 小程序切后台的时候触发
onHide(){
console.log("onhide")
},
// 当小程序有报错信息,无论是页面文件还是全局文件,只要有报错信息,就会触发onerror函数
onError(err){
console.log("错误信息",err)
},
onPageNotFound(){
console.log("页面不存在")
wx.navigateTo({
url: '/pages/logs/logs',
})
},
// 全局的变量
userInfo:{
name:"张三",
age:20
},
// say(){
// return "正在吃东西"
// }
// 全局的函数
say:function(){
// console.log(this.userInfo,"函数")
// 在函数内部访问全局变量
return this.userInfo.name + "正在吃东西"
}
})
// 获取app实例唯一的方法
let app = getApp();
console.log(app.userInfo.name)
// 注意事项:不要在页面中调用app的生命周期
Page({
})
getApp
方法获取到全局唯一的 App 实例,获取App上的数据或调用自定义函数开发者注册在 App
上的函数。// xxx.js
const appInstance = getApp()
console.log(appInstance.globalData) // I am global data
App()
内的函数中,或调用 App
前调用 getApp()
,使用 this
就可以拿到 app 实例。getApp()
获取实例之后,不要私自调用生命周期函数。js
文件中使用Page构造方法进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。Page({
/**
\* 页面的初始数据
*/
data: {
},
/**
\* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log("index load")
},
/**
\* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
console.log("index ready")
},
/**
\* 生命周期函数--监听页面显示
*/
onShow: function () {
console.log("index show")
},
/**
\* 生命周期函数--监听页面隐藏
*/
onHide: function () {
console.log("index hide")
},
/**
\* 生命周期函数--监听页面卸载
*/
onUnload: function () {
console.log("index unload")
},
/**
\* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
console.log("下拉刷新")
},
/**
\* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
console.log("加载更多")
},
/**
\* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
//修改数据
this.setData({
num:2
})
data: {
name:"zhangsan",
age:"18"
},
/**
\* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this._login()
},
_login:function(){
console.log("login ok")
},
_fn:function(){
this.setData({
age:2
})
},
// pages/demo1/demo1.js
Page({
/**
* 页面的初始数据
*/
data: {
num:1,
},
//页面的下拉刷新,必须先把enablePullDownRef开启才可以出发该事件函数
onPullDownRefresh(){
console.log("demo1的下拉刷新")
this.setData({
num:2
})
console.log(this)
},
//默认是距离底部有50px的时候,触发该函数,如果想改变距离,设置onReachBottomDistance就可以
onReachBottom(){
console.log("demo1的上拉刷新")
},
// 页面滑动事件
onPageScroll(e){
console.log("页面的滚动事件",e)
}
})
{{msg}}
主人下马客在船
{{1+2+num}}
{{1+2+"3"}}
{{1+"2"+3}}
{{ store>=60?"及格":"不及格" }}
{{arr[0]}}
{{arr[1]}}
{{arr[2]}}
{{obj.name}}------{{obj.text}}
{{index}}-------{{item}}
{{index1}}-------{{item1}}
{{index}}
{{index}}-----{{item}}
pages/demo2/demo2.wxml
{{index}}------ {{item}}
{{index}}-----{{item.id}}-----{{item.name}}------{{item.price}}
{{item}}
{{item}}
{{item}}
pages/demo3/demo3.wxml
及格
优秀
中等
不及格
内容
内容一
{{name}}
{{age}}
{{age}}
{{}}
{{age+1}}
{{name+"三"}}
{{arr[0]}}
{{user.height}}
{{user.height}}
data: {
name:"zhangsan",
age:17,
title:"我是标题",
arr:[1,2,3],
user:{
height:180,
weight:"150"
},
goods:[{
id:1,
name:"小米"
},{
id:2,
name:"华为"
}],
string:"abcdefg"
},
--------遍历数组-----------
{{index}}---{{item}}
{{key}}---{{vo}}
--------遍历对象-----------
{{index}}---{{item}}
{{key}}---{{vo}}
--------遍历数组对象-----------
{{index}}---{{item.id}}---{{item.name}}
--------遍历字符串-----------
{{index}}---{{item}}
--------遍历数字-----------
{{index}}---{{item}}
{{item.id}}
{{item.name}}
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
wx:key 的值以两种形式提供
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
成年
成年
未成年
成年
青少年
少年
name="名字"
is="相对应的模板名字"
要在模板中定义
pages/demo4/demo4.wxml
姓名:{{name}}
年龄:{{age}}
include 可以将目标文件除了 外的整个代码引入,相当于是拷贝到 include 位置
import可以在该文件中使用目标文件定义的template
import引的是模板 inclue引入的是普通的组件
设计稿的元素宽度2px/设计稿的宽度750px = 设计布局的宽度2rpx/设备的宽度750rpx
设计稿的元素宽度2px/设计稿的宽度640px = 设计布局的宽度2rpx/设备的宽度750rpx
/* pages/demo6/demo6.wxss */
@import "/common/my.wxss";
.box{
width: 100rpx;
height: 100rpx;
background-color: red;
}
我是页面的头部
我是页面的底部
我是cate
data: {
style:"style1",
temp:{
nav:[{
id:1,
name:"男装"
},{
id:2,
name:"女装"
}],
name:"aaa"
}
},
{{item.name}}
{{name}}
只引入目标文件中的template模板
,其余的一概不引入
template
,在B中可以使用A定义的template
,但是C不能使用A定义的template
。include
可以将目标文件除了
外的整个代码引入,相当于是拷贝到 include
位置
规定屏幕宽为750rpx
。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。@import "../../common/cart.wxss";
nihao
.
,样式类名之间用空格分隔。nihao
bind+事件类型 = "函数名"
或者使用catch+事件类型 = "函数名"
来绑定事件事件1
事件1
箭头函数拿不到this 建议在写事件函数的不要用箭头函数
_fn1:function(){
console.log("我被触发了fn1")
},
_fn2(){
console.log("我被触发了fn2")
},
//将this重新赋值
let money=[10,20,30]
let that=this
let new_money=money.map(function(item){
return item+that.data.add
})
console.log(new_money)
//使用箭头函数
let money=[10,20,30]
let new_money=money.map((item)=>{
return item+this.data.add
})
console.log(new_money)
冒泡事件,非冒泡事件
冒泡事件
submit
事件,input 的input
事件,scroll-view 的scroll
事件
type
:什么事件触发的。touches
:事件发生的位置,detail
:子组件传递过来的数据就放在detail。currentTarget
:事件绑定的元素。target
:事件触发的元素。id
接参 e.target.id
e.currentTaget.id
data-*(自定义的参数名)
接参 e.target.dataset.id
e.currentTarget.dataset.id
//推荐使用的传参方式,参数名称比如data-user-sex====>userSex//传递的参数可以是对象/数组
总结:
开始标签
和 结束标签
,属性
用来修饰这个组件,内容
在两个标签之内。
Content goes here ...
-
连接
文本 内容
文本 内容
文本>内容
{{goods_info}}
nodes 节点列表string/array
string形式
array形式
arr:[
{
// 二级标题数组
// 标签名是节点node 标签内容是text
//节点类型
type:"node",
name:"h2", //标签名
attrs:{class:"box1"}, //标签身上的属性
children:[
{
type:"text",
text:"二级标题数组"
}
]
}
]
我是son
swiper的基础使用
pages/demo04/demo04.wxml
pages/demo05/demo05.wxml
/* pages/demo05/demo05.wxss */
image{
width: 100%;
height: 100%;
}
.banner{
position: relative;
}
.dots{
position: absolute;
left: 0;
bottom: 0;
width: 100%;
text-align: center;
}
.dots text{
width: 40rpx;
height: 20rpx;
display: inline-block;
background: #ccc;
margin-left: 10rpx;
}
.dots .active{
background-color: red;
}
// pages/demo05/demo05.js
Page({
/**
* 页面的初始数据
*/
data: {
arr:[
"/logo/1.jpg",
"/logo/2.jpg",
"/logo/3.jpg",
],
_currentIndex:0,
num:1
},
_change(e){
// console.log(e.detail.current)
// 异步
this.setData({
_currentIndex:e.detail.current,
},function(){
// console.log(this.data.num++)
})
// 如果变量经过赋值改变之后,要渲染在视图层,建议写setdata进行改变值
// 如果变量只在js文件中使用,可以直接进行赋值,不需要再setdata里面改变
console.log( this.data.num++)
}
})
/* pages/swiper/swiper.wxss */
.container{
position: relative;
}
.container .dots{
width: 100%;
position: absolute;
bottom: 20rpx;
text-align: center;
}
.dots text{
display: inline-block;
width:20rpx;
height:8rpx;
margin-left:10rpx;
background-color:#333;
}
text.active{
background-color: blue;
}
.img{
width: 100%;
}
/**
\* 页面的初始数据
*/
data: {
banner:["1.jpg","2.jpg","3.jpg"],
currentIndex:0
},
_changeImg:function(e){
this.setData({
currentIndex:e.detail.current
})
},
pages/demo06/demo06.wxml
{{item.title}}
{{item.title}}
{{item1.text}}
_change(e){
console.log(e.target.dataset.index)
this.setData({
_currentIndex:e.target.dataset.index
})
},
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
分类1
/* pages/scroll/scroll.wxss */
.scroll-x{
white-space: nowrap;
}
.scroll-x view {
display: inline-block;
padding:10rpx;
background-color: #ccc;
margin:0rpx 10rpx;
}
.scroll-y{
height:600rpx;
width:400rpx;
border:1rpx solid #ccc
}
.scroll-y view {
width: 400rpx;
height:270rpx;
background-color: #ccc;
margin-bottom: 10rpx;
}
分类1
分类2
分类3
分类4
分类5
分类6
分类7
分类8
分类1子分类
分类1子分类
分类1子分类
分类1子分类
分类2子分类
分类2子分类
分类2子分类
分类2子分类
分类3子分类
分类3子分类
分类3子分类
分类3子分类
分类4子分类
分类4子分类
分类4子分类
分类4子分类
分类5子分类
分类5子分类
分类5子分类
分类5子分类
分类6子分类
分类6子分类
分类6子分类
分类6子分类
分类7子分类
分类7子分类
分类7子分类
分类7子分类
分类8子分类
分类8子分类
分类8子分类
分类8子分类
data: {
view:"cate1"
},
_scrollview:function(e){
let {cate}=e.currentTarget.dataset
this.setData({
view:cate
})
},
/* pages/scroll-view/scroll-view.wxss */
.container{
display: flex;
height:800rpx;
}
.left{
width:200rpx;
height:800rpx;
}
.left view{
height:120rpx;
line-height: 120rpx;
text-align: center;
margin-bottom:20rpx;
background-color: #ccc;
}
.right{
width:550rpx;
height:800rpx;
}
.right view{
width: 550rpx;
height:400rpx;
background-color: #ccc;
margin-bottom:20rpx;
}
.right view text{
display: inline-block;
padding: 20rpx;
margin:10rpx;
background-color: #fff;
}
注意
radio-group需要和radio组件一起使用
checkbox-group需要和checkbox一起使用
switch组件也有checkbox,值为true和false
怎么区分button中的提交和重置 利用button组件的form-type属性
如何一次获取全部表单数据 button按钮的form-type属性和form组件的bindsubmit事件一起使用,还需要在每个表单组件身上绑定name属性
/* pages/form/form.wxss */
.page{
padding: 10rpx;
}
.page view{
margin:15rpx;
}
.title{
height:80rpx;
line-height: 80rpx;
padding-left: 10rpx;
font-weight: bold;
color:#fff;
background-color: orangered;
}
view label{
font-size: 36rpx;
font-weight: bold;
}
.input{
height:80rpx;
border:1rpx solid #ccc;
margin-top:10rpx;
border-radius: 10rpx;
padding-left: 10rpx;
}
data: {
name:"",
tel:"",
sex:"男",
hobby:[],
agree:false,
score:60,
arr:[{
id:1,
name:"有氧运动"
},{
id:2,
name:"无氧运动"
}],
index:0
},
_submit:function(e){
console.log(e)
},
_inputSport:function(e){
this.setData({
index:e.detail.value
})
},
_inputName:function(e){
this.setData({
name:e.detail.value
})
},
_inputPhone:function(e){
this.setData({
tel:e.detail.value
})
},
_inputSex:function(e){
this.setData({
sex:e.detail.value
})
},
_inputHobby:function(e){
this.setData({
hobby:e.detail.value
})
},
_inputAgree:function(e){
this.setData({
agree:e.detail.value
})
},
_inputScore:function(e){
this.setData({
score:e.detail.value
})
},
pages/demo1/demo1.wxml
跳转到商品详情
跳转cart
跳转列表
返回
_goHome(){
wx.navigateTo({
url: '/pages/homework/homework',
success:(res)=>{
console.log(res)
// 逻辑
},
fail:(err)=>{
console.log(err)
},
// 无论成功或者失败,都会执行的回调函数
complete:(res)=>{
console.log(res)
}
})
},
小米手机
_goDetail:function(){
wx.navigateTo({
url: '../detail/detail?id=2&name=华为&price=80000',
})
},
onLoad: function (options) {
console.log(options)
},
星座和运势
const name='swk'
const say=()=>{
console.log("say")
}
export {
name,
say
}
import {name,say} from '../../utils/tool'
const name='swk'
const say=()=>{
console.log("saying")
}
export default {
name,
say
}
import tool from '../../utils/tool'
console.log(tool.name)
const name='swk'
const say=()=>{
console.log("saying")
}
module.exports={
name,
say
}
const tool=require("../../utils/tool")
console.log(tool.name)
tool.say()
1定义组件
// components/test/test.js
Component({
/**
\* 组件的属性列表,外部传递的值
*/
properties: {
},
/**
\* 组件的初始数据,组件的内部的值
*/
data: {
},
/**
\* 组件的方法列表,组件的方法
*/
methods: {
}
})
{
"component": true, //说明这是一个组件
"usingComponents": {} //注册组件用的
}
全局注册
"usingComponents": {
"my-test":"/components/test/test"
},
局部注册
properties: {
name:{
type:'String',
value:""
},
age:{
type:'Number',
value:18
}
},
我是{{name}}我的年龄:{{age}}
methods: {
_hander:function()
this.triggerEvent("get",{name:"hello"+this.properties.name,age:this.properties.age+1})
}
}
_getUser:function(e){
console.log(e)
},
我是{{name}}我的年龄:{{age}}
我是默认的插槽
Component({
options: {
multipleSlots: true // 在组件定义时的选项中启用多slot支持
},
properties: { /* ... */ },
methods: { /* ... */ }
})
我是{{name}}
我的年龄:{{age}}
我是头部的插槽
我是默认的插槽
我是底部的插槽
Component({
lifetimes: {
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
},
// 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
// ...
})
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/api.html
从接口的风格分成三种类型
我们约定,以 on
开头的 API 用来监听某个事件是否触发,如:wx.onSocketOpen,wx.onCompassChange 等。
这类 API 接受一个回调函数作为参数,当事件触发时会调用这个回调函数,并将相关数据以参数形式传入。
代码示例
wx.onCompassChange(function (res) {
console.log(res.direction)
})
try {
wx.setStorageSync('key', 'value')
} catch (e) {
console.error(e)
}
Object
类型的参数,这个参数都支持按需指定以下字段来接收接口调用结果:参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
其他 | Any | - | 接口定义的其他参数 |
let info=wx.getSystemInfoSync()
console.log(info)
wx.getSystemInfo({
success:res=>{
console.log(res)
},
fail:err=>{
}
})
_show:function(){
wx.showToast({
title: '显示成功',
icon:"none",
duration:5000
})
},
_hide:function(){
wx.hideToast()
},
wx.showLoading({
title:"加载中"
})
wx.hideLoading()
wx.showModal({
title:"系统提示",
content:"请先完善个人信息",
confirmText:"前往",
cancelText:"放弃",
success:res=>{
console.log(res)
}
})
wx.showActionSheet({
alertText:"请选择",
itemList:["订单查询","联系客服","联系商家"],
success:res=>{
if(res.tapIndex==0){
}
if(res.tapIndex==1){
}
}
})
wx.setNavigationBarTitle({
title: '首页',
})
wx.setNavigationBarColor({
backgroundColor: '#00ff00',
frontColor: '#ffffff',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})
wx.showTabBarRedDot({
index: 2,
})
wx.setTabBarBadge({
index: 1,
text: '5',
})
wx.setBackgroundColor({
backgroundColor: '#0000ff',
})
wx.setStorageSync('name', "zhangsan")
wx.setStorageSync('userinfo',{
age:18,
sex:1
})
wx.setStorage({
data:{
id:1,
goods_name:"小米"
},
key: 'goods',
})
wx.clearStorage()
wx.clearStorageSync()
wx.getStorage({
key: 'userinfo',
success:res=>{
console.log(res)
}
})
let goods= wx.getStorageSync('goods')
console.log(goods)
wx.getStorage({
key: 'userinfo',
success:res=>{
console.log(res)
}
})
let goods= wx.getStorageSync('goods')
console.log(goods)
http响应
响应的状态码
响应的内容
_getProduct:function(){
wx.request({
url: 'http://localhost:3000/product',
method:"get",
data:{
id:1,
name:"zhansan"
},
header:{
"content-type":"application/x-www-form-urlencoded",
},
success:res=>{
console.log(res)
},
})
wx.request({
url: 'http://localhost:3000/login',
method:"post",
header:{
"content-type":"application/x-www-form-urlencoded",
},
data:{
tel:"12345",
pwd:"123"
},
success:res=>{
console.log(res)
}
})
},
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。转换规则如下:
对于 GET 方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)
对于 POST 方法且 header[‘content-type’] 为 application/json 的数据,会对数据进行 JSON 序列化
对于 POST 方法且 header[‘content-type’] 为 application/x-www-form-urlencoded 的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)
const baseUrl="http://localhost:3000"
const http=(option)=>{
return new Promise((resolve,reject)=>{
wx.request({
url:baseUrl+option.url,
method:option.method||"get",
data:option.data||{},
header:option.header||{
"content-type":"application/x-www-form-urlencoded",
},
success:resolve,
fail:reject
})
})
}
export {
http
}
https://developers.weixin.qq.com/community/develop/article/doc/000ecc775a86807f7ba9b7dc956c13
随着小程序的普及,微信也有很多内部小程序在开发,每个小程序都需要从零到1进行开发设计,而这个过程中,有大量的UI交互是重复的,另外,微信内部已经有一套H5版本的WeUI样式库。综合考虑,我们基于WeUI样式库开发了小程序版本的UI组件库,在内部多个小程序项目已经使用OK的情况下,我们把这套组件库开源让外部开发者也可以使用,欢迎大家Star以及提Issue。
1使用扩展库的方式(推荐)
"useExtendedLib": {
"weui": true
},
2 使用npm的方式进行构建
@import '/miniprogram_npm/weui-miniprogram/weui-wxss/dist/style/weui.wxss';
订单查询
首页 |返回
data: {
tab:[{
text:"物流查询",
iconPath:"/static/icon/dd.png",
selectedIconPath:"/static/icon/ddFull.png"
},{
text:"物流查询",
iconPath:"/static/icon/dd.png",
selectedIconPath:"/static/icon/ddFull.png",
badge:"3"
},{
text:"物流查询",
iconPath:"/static/icon/dd.png",
selectedIconPath:"/static/icon/ddFull.png",
},{
text:"物流查询",
iconPath:"/static/icon/dd.png",
selectedIconPath:"/static/icon/ddFull.png",
}],
groups:[
{ text: '示例菜单', value: 1 },
{ text: '示例菜单', value: 2 },
{ text: '负向菜单', type: 'warn', value: 3 }
],
show:false
},
_goIndex:function(){
wx.switchTab({
url: '../index/index',
})
},
_switchTab:function(e){
if(e.detail.index==1){
}
},
_showAction:function(){
this.setData({
show:true
})
},
/* pages/order/order.wxss */
.back{
padding: 10rpx;
border:1rpx solid #ccc;
border-radius: 25rpx;
}
image{
width: 40rpx;
height: 40rpx;
}
{
"usingComponents": {
"mp-navigation-bar": "/miniprogram_npm/weui-miniprogram/navigation-bar/navigation-bar",
"mp-icon": "/miniprogram_npm/weui-miniprogram/icon/icon",
"mp-searchbar": "/miniprogram_npm/weui-miniprogram/searchbar/searchbar",
"mp-tabbar": "/miniprogram_npm/weui-miniprogram/tabbar/tabbar",
"mp-cells": "/miniprogram_npm/weui-miniprogram/cells/cells",
"mp-cell": "/miniprogram_npm/weui-miniprogram/cell/cell",
"mp-actionSheet": "/miniprogram_npm/weui-miniprogram/actionsheet/actionsheet"
},
"navigationStyle":"custom"
}
https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html
概念
某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。
在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示。
一个小程序如果使用分包技术,必须有一个主包,至少有一个分包,公共的资源和首页和tabbar必须放在主包
目前小程序分包大小有以下限制:
分包的实现
subpackages
字段声明项目分包结构:"subPackages": [{
"root":"animate",
"pages":[
"pages/cat/cat",
"pages/dog/dog"
]
},{
"root":"firut",
"pages":[
"pages/orange/orange",
"pages/pear/pear"
]
}],
打包原则
声明 subpackages 后,将按 subpackages 配置路径进行打包,subpackages 配置路径外的目录将被打包到 app(主包) 中
app(主包)也可以有自己的 pages(即最外层的 pages 字段)
subpackage 的根目录不能是另外一个 subpackage 内的子目录
tabBar 页面必须在 app(主包)内
引用原则
低版本兼容问题
subpackage
里面的路径放到 pages 中。概述
实现
"subPackages": [{
"root":"animate",
"pages":[
"pages/cat/cat",
"pages/dog/dog"
],
"independent": true
},{
"root":"firut",
"pages":[
"pages/orange/orange",
"pages/pear/pear"
]
}],
限制
app.wxss
对独立分包无效,应避免在独立分包页面中使用 app.wxss
中的样式;App
只能在主包内定义,独立分包中不能定义 App
,会造成无法预期的行为;关于getApp
关系型 | 文档型 |
---|---|
数据库 database | 数据库 database |
表 table | 集合 collection |
行 row | 记录 record / doc |
列 column | 字段 field |
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
env: 'music-dev-wi2lv',
traceUser: true,
})
}
}
1初始化数据库的连接
const db=wx.cloud.database()
增
db.collection("test").add({
data:{
book_name:"西游记",
book_pirce:120,
book_author:"吴承恩",
book_tag:["神话","古装"]
},
success:res=>{
console.log(res)
}
})
db.collection("test").add({
data:{
book_name:"西游记",
book_pirce:1200,
book_author:"吴承恩",
book_tag:["神话","古装"]
}
}).then(res=>{
console.log(res)
})
删
db.collection(表名).where({ 匹配的字段名:字段值 }).remove().then(res=>{ })
_delete:function(){
db.collection("test").where({
book_pirce:1200
}).remove().then(res=>{
console.log(res)
})
},
改
API | 说明 |
---|---|
update | 局部更新一个或多个记录 |
set | 替换更新一个记录 |
db.collection(表名).doc("id值").update/set({data:{要更新的字段名:更新后的字段值}}).then(res=>{ })
db.collection("test")
.doc("21ded5cb5fe59586000dbef439a762df").update({
data:{
"book_name":"大话西游"
}
}).then(res=>{
console.log(res)
})
db.collection("test")
.doc("21ded5cb5fe59586000dbef439a762df").set({
data:{
"book_name":"大话西游"
}
}).then(res=>{
console.log(res)
})
查
//使用doc通过主键查询获取单条数据,doc只能放置主键id
db.collection(“test”)
.doc("023ce9555fe590a6000c372d714bcc02")
.get().then(res=>{
console.log(res)
})
db.collection(“test”)
.where({
book_author:"吴承恩",
book_pirce:120
})
.get().then(res=>{
console.log(res)
})
上传文件
_selectImg:function(){
wx.chooseImage({
count: 9,
success:res=>{
this.setData({
fileList:res.tempFilePaths
})
}
})
},
_upload:function(){
this.data.fileList.forEach((item,index)=>{
let ext=item.split(".").pop()
let file=(new Date).getTime()+index+"."+ext
wx.cloud.uploadFile({
cloudPath:file,
filePath:item
}).then(res=>{
console.log(res)
})
})
},
下载文件
wx.cloud.downloadFile({
fileID:"cloud://music-dev-wi2lv.6d75-music-dev-wi2lv-1302673657/1.jpg"
}).then(res=>{
wx.saveFile({
tempFilePath:res.tempFilePath,
success:res=>{
console.log(res)
wx.showToast({
title: '下载成功',
})
}
})
})
删除文件
_deleteImg:function(){
wx.cloud.deleteFile({
fileList:[" cloud://music-dev-wi2lv.6d75-music-dev-wi2lv-1302673657/1608885426389.jpg","cloud://music-dev-wi2lv.6d75-music-dev-wi2lv-1302673657/1608885426387.jpg"]
}).then(res=>{
console.log(res)
})
},
1定义云函数
const cloud = require('wx-server-sdk')
//初始化云能力
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
let sum=event.a+event.b
return {
sum,
openid: wxContext.OPENID
}
}
2使用云函数
wx.cloud.callFunction({
name:"g_sum",
data:{
a:1003,
b:3849
}
}).then(res=>{
console.log(res)
})
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
const db=cloud.database()
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
let res=await db.collection(event.table).where(event.where).remove()
return {
openid: wxContext.OPENID,
res
}
}
3 软件的开发流程
1 市场调研
2 需求分析
3 概要设计
4 详细设计
5 编码
6 测试
7 上线运维
8 产品运营