微信小程序
APPID
云开发要求必须有appid,在微信小程序的开发设置里面
新建项目
新建文件夹
在app.json
中,写入文件夹名或者文件名,就会自动新建以文件名命名的wxml、wxss、js和json文件
- wxml:相当于html文件
- wxss:相当于css文件
"pages": [
//放在首位的路径就是首页文件
"pages/home/home",//在pages文件夹下的home文件夹下,有home命名的wxml、wxss、js和json文件
"pages/topic/topic",
"pages/category/category",
//通常以components命名的是组件
"components/goodsList/goodsList",
//新建自定义tabBar栏
"custom-tab-bar/index",
],
标签
view
(即:div) 与
text
(即:span)
标签分单双标签,书写格式与html完全一样,但在微信小程序里,没有div、span、p、h1-h6这些标签,它只有非常简单的两个最基本的标签:view(即:div) 与 text(即:span)。当然,还有其他经过封装的组件,我们后面会再做介绍。
block
block
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
tabBar
tabBar:底部的菜单栏,有首页,分类,购物车,我的……(一般为五个)
配置
在 app.json
中,windows
同级的位置,(app.json
是全局配置的文件)写入:
{
"windows": {
...
},
"tabBar": {
"custom": true, //开启自定义tanBar
"color": "#000000",//字体颜色
"selectedColor": "#000000",//选中的字体颜色
"backgroundColor": "#000000",//背景颜色
"list": [{
"pagePath": "pages/home/home",//地址或者路径
"text": "首页",//标题
"iconPath": "images/bar/bar1_1.png" //图标
"selectedIconPath": "images/bar/bar1.png"
},{
"pagePath": "pages/menu/menu",
"text": "菜单",
"iconPath": "images/bar/bar2_2.png",
"selectedIconPath": "images/bar/bar2.png"
},{
"pagePath": "pages/new/new",
"text": "新品",
"iconPath": "images/bar/bar3_3.png",
"selectedIconPath": "images/bar/bar3.png"
},{
"pagePath": "pages/kefu/kefu",
"text": "小二",
"iconPath": "images/bar/bar4_4.png",
"selectedIconPath": "images/bar/bar4.png"
}]
}
}
自定义tabBar
- 在
app.json
中的tabBar
项指定custom
字段,同时其余tabBar
相关配置也补充完整。 - 所有 tab 页的 json 里需声明
usingComponents
项,也可以在app.json
全局开启。
"tabBar": {
"custom": true, //开启自定义tanBar
"color": "#000000",//字体颜色
"selectedColor": "#000000",//选中的字体颜色
"backgroundColor": "#000000",//背景颜色
"list": [{
"pagePath": "pages/home/home",//地址或者路径
"text": "首页",//标题
"iconPath": "images/bar/bar1_1.png" //图标
"selectedIconPath": "images/bar/bar1.png"
}]
添加 tabBar 代码文件
在根目录新建以custom-tab-bar命名的文件夹
custom-tab-bar/index.js
custom-tab-bar/index.json
custom-tab-bar/index.wxml
custom-tab-bar/index.wxss
注意:
在custom-tab-bar/index.js中不能使用Pages({ }) 要使用 Component({ })来存放数据
使用方法需要写在 methods:{ } 里面
数据绑定
.wxml 文件中接收 .js文件的数据 用"胡子语法" {{ }}
//home.wxml
<view>{{msg}}</view>
//home.js
Page({
data: {
msg: '你好,世界'
}
})
页面显示:
你好,世界
this.setData
修改data中的数据,并渲染到页面上 用 this.setData({ })
this.setData({
})
//setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。
//语法:
this.setData(Object data, Function callback)
callback Function 否 setData引起的界面更新渲染完毕后的回调函数
this.setData({ }, ()=>{
})
方法绑定
给标签上绑定一个事件
//在页面中的写法:
<button bindtap="tapFn">按钮</button>
//在js中的写法
Page({
data: {
...
},
tapFn(){
// do something...
}
})
双向数据绑定
///在页面中的写法:
<input value="{{msg}}" bindinput="iptFn"></input>
<view>{{msg}}</view>
//在js中的写法:
Page({
data: {
msg: '你好,世界'
},
// input值被修改时触发的函数
iptFn(e){
//用this.setData()
this.setData({
msg: e.detail.value
})
}
})
列表循环
wx:for='{{}}' wx:key="index或者*this或者是id"
//例子:
//<!-- 方法1 -->
<view class="box">
<view wx:for="{{arr}}" wx:key="*this">{{item}}</view>
</view>
//<!-- 方法2 -->
<view class="box">
<block wx:for="{{arr}}" wx:key="*this">
<view>{{item}}</view>
</block>
</view>
这里要注意几点:
- wx:key可以不写,但不写会报黄色警告;
- 保留关键字
*this
代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字; - 每个循环都会自带
item
与index
,不需要像vue一样写:v-for="(item, index) in arr"
; - 如果出现多层数组的循环,那就会出现item指向不明确,虽然小程序可以帮我们自动识别,但代码可维护性降低,因此,我们可以使用
wx:for-item="items"
来改变item的名称。
条件渲染
wx:if
wx:if="{{}}"
//还有
wx:elif ="{{}}"
wx:else
//例子:
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
hidden
<view hidden="{{ifShow}}">显示或隐藏</view>
两者的区别
wx:if
之中的模板也可能包含数据绑定,所以当 wx:if
的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if
也是惰性的,如果在初始渲染条件为 false
,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
hidden
,组件始终会被渲染,只是简单的控制显示与隐藏。
wx:if
有更高的切换消耗而 hidden
有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden
更好,如果在运行时条件不大可能改变则 wx:if
较好。
模板
在 pages/home/
目录下创建 templates
文件夹,里面用于存放模板文件。我们新建 item.wxml
文:
新建模板
<template name="box1">
<text bindtap="txtFn">box1: {{content}}</text>
</template>
<template name="box2">
<text bindtap="txtFn">box2: {{content}}</text>
</template>
模板引用
//引入模板
<import src="./templates/item.wxml" />
//使用is属性来指定调用 item.wxml 中哪个模板,使用data属性来传值。
<template is="box1" data="{{content: txt}}"></template>
WXS模块
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
//在wxs文件中:
function my_slice(str,a,b){
return str.slice(a,b);
}
module.exports = {
my_slice: my_slice
}
//在wxml文件中:
<wxs src="./test.wxs" module="tools" />
<view>
{{tools.my_slice("123456789",0,5)}}
</view>
也可以写在wxml文件中
<wxs module="tools">
function add(a, b){
var sum = a + b;
return sum;
}
module.exports = {
add: add
};
</wxs>
<view>
{{tools.add(3, 4)}}
</view>
作用:可以提前处理好价格数据(例如小数点后两位,带钱币符号)
组件化开发
新建组件
组件相当于页面,创建的方法与创建页面相同,可以在 app.json
中的 pages
进行创建:
{
"pages": [
...,
"components/product/product"
],
}
结构、样式与数据渲染
//wxml和wxss文件按照正常的写
//在js文件中,把Page()方法改成了Component()方法
Component({
data: {
showArr: [
{imgSrc: "/images/home/newPro1.jpg", imgTxt: "卡布奇诺"},
]
},
})
//方法的调用
methods: {
//事件
getFn(){
}
}
声明为组件
//在组件的json文件中 加入"component": true 声明为组件
{
"usingComponents": {},
"component": true
}
调用组件
//在调用的组件的页面中的json文件中,使用组件usingComponents,并写入组件的位置
{
"usingComponents": {
//调用组件
"product-block": "/components/product/product"
},
"navigationStyle": "custom"
}
//在wxml文件中就可以直接使用(单标签或者双标签都可以)
<product-block />
或:
<product-block></product-block>
组件传值
父传子
//父的 wxml 文件中
<product-block showArr="{{showArr}}" />
传入子组件的数据名 = 父组件的数据名
//在子组件中用 properties 接收
Component({
// properties用于接收传值,类似于vue中的props
properties: {
showArr: {
// 设置数据类型
type: Array,
// 设定初始值(即默认值)
value: [{imgSrc: "/images/home/newPro1.jpg", imgTxt: "卡布奇诺"}]
}
}
})
子传父
//使用事件来进行传递
//在子组件中写入事件 ,然后通过 triggerEvent 进行传递
//子组件的js文件
// components/product/product.js
Component({
...,
// 如果是组件,不是页面,就必须写methods
methods: {
productTap(){
// 小程序中子传父通过triggerEvent来实现
this.triggerEvent('fatherEvent', 100);
传入父组件的自定义事件名,参数
}
}
})
//父组件中通过bind:自定义事件名
//<!-- 标签上使用bind来接收子组件传过来的事件 -->
<product-block showArr="{{showArr}}" bind:fatherEvent="fatherEventFn" />
子组件的自定义事件名 ,父组件的事件名
Page({
...,
// 页面无需写methods
fatherEventFn(data){
console.log(data.detail); // 100
}
})
全局变量globalData
在app.js文件中
// app.js
App({
onLaunch() {
},
//和onLaunch同级
globalData: {
userInfo: "",
pageUrl:""
}
})
调用方法
//【方法一(推荐)】通过app获取,需要在第一行声明app的实例 const app = getApp()
const app = getApp()
Page({
onLoad: function () {
console.log(app.globalData.name);
},
})
//【方法二】直接通过getApp().globalData获取,不需要写const app = getApp()实例
onLoad: function () {
console.log(getApp().globalData.name);
},
//
修改global的方法
//不声明app的实例
getApp().globalData.name="xxxx"
//声明app的实例
app.globalData.name = "xxxx";
路由跳转
跳转到非tabbar页面(js)—navigateTo
wx.navigateTo({
url: '/pages/logs/logs'
})
// url携带参数的形式:
wx.navigateTo({
url: '/pages/logs/logs?id=123',
})
// 如何获取参数?
onLoad: function (options) {
console.log(options.id) // 123
},
// 携带复杂参数的形式
wx.navigateTo({
url: '/pages/logs/logs?id=123',
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('someData', { arr: [1,2,3] })
}
})
// 接收复杂参数的形式
onLoad: function (options) {
console.log(options.id) // 123
const eventChannel = this.getOpenerEventChannel() // 通过eventChannel来获取参数
eventChannel.on('someData', function(data) {
console.log(data.arr) // [1,2,3]
})
},
// 当前页反向发射数据到上一页
onLoad: function (options) {
const eventChannel = this.getOpenerEventChannel()
// 反向发射数据
eventChannel.emit('fanxiang', {username: '张三'});
},
// 上一页接收反向发射的数据
wx.navigateTo({
url: '/pages/list/list?id=123',
// events中写反向发射的函数
events: {
fanxiang(data){
console.log(data)
}
}
})
参数
Object object
属性 类型 默认值 必填 说明
url string 是 需要跳转的应用内非 tabBar 的页面的路径 (代码包路径), 路径后可以带参数。参数与路径之间使用 ? 分隔,参数键与参数值用 = 相连,不同参数用 & 分隔;如 'path?key=value&key2=value2'
events Object 否 页面间通信接口,用于监听被打开页面发送到当前页面的数据。基础库 2.7.3 开始支持。
success function 否 接口调用成功的回调函数
fail function 否 接口调用失败的回调函数
complete function 否 接口调用结束的回调函数(调用成功、失败都会执行)
object.success 回调函数
参数
Object res
属性 类型 说明
eventChannel EventChannel 和被打开页面进行通信
跳转到非tabbar页面(wxml)
<navigator url="/pages/logs/logs"></navigator>
跳转到tabbar页面
wx.switchTab({
url: '/pages/user/user'
})
参数
Object object
属性 类型 默认值 必填 说明
url string 是 需要跳转的 tabBar 页面的路径 (代码包路径)(需在 app.json 的 tabBar 字段定义的页面),路径后不能带参数。
success function 否 接口调用成功的回调函数
fail function 否 接口调用失败的回调函数
complete function 否 接口调用结束的回调函数(调用成功、失败都会执行)
生命周期
微信小程序有两类生命周期,一类是组件的生命周期 (opens new window),另一类是页面的生命周期 (opens new window)。
页面的生命周期
小程序页面的生命周期为:
onLoad > onShow > onReady > onHide > onShow > onUnload
数据请求
原生API调用
在微信小程序中,我们使用 wx.request()
方法做数据请求,发起 HTTPS 网络请求。如:
wx.request({
url: 'http://kumanxuan1.f3322.net:8001',
success(res){
console.log(res);
}
})
合法域名配置
因为小程序对接口地址有严格要求,所有的baseUrl必须在小程序后台配置合法域名。
到 mp.weixin.qq.com
登录,找到 开发
- 开发管理
- 开发设置
- 服务器域名
。只需要将后端给你的接口地址填写进去即可。这里注意:合法域名必须是https开头,否则无法配置,只能作为开发阶段的测试。
开发阶段想要测试,可以点击开发工具右上角的 详情
:将 不校验合法域名
勾选上即可。
request封装
在根目录下新建文件夹request 里面有两个js文件
request.js
是用来封装请求的,一般我们不动它api.js
是用来统一管理Restful风格的接口地址与baseUrl的
//request.js文件中写入
let baseUrl = "http://kumanxuan1.f3322.net:8001" //前置导航
function requset(api,params) {
return new Promise((resolve,reject)=>{
if(wx.getStorageSync('token')){
wx.request({
url: baseUrl + api,
data:params.data || {},//请求体
header:params.header ||{"X-Nideshop-Token":wx.getStorageSync('token')},//请求头
method:params.method || "GET",//请求数据类型
dataType:"json",
success (res) {
resolve(res.data)
},
fail(err){
reject(err)
}
})
}else{
wx.request({
url: baseUrl + api,
data:params.data || {},
header:params.header || {},
method:params.method || "GET",
dataType:"json",
success (res) {
resolve(res.data)
},
fail(err){
reject(err)
}
})
}
})
}
//导出函数
module.exports={
requset
}
//在api.js文件中写入
//导入
const {requset} = require("./request.js")
// 品牌详情
export const GetBrandApi = (params)=>requset("/brand/detail",params)
//导出
//在需要发起请求的js文件中
//1、先引入函数
const {GetBrandApi}=require("../../request/api.js")
//2、在页面下面就可以直接用了
GetBrandApi({
//传入请求体参数
}).then(res=>{
console.log(res)
})
Vant Weapp引入
依赖安装
Vant Weapp官网地址:https://vant-contrib.gitee.io/vant-weapp/#/home
# npm初始化
npm init -y
# 通过 npm 安装
npm i @vant/weapp -S --production
# 或者通过 yarn 安装
yarn add @vant/weapp --production
修改配置文件
找到 project.config.json
中的 packNpmManually
:
{
"setting": {
...
"packNpmManually": true,
"packNpmRelationList": [
{
"packageJsonPath": "./package.json",
"miniprogramNpmDistDir": "./"
}
]
}
}
构建npm包
打开微信开发者工具,点击 工具 -> 构建 npm,并勾选 使用 npm 模块 选项,构建完成后,即可引入组件
全局引入组件
在 app.json
中:
{
"usingComponents": {
"van-button": "@vant/weapp/button/index"
},
}
在 index.wxml
中:
<van-button type="primary">按钮</van-button>
按需引入组件
在单独某个页面的json文件中引入
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
界面交互
wx.showToast
需要搭配 wx.hideToast 配对使用,一般在定时器 setTimeout 里面写如 hideToast
wx.showToast({
title: '删除成功',
icon: 'success',
duration: 1000
})
setTimeout(() => {
wx.hideToast()
}, 2000)
参数
Object object
属性 类型 默认值 必填 说明 最低版本
title string 是 提示的内容
icon string success 否 图标
合法值 说明
success 显示成功图标,此时 title 文本最多显示 7 个汉字长度
error 显示失败图标,此时 title 文本最多显示 7 个汉字长度
loading 显示加载图标,此时 title 文本最多显示 7 个汉字长度
none 不显示图标,此时 title 文本最多可显示两行,1.9.0及以上版本支持
image string 否 自定义图标的本地路径,image 的优先级高于 icon 1.1.0
duration number 1500 否 提示的延迟时间
mask boolean false 否 是否显示透明蒙层,防止触摸穿透
success function 否 接口调用成功的回调函数
fail function 否 接口调用失败的回调函数
complete function 否 接口调用结束的回调函数(调用成功、失败都会执行)
wx.showLoading
显示 loading 提示框。需主动调用 wx.hideLoading 才能关闭提示框
wx.showLoading({
title: '加载中',
})
setTimeout(function () {
wx.hideLoading()
}, 2000)
参数
Object object
属性 类型 默认值 必填 说明
title string 是 提示的内容
mask boolean false 否 是否显示透明蒙层,防止触摸穿透
success function 否 接口调用成功的回调函数
fail function 否 接口调用失败的回调函数
complete function 否 接口调用结束的回调函数(调用成功、失败都会执行)
- wx.showLoading 和 wx.showToast 同时只能显示一个
小程序使用Less
1、vscode安装less插件
打开vscode,安装 Easy Less
:
2、找到扩展
点击文件目录树旁边的 扩展
,或是直接按 ctrl+shift+x
快捷键到达这个界面:
3、Less配置
默认小程序是用wxss,但因为Easy-less默认输出的css,我们需要设置一下输出的文件后缀。找到以下位置
在打开的界面搜索 easy-less
:点击 在setting.json中编辑,找到 less.compile
:
{
...,
"less.compile": {
"outExt": ".wxss"
}
}
4、编写less
当你在一个页面或组件中删掉原来的 .wxss ,新建.less文件,写完之后只要按ctrl+s,就可以自动编译出来.wxss文件了。
小程序刷新当前页
方法一:
this.onLoad();
// 或是
this.onShow();
方法二:
//如果只是为了清除数据刷新页面,恢复初始值的话,可以将data中的数据抽离,然后重新setData即可:
let obj = {username: "xxx"}
Page({
data: JSON.parse(JSON.stringify(obj)), // 做一次深拷贝,让data与obj脱钩
fn(){
this.setData(obj); // 重新赋值data,相当于刷新了页面,因为数据还原了
}
})
pi/ui/interaction/wx.showLoading.html) 和 wx.showToast 同时只能显示一个
小程序使用Less
1、vscode安装less插件
打开vscode,安装 Easy Less
:
2、找到扩展
点击文件目录树旁边的 扩展
,或是直接按 ctrl+shift+x
快捷键到达这个界面:
3、Less配置
默认小程序是用wxss,但因为Easy-less默认输出的css,我们需要设置一下输出的文件后缀。找到以下位置
[外链图片转存中…(img-IqX4ukkW-1646575860109)]
在打开的界面搜索 easy-less
:点击 在setting.json中编辑,找到 less.compile
:
{
...,
"less.compile": {
"outExt": ".wxss"
}
}
4、编写less
当你在一个页面或组件中删掉原来的 .wxss ,新建.less文件,写完之后只要按ctrl+s,就可以自动编译出来.wxss文件了。
小程序刷新当前页
方法一:
this.onLoad();
// 或是
this.onShow();
方法二:
//如果只是为了清除数据刷新页面,恢复初始值的话,可以将data中的数据抽离,然后重新setData即可:
let obj = {username: "xxx"}
Page({
data: JSON.parse(JSON.stringify(obj)), // 做一次深拷贝,让data与obj脱钩
fn(){
this.setData(obj); // 重新赋值data,相当于刷新了页面,因为数据还原了
}
})