赞
踩
小程序可以视为只能用微信打开和浏览的网站,小程序页面本质上就是网页
项目体积不能超过20MB
微信 App 的功能(比如拍照、扫描、支付等等),小程序大部分都能使用
<view>
标签表示一个区块,用于跟其他区块分隔, 类似 HTML的
标签
<text>
表示一段行内文本,类似于 HTML的标签
{
"pages": [
"pages/home/home"
],
"window": {
"navigationBarBackgroundColor": "#ff0000", //导航栏的颜色,默认黑色
"navigationBarTextStyle": "white", //导航栏的文字颜色,只支持黑白,默认白
"navigationBarTitleText": "小程序 Demo" //导航栏的文字,默认为空
}
}
全局样式文件:顶层的app.wxss文件,里面采用 CSS 语法设置页面样式
局部样式文件:每个page对应一个单独的wxss文件
推荐布局方式:Flex
推荐长度单位:rpx【小程序自创响应式单位,任何设备宽度都是750rpx】
推荐的UI框架:WeUI【官方封装的UI框架】https://weui.io/
源码:https://github.com/Tencent/weui-wxss/
在dist/style/weui.wxss文件,将源码全部复制到你的app.wxss文件的头部
<view>
<button class="weui-btn weui-btn_primary">
主操作
</button>
<button class="weui-btn weui-btn_primary weui-btn_loading">
<i class="weui-loading"></i>正在加载
</button>
<button class="weui-btn weui-btn_primary weui-btn_disabled">
禁止点击
</button>
</view>
<image src="https://picsum.photos/200"></image>
<swiper
indicator-dots="{{true}}" 是否显示轮播点
autoplay="{{true}}" 是否自动播放
style="width: 750rpx;">
<swiper-item>
<image src="https://picsum.photos/200"></image>
</swiper-item>
<swiper-item>
<image src="https://picsum.photos/250"></image>
</swiper-item>
<swiper-item>
<image src="https://picsum.photos/300"></image>
</swiper-item>
</swiper>
小程序的数据绑定类似VUE,也遵循MVVM设计模式,文本框直接用{{}}
在JS中定义数据
Page({
data: {
name: '张三'
}
});
在WXML中使用数据
<view>
<input value='{{name}}'/>
<text> {{name}}</text>
</view>
Page({
data: {
items: ['事项 A', '事项 B', '事项 C']
}
});
<view>
<text class="title" wx:for="{{items}}">
{{index}}、 {{item}}
</text>
</view>
<view>
<input model:value='{{name}}'/>
</view>
在根路径下的app.js中的gloablData对象里配置全局共享数据
App({
globalData: {
userInfo: {
name:'小王'
}
}
})
在任意一个页面中获取共享数据
Page({
data: {
name: getApp().globalData.userInfo.name
}
});
tap:触摸后马上离开。
longpress:触摸后,超过 350ms 再离开。如果指定了该事件的回调函数并触发了该事件,tap事件将不被触发。
touchstart:触摸开始。
touchmove:触摸后移动。
touchcancel:触摸动作被打断,如来电提醒,弹窗等。
touchend:触摸结束。
同一个事件在同一个元素上面其实会触发两次:捕获阶段一次,冒泡阶段一次
capture-bind:捕获阶段触发。
capture-catch:捕获阶段触发,不再向下传播,并取消随后的冒泡阶段。
bind:冒泡阶段触发。
catch:冒泡阶段触发,并取消事件进一步向上冒泡
通常使用的是:bind+tap的组合
<button bindtap="buttonHandler">点击</button>
buttonHandler(){
this.data.name; //获取name属性
this.setData({
name:'xxx' //更新name属性
})
}
跳转到应用内非 tabBar 的页面路径,保留历史记录(navigate:导航)
wx.navigateTo({
url: '/second/second?key1=value1&key2=value2'
});
返回上一页面或多级页面
wx.navigateBack({
delta: 2
})
跳转到 tabBar 页面(在tabBar配置的页面,要用switchTab跳转)(switch:开关)
wx.switchTab({
url: '/index'
})
跳转到应用内非 tabBar 的页面路径,不保留历史记录(redirect:重定向)
wx.redirectTo({
url: 'test?id=1'
})
接收参数:(load:载入)
onLoad(options) {
console.log('参数:',options);
}
choose:选择 source:从某地获得 type:类型
chooseAvatar() { var abc = this; wx.chooseImage({ count: 1, //最多选择几张照片 sizeType: ['compressed', 'original'], // compressed:压缩 original:原始 sourceType: ['album', 'camera'], // album:相册 camera:相机 success(res) { // 获得图片临时路径 console.log(res.tempFilePaths[0]); getApp().globalData.userInfo.avatar = res.tempFilePaths[0] abc.setData({ avatar: res.tempFilePaths[0] }) } }) },
wx.showToast({
title: '操作完成',
duration: 700
});
const that = this;
wx.showModal({
title: '操作确认',
content: '你确认要修改吗?',
success (res) {
if (res.confirm) {
wx.showToast({
title: '操作完成',
duration: 700
});
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
同步:
wx.setStorageSync(key,value)
wx.getStorageSync(key)
异步:
wx.setStorage({ key:"key", data:"value"})
wx.getStorage({ key: 'key',success (res) {
console.log(res.data)
}
})
<button bindtap='getUserProfile'>获取头像昵称</button>
getUserProfile(e){
getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success(res){
console.log(res) // 拿到用户信息
}
})
}
onLaunch() | 小程序启动(执行一次)(Launch:启动) |
---|---|
onShow() | 小程序显示(show:显示) |
onHide() | 小程序隐藏(hide:隐藏) |
onError() | 小程序报错(error:错误) |
onLoad() | 加载完成(执行一次)(负责接收页面参数)(load:加载) |
---|---|
onShow() | 当前页面显示(show:显示) |
onHide() | 当前页面隐藏(hide:显示) |
onReady() | 渲染完成(类似vue的mounted)(ready:准备改了) |
onUnlode() | 当前页面卸载(unload:卸载) |
{
"usingComponents": {
"shop-list":"/pages/shopList/shopList"
}
}
<shop-list></shop-list>
默认情况下,自定义组件的样式只受到自定义组件 wxss 的影响。除非以下两种情况:
app.wxss
或页面的 wxss
中使用了标签名选择器(或一些其他特殊选择器)来直接指定样式,这些选择器会影响到页面和全部组件。通常情况下这是不推荐的做法。styleIsolation
。Component({
options: {
styleIsolation: 'isolated'
}
})
styleIsolation
选项从基础库版本 2.6.5 开始支持。它支持以下取值:
isolated
表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);apply-shared
表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;shared
表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared
或 shared
的自定义组件。(这个选项在插件中不可用。)使用后两者时,请务必注意组件间样式的相互影响。
如果这个 Component 构造器用于构造页面 ,则默认值为 shared
,且还有以下几个额外的样式隔离选项可用:
page-isolated
表示在这个页面禁用 app.wxss ,同时,页面的 wxss 不会影响到其他自定义组件;page-apply-shared
表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式不会影响到其他自定义组件,但设为 shared
的自定义组件会影响到页面;page-shared
表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式会影响到其他设为 apply-shared
或 shared
的自定义组件,也会受到设为 shared
的自定义组件的影响。从小程序基础库版本 2.10.1 开始,也可以在页面或自定义组件的 json 文件中配置 styleIsolation
(这样就不需在 js 文件的 options
中再配置)。例如:
{
"styleIsolation": "isolated"
}
此外,小程序基础库版本 2.2.3 以上支持 addGlobalClass
选项,即在 Component
的 options
中设置 addGlobalClass: true
。 这个选项等价于设置 styleIsolation: apply-shared
,但设置了 styleIsolation
选项后这个选项会失效。
代码示例:
/* 组件 custom-component.js */
Component({
options: {
addGlobalClass: true,
}
})
<!-- 组件 custom-component.wxml -->
<text class="red-text">这段文本的颜色由 `app.wxss` 和页面 `wxss` 中的样式定义来决定</text>
/* app.wxss */
.red-text {
color: red;
}
父组件:
<goos-list list="{{xq}}"></goos-list>
父组件:
{
"usingComponents": {
"goos-list": "/pages/goosList/goosList"
}
}
父组件:
xq:[······]
子组件:
<!-- 代码块 -->
子组件:
proprties:{
list:{
type:Array,
value:[]
}
}
父组件:
<goos-list bindClick='play'></goos-list>
父组件:
{
"usingComponents": {
"goos-list": "/pages/goosList/goosList"
}
}
父组件:
play(value){
console.log('子传父:' + value) // value为子组件传回的值
}
子组件:
<image src='' bindtap='play_son'></image>
子组件:
play_son(){
this.triggerEvent('bindClick')
}
created
created(){
//组件实例刚刚被创建好时(此时还不能调用 setData)
}
attached
attached(){
//组件完全初始化完毕(绝大多数初始化工作在此执行)
}
detached
detached(){
//组件实例被从页面节点树移除时
}
云开发代替了传统的后台服务,前端人员容易上手
AppID不能使用测试号
开通云开发服务,获取环境名称和环境 ID
给cloudfunctions 文件夹名设置当前的环境名称
指定小程序的云开发环境:miniprogram 里的 app.js
wx.cloud.init({ // 此处请填入环境 ID, 环境 ID 可打开云控制台查看(云开发=> 设置 => 环境ID) env: 'my-env-id', // traceUser: true, }) --------------------------------------- //app.js文件 App({ onLaunch: function () { if (!wx.cloud) { console.error('请使用 2.2.3 或以上的基础库以使用云能力') } else { console.log('--wx.cloud.init--') wx.cloud.init({ env: 'cloud1-8ghbh19oafb43f5c', traceUser: true, }) } this.globalData = {} } })
鼠标放在cloudfunctions文件夹上右键点击:新建Node.js云函数 例如:login
打开index.js文件会看到默认生成的代码,它会直接获取当前上下文,并返回我们所需的openid和一些其他信息
右键login文件夹->在内建终端打开
安装依赖:npm install
右键login文件夹->开启云函数本地调试
// 后端的index.js文件 // 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext() // evevt为返回值(使用他进行计算等操作) return { event, openid: wxContext.OPENID, appid: wxContext.APPID, unionid: wxContext.UNIONID, } }
在调试面板最右侧请求方式:手动触发
点击绿色按钮:调用
点击Console查看结果
如果云函数调试成功,说明代码没有问题,点击login右键->上传并部署所有文件,这样做了才能在小程序端调用到
在miniprogram中任意创建一个页面,例如:main
在main/main.js中的onLoad事件中获取环境ID,保存到data中,可以从envList.js文件中得到
用下面的代码调用云函数
wx.cloud.callFunction({ name: 'login',//云函数名称 config: { env: 'xx' //环境ID }, data: {'自己的XX参数'} }) —————————————————————————————————————— const {envList} = require('../../envList') wx.cloud.callFunction({ name:'login', //调用的云函数名称 config:{ env:envList[0].envId }, data:{} }).then(res=>{ console.log(res) })
使用wx.chooseImage获取手机图片
使用wx.cloud.uploadFile将文件上传到云存储中
在云开发面板->云存储可以看到上传的文件信息
代码实例:
wx.chooseImage({count: 1,//选择图片最大数量 sizeType:['compressed','original'],//图片质量 sourceType: ['album', 'camera'],//图片来源(相册,相机) success (res) { //拿到照片 const filePath = res.tempFilePaths[0] var pointIndex = filePath.lastIndexOf('.') var extname = filePath.substring(pointIndex);//图片后缀名 //更名 const cloudPath = Date.now() + extname;//利用云存储将照片保存到云端 wx.cloud.uploadFile({ filePath, cloudPath, success:function(res){ //将云端的图片路径赋值给当前页面的头像 that.setData({ avatar:res.fileID }) } }) } }) --------------------------------------------------------------------- wx.chooseImage({ count: 1,//选择图片最大数量 sizeType:['compressed','original'],//图片质量 sourceType: ['album', 'camera'],//图片来源(相册,相机) success (res) { //拿到照片 const filePath = res.tempFilePaths[0] var pointIndex = filePath.lastIndexOf('.') var extname = filePath.substring(pointIndex);//图片后缀名 //更名 const cloudPath = Date.now() + extname; //利用云存储将照片保存到云端 wx.cloud.uploadFile({ filePath, cloudPath, success:function(res){ //将云端的图片路径赋值给当前页面的头像 that.setData({ avatar:res.fileID }) } }) } })
在菜单“云开发”中找到:数据库->新建一个集合->存几条数据
新建一个云函数
// 云函数入口文件 const cloud = require('wx-server-sdk')//配置环境 IDcloud.init({env:cloud.DYNAMIC_CURRENT_ENV})//获取数据库实例 let db = cloud.database()// 云函数入口函数 exports.main = async (event, context) => { //数据查询 return await db.collection('zhihu_daily').get() } ------------------------------------------------------------ // 云函数入口文件 const cloud = require('wx-server-sdk') //配置环境ID cloud.init({ env:cloud.DYNAMIC_CURRENT_ENV }) //获取数据库实例 let db = cloud.database() // 云函数入口函数 exports.main = async (event, context) => { //数据查询(上面的是main.js自动生成的) return await db.collection('my_SQL').doc(event.id).remove() }
安装依赖+本地调试+上传
在本地页面调用该云函数,获得结果
wx.cloud.callFunction({ name:'zhihu_daily', config:{ env:envList[0].envId }, data:{} }).then(res=>{ console.log(res.result.data) }) ------------------------------------------------------------ //调用云函数查询数据 wx.cloud.callFunction({ name:'zhihu_daily', config:{ env:envList[0].envId }, data:{} }).then(res=>{ console.log(res.result.data) that.setData({ items:res.result.data }) })
// 后端main.js文件 // 云函数入口文件 const cloud = require('wx-server-sdk') // 配置环境ID cloud.init({ env:cloud.DYNAMIC_CURRENT_ENV }) // 获得数据库实例 let db = cloud.database() // 云函数入口函数 exports.main = async (event, context) => { return await db.collection('my_SQL').get() } ---------------------------------------------------------- 前端:.js文件 // 删除 async rem(event){ // 通过data-id的方式获得对应数据库的id号 console.log(event.target.dataset.id); let id = event.target.dataset.id await wx.cloud.callFunction({ name:'my_SQL', config:{ env:envList[0].envId, }, data:{ id } }) }, ---------------------------------------------------------- // 后端另一个执行删除操作的云函数的main.js的文件 // 云函数入口函数 exports.main = async (event, context) => { return await db.collection('数据库名').doc(event.id).remove() }
删除:db.collection(‘表名’).doc(‘_id值’).remove()
删除必须要有条件,doc()里面传入数据的id可以查出一条唯一数据来
更新:db.collection(‘表名’).doc(‘_id值’).update({data:{更新条件}})
添加:db.collection(‘表名’).add({JSON形式的数据字段})
查询条数:db.collection(‘表名’).count()
条件查询:db.collection(‘表名’).where({查询条件}).get()
分页查询:db.collection(‘表名’).skip(跳过数量).limit(条数).get()
单条查询:db.collection(‘表名’).doc(id值).get()
一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序。
新建项目->uni-app项目
在manifest.json中配置申请的AppID
静态资源只能存放于static文件夹中,访问时以 / 开头
每个平台有自己的一些特性,因此会存在一些无法跨平台的情况
条件编译写法 | 说明 |
---|---|
#ifdef APP-PLUS(代码)#endif | 只在app中出现的代码 |
#ifndef H5(代码)#endif | 除了H5平台,其他平台均出现的代码 |
#ifdef H5 || MP-WEIXIN(代码)#endif | 只在 H5平台 或 微信小程序 中出现的代码 |
<!-- #ifdef APP-PLUS -->
只在App中可以看到:{{title}}
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
再在微信小程序在可以看到:{{title}}
<!-- #endif -->
<!-- #ifdef H5 -->
只在H5中可以看到:{{title}}
<!-- #endif -->
写法:
<!-- #ifdef %PLATFORM% -->
平台特有的组件
<!-- #endif -->
/* #ifdef %PLATFORM% */
平台特有样式
/* #endif */
// #ifdef %PLATFORM%
平台特有的API实现
// #endif
基本流程和微信一样
获取code
const [loginErr, loginRes] = await uni.login({
provider: 'weixin'
})
//获取微信code,传递后端
loginRes.code
-------------------------------------------------------------------
uni.login({
provider:'微信'
}).then(res=>{
console.log(res)
})
结果:
(2) [null, {…}]
0: null
1: {errMsg: "login:ok", code: "07180oFa1b6e3C021nHa1X8Z0p080oF4"} // 拿到code
length: 2
nv_length: 2
__proto__: Array(0)
拿到code传递后后端,后端根据code+app id + app Secret 请求微信服务器,获取open id
// 获取用户信息
uni.getUserProfile({
desc:'微信',
success: (res) => {
this.aaa= res.userInfo.nickName // userInfo:用户信息
console.log(res)
}
})
onLauch(){
//当uni-app初始化完成时触发(全局触发一次)
}
onShow(){
//当uni-app启动,或从后台进入前台显示
}
onHide(){
//当uni-app从前台进入后台
}
onError(){
//当uni-app报错时触发
}
onLoad(option){ //页面加载完成事件,并且可以从option接收参数 } onShow(){ //监听页面显示,每次出现当前页面时都触发 } onReady(){ //监听页面初次渲染完成 } onHide(){ //监听页面隐藏 } onUnload(){ //监听页面卸载 }
uni-app内置了vuex,只需创建store/index.js,并且引入即可
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {},
mutations: {},
actions: {}
})
export default store
//main.js
import Vue from 'vue'
import store from './store'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
store,
...App
}).$mount()
和小程序的语法基本一致
uni.request({
url: 'https://www.example.com/request',
data: {
text: 'uni.request'
},
method:'GET',
header: {
'custom-header': 'hello'
},
success: (res) => {
console.log(res.data);
},
fail:(err) => {}
});
manifest.json的源码视图
"h5" : {
"devServer" : {
"port" : 8080,
"disableHostCheck" : true,
"proxy" : {
"/" : {
"target" : "http://192.168.0.101:8081/",
"changeOrigin" : true,
"secure" : false
}
}
}
}
<map style="width: 500px; height: 300px;" :markers="markers"
:latitude="latitude" :longitude="longitude">
</map>
data(){
return {
title: 'map',
latitude: 39.909,//纬度
longitude: 116.39742,//经度
markers:[{id:1,latitude:xxx,longitude:xxx,iconPath:’xx.jpg’,width:20,height:20}]//在地图上的坐标点
}
}
uni.getLocation({
type: 'gcj02', //wgs84 gps 坐标;gcj02 返回国测局坐标
success: function (res) {
console.log('当前位置的经度:' , res.longitude);
console.log('当前位置的纬度:' , res.latitude);
console.log('详细的地址信息:' , res.address);//仅app支持
}
});
uniapp内置的getLocation函数,仅在APP端可以获取中文位置信息?
如果希望在小程序端也拿到中文信息,则可以使用腾讯地图API
baidu搜索:腾讯地图开放平台
开发文档:微信小程序JavaScript SDK
申请开发者密钥(创建应用,添加key,填写APPID)
下载微信小程序SDK(拿到js文件,放到项目目录中)
安全域名设置:添加
https://apis.map.qq.com添加为合法域名
代码实现:在当前地区搜索酒店的信息和坐标
import QQMapWX from ‘./qqmap-ws-jssdk.min.js’
onLoad(){
//实例化
this.qqmapwx = new QQMapWX({
key:’申请的地图KEY’
})
this.qqmapwx.search({
keyword:’酒店’,
success:function(res){}
})
}
uni.navigateToMiniProgram(OBJECT)
uni.navigateToMiniProgram({
appId: '',
path: 'pages/index/index?id=123',
extraData: {
'data1': 'test'
},
success(res) {
// 打开成功
}
})
只有当另一个小程序跳转到当前小程序时才会能调用成功。
uni.navigateBackMiniProgram(OBJECT)
uni.navigateBackMiniProgram({
extraData: {
'data1': 'test'
},
success(res) {
// 返回成功
}
})
uni.checkSession({ success: (res) => { if (res.errMsg == 'checkSession:ok') { console.log(res); console.log('登录暂未过期'); console.log(uni.getStorageSync('openId')); } }, fail: (err) => { console.log(err, '已过期') //过期的话调用接口 uni.showModal({ cancelText: '取消', confirmText: '确定', title: '登录已过期,请重新登录', success: (res) => { if (res.confirm) { uni.showLoading({ mask: true, title: '登录中...' }) uni.login({ provider: 'weixin', success: (res) => { console.log(res); } }) } } }) } })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。