一、创建小程序项目
1. 点击➕新建小程序项目
2.填写项目名称、项目存放目录、AppID、选择开发模式等信息,点击确定就可以进行项目开发了。AppID官网注册登录后,点击开发-开发管理,即可看到开发者ID中的AppID
二、基本目录结构介绍
小程序页面文件夹(每个页面分成4类文件):
-
js业务逻辑文件(在该文件中调用Page()方法注册页面,指定页面的初始数据data:{}、生命周期回调、事件处理函数等)
-
wxml页面结构 类似html
-
wxss页面样式(rpx适配单位、@import ""; 外联样式导入) 类似css(rem适配单位)
-
json 配置文件(页面配置,进行组件注册)
页面配置属性详见:developers.weixin.qq.com/miniprogram…
注:当小程序页面配置与全局配置冲突时根据就近原则以页面配置为准
小程序全局配置
-
app.js小程序执行的入口文件(在该文件中调用APP()方法注册一个小程序应用,小程序启动后会加载app.json配置文件中”pages”项的第一个注册的页面)
-
app.wxss小程序全局样式文件
-
app.json小程序应用全局配置文件(对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等)
全局配置属性详见: developers.weixin.qq.com/miniprogram…
-
pages:记录小程序所有页面存放路径,tabbar页面在pages中要往前提
-
windows:全局设置小程序窗口外观(窗口分为导航栏区域navigationbar、背景区域background(下拉显示)、页面主体区域(展示wxml中的布局))
可以配置导航栏标题、标题颜色(黑白)、背景色(十六进制颜色值)、下拉刷新、下拉刷新背景色(十六进制颜色值)、loading样式(黑白)、上拉触底距离等
- tabbar:设置小程序tabbar效果,实现多页面快速切换(底部tabbar、顶部tabbar)
可以配置tabbar背景色、上边框颜色、选中和未选中时的文本颜色、页面路径、文本、选中和未选中时的图标路径
注意:只能配置2-5个tab页签;顶部tabbar不显示icon,只显示文本
- style:"v2"是否启用新版的组件样式
三、语法
快速创建小程序页面:
找到app.json文件,在pages选项中增加页面路径,保存,微信开发者工具会自动创建对应的页面文件。
小程序官方文档:developers.weixin.qq.com/miniprogram…
1.组件(小程序内置组件在官方文档--组件中可查看)
例:
view视图容器,类似div标签
scroll-view可滚动的视图容器,滚动列表效果
swiper轮播图容器组件,swiper-item轮播图item
text文本组件,类似span标签,不会换行,selectable属性实现长按选中文本内容效果
rich-text富文本组件,nodes属性支持把html字符串渲染为wxml结构(nodes="<h1>标题</h1>")
navigator url=“”超链接,类似a href=“”标签
image图片组件,mode属性指定图片裁剪缩放模式(scaleToFill默认不保持横纵比缩放)
button按钮组件,open-type属性可以调用微信提供的各种功能(客服、转发、获取用户授权、信息等)
2. 样式
app.wxss中定义全局样式,可以在所有页面直接用
页面文件夹中的wxss文件定义页面样式,在该页面直接用
3. 数据显示
模板插值{{}}
4. 数据处理
4.1动态绑定数据
js文件data中定义数据:data: {title: "首页"}
wxml文件中使用数据:<text>{{title}}</text>
4.2动态绑定属性
data: {src: "www.baidu.com"}
<navigator url=“{{src}}”></navigator>
(vue中绑定属性用v-bind)
4.3获取、更改数据
获取:this.data.title
更改:this.setData({title})(同react)
5. 事件(常用事件:tap手指触屏后马上离开,类似click、input文本框输入事件、change复选框状态改变时触发)
bind:tap=""或者bindtap=""手指触屏后马上离开(vue中v-on:click=””或者@click=””点击事件)
bind:longpress=””手指触屏后超过350ms在离开,长按事件
bind:touchmove=””手指触摸后移动
bind:touchstart=””手指触摸动作开始
bind:touchend=””手指触摸动作结束
bind:touchcancel=””手指触摸动作被打断,比如来电提醒
bind:input=""文本框输入事件
5.1事件回调触发,会收到一个事件对象event,其属性有:
type:事件类型
timeStamp:页面打开到触发事件所经过的毫秒数
target:触发事件的源头组件的一些属性值集合
currentTarget:当前正在触发事件组件的一些属性值集合
detail:额外的参数信息
touches:触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouches:触摸事件,当前变化的触摸点信息的数组
5.2事件冒泡(当触发一个事件时,事件会从事件源向上冒泡,直到window对象结束)bind:tap=""
除 bind 外,也可以用 catch 来绑定事件, catch 会阻止事件向上冒泡。
阻止事件冒泡catch:tap=""
5.3事件捕获capture-bind:tap=””
阻止事件捕获capture-catch:tap=””
应用场景:自定义组件时
6、事件传参
bind:tap="onDelete" data-id="{{100}}"({{100}}传的是数字,100传的是字符串)
通过data-传参,id为参数名,100为参数值(vue中 通过事件括号传参)
e.target.dataset获取参数
7、条件渲染
wx:if/wx:elif/wx:else=”{{online}}”(vue中v-if/v-else=”online”)
结合block使用,使用block标签将多个组件包装起来,一次性控制多个组件的展示隐藏:
block包裹不会在页面中渲染,view包裹会在页面中渲染
<block wx:if="{{true}}">
<view>1</view>
<view>2</view>
</block>
控制元素显示隐藏:<view hidden=“{{true}}”>1</view>
wx:if和hidden对比:
wx:if以动态创建和移除元素的方式,实现元素的展示隐藏。控制条件比较复杂时使用
hidden以切换样式的方式,控制元素的展示隐藏(display:none/block)。频繁切换时使用
8、列表渲染
wx:for=”{{list}}” wx:key=”id”(vue中v-for=”list” :key=”id”)
列表项默认为item,索引号默认为index
wx:for-item=”user” wx:for-index=”id”
列表项修改为user,索引号修改为id
9、表单数据双向绑定
value=”” bind:input=””/model:value=”{{}}” 通过e.detail.value获取输入框的值
(vue中 :value="" @input=""/v-model 通过event.target.value获取输入框的值)
10、屏幕适配单位rpx
小程序特有的适配单位,可以根据屏幕宽度自适应
rpx把所有设备的屏幕宽度等分为750份(即当前屏幕总宽度为750rpx),小程序在不同设备上运行的时候,会自动把rpx 的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配
换算: rpx换px(屏幕宽度/750)
iphone6 屏幕宽度375px,750个物理像素,等分为750rpx
1rpx = 0.5px 1px = 2rpx
示例代码
wxml文件
<view class="container">
<view>-- 数据显示 --</view>
<text>{{title}}</text>
<view>-- 触屏事件 --</view>
<button bind:tap="onTap">确定</button>
<!-- <button bindtap="onTap">确定</button> -->
<view>-- 条件渲染 --</view>
<view>
<text wx:if="{{online === 0}}">在线状态</text>
<text wx:elif="{{online === 1}}" >离线状态</text>
<text wx:else>隐身状态</text>
</view>
<view>-- 列表渲染 --</view>
<view>
<view wx:for="{{list}}" wx:key="index">
<text>{{item.name}}-{{item.age}}</text>
</view>
//修改列表项和索引号
<view wx:for="{{list}}" wx:for-item="user" wx:for-index="id" wx:key="id">
<text>{{id}}-{{user.name}}-{{user.age}}</text>
</view>
</view>
<view>-- 表单双向数据绑定 --</view>
<view>
<text>{{inputValue}}</text>
<!-- <input class="m-input" type="text" value="{{inputValue}}" bind:input="onInput" placeholder="请输入内容"/> -->
<input class="m-input" type="text" model:value="{{inputValue}}"/>
</view>
<view>-- 事件传参 --</view>
<view>
<button bind:tap="onDelete" data-id="100" data-price="88.98">删除</button>
</view>
<view>-- rpx 屏幕适配单位 --</view>
<view>
<view class="g-wrapper">rpx单位</view>
</view>
</view>
js文件
Page({
data: {
title: "首页",
online: 2,
list: [
{ name: "jack", age: 21 },
{ name: "rose", age: 20 },
{ name: "tom", age: 21 },
],
inputValue: "hello",
},
// 触屏事件
onTap() {
console.log("onTap >>> ");
// this.data.title = '修改后的首页'
//更改数据
this.setData({title:'修改后的首页'})
},
/**
* 输入事件
* e.detail.value
*/
onInput(e) {
// this.setData({ inputValue:e.detail.value });
const inputValue = e.detail.value;
console.log("onInput >>> ", inputValue);
this.setData({ inputValue });
},
// 删除
onDelete(e) {
console.log("onDelete >>> ", e);
console.log('id ',e.target.dataset.id);
console.log('price ',e.target.dataset.price);
},
});
wxss文件
.m-input{
border: 1px solid gray;
}
.g-wrapper{
/* width: 100px;
height: 100px; */
width: 200rpx;
height: 200rpx;
background-color: skyblue;
}
11、wxs小程序独有的脚本语言(结合wxml构建页面结构)
wxml中无法调用在页面的.js 中定义的function函数,但是,wxml中可以调用 wxs 中定义的函数。当作过滤器使用。
wxs语法:
① wxs 有自己的数据类型(number、string、boolean、object、function、array、date日期类型、regexp正则)
② wxs 不支持ES6及以上的语法形式
不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc..
支持:var 定义变量、普通 function 函数等,类似于 ES5 的语法
③ wxs 遵循 Commonjs 规范
module 对象、require()函数、module.exports 对象
④ wxs语法类似于javascript(wxml文件中使用<wxs>标签,<wxs>标签必须提供 module 属性,用来指定当前 wxs 的模块名称。就像html中使用<script>标签)
wxs特点:
- 隔离性( wxs 的运行环境和其他JavaScript 代码是隔离的)
① wxs 不能调用js 中定义的函数
② wxs 不能调用小程序提供的 API
2.性能好
① 在 i0s 设备上,小程序内的 WXS 会比JavaScript 代码快 2~20 倍
② 在 android 设备上,二者的运行效率无差异
示例代码1(内联)
wxml文件
<wxs module="eg">
module.exports.filterUrl = function(url){
if(url && url.indexOf('http') === -1){
return 'https://10.7.163.165:8089'+url
}
return url
}
</wxs>
<view>
<!-- 菜品列表 -->
<block wx:for="{{goodsList}}" wx:key="*this">
<van-card num="0" price="{{item.price}}" desc="{{item.desc}}" title="{{item.product}}" thumb="{{ eg.filterUrl(item.picture) }}">
<view slot="footer">
<van-button round icon="plus" type="warning" size="mini"></van-button>
</view>
</van-card>
</block>
</view>
js文件
// pages/goods/index.js
import { RequestGoodsList } from '../../api/goods'
Page({
/**
* 页面的初始数据
*/
data: {
goodsList: [], // 菜品列表
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getGoodsList()
},
/**
* 获取菜品列表
*/
async getGoodsList() {
const data = await RequestGoodsList()
const { resultCode, resultInfo } = data
if (resultCode === 1) {
const list = resultInfo.list // 当前页列表
this.setData({ goodsList: list })
}
}
})
示例代码2(外联)
编写在以wxs为后缀的文件中,就像javascript编写在以js为后缀的文件中
在util文件夹中创建一个util.wxs文件
function filterUrl(url){
if(url && url.indexOf('http') === -1){
return 'http://10.7.163.165:8089'+url
}
return url
}
module.exports = {
filterUrl:filterUrl//属性:值
}
wxml文件
<wxs src="../../utils/utils.wxs" module="util"></wxs>
<view>
<!-- 菜品列表 -->
<block wx:for="{{goodsList}}" wx:key="*this">
<van-card num="0" price="{{item.price}}" desc="{{item.desc}}" title="{{item.product}}" thumb="{{ util.filterUrl(item.picture) }}">
<view slot="footer">
<van-button round icon="plus" type="warning" size="mini"></van-button>
</view>
</van-card>
</block>
</view>
js文件
// pages/goods/index.js
import { RequestGoodsList } from '../../api/goods'
Page({
/**
* 页面的初始数据
*/
data: {
goodsList: [], // 菜品列表
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getGoodsList()
},
/**
* 获取菜品列表
*/
async getGoodsList() {
const data = await RequestGoodsList()
const { resultCode, resultInfo } = data
if (resultCode === 1) {
const list = resultInfo.list // 当前页列表
this.setData({ goodsList: list })
}
}
})