/**
* pages页面组成
* -- .js、.json、.wxml、.wxss
*
* app.json: 全局配置
*
* WXML: 小程序的标签语言,用来构建小程序的UI结构,类似于HTML但是和HTML有所不同
* WXML和HTML区别
* 1.标签名不同
* HTML(div, span, img, a)
* WXML(view, text, image, navigator)
* 2.属性节点不同
* <a href=""></a>
* <navigator url=""></navigator>
* 3.提供了类似于vue中的模板语法
* 数据绑定、列表渲染、条件渲染等
*
* WXSS: 一套小程序的样式语言,类似于网页开发中的CSS,用于美化页面结构
* WXSS和CSS区别
* 1.新增了rpx尺寸单位
* rpx:小程序独有的屏幕适配单位,会在不同大小屏幕进行换算,类似css中rem
* 2.提供了全局样式和局部样式
* 根目录中app.wxss会作用于所有小程序页面
* 局部页面.wxss仅对当前样式生效
* 3.WXSS仅支持部分CSS选择器
* 支持的选择器:id、class、element、后代选择器、伪类(before, after)选择器等
* 4.增加了'@import' 样式导入
*
* 宿主环境:程序运行所必须的依赖环境(如android和ios是不同宿主环境)
* 手机微信是微信小程序的宿主环境
*
* 小程序通信模型:
* 渲染层(wxml、wxss)和逻辑层(js):通过Native微信客户端进行通信
* 逻辑层(js)和三方服务器:通过Native微信客户端进行通信
*
* 小程序数据渲染
* 渲染数据 --> {{msg}}
* 动态渲染 --> src={{path}} (和vue区别src前面没有:(冒号))
* 三元运算 --> {{trigger ? '是' : '否'}}
* 条件渲染 -->
* wx:if <view wx:if={{show}}></view>
* wx:elif <view wx:elif={{show}}></view>
* wx:else <view wx:else></view>
* hidden也能控制元素的显示与隐藏
* <view hidden={{show}}></view> show为true隐藏,false显示元素
* wx:if和hidden对比
* wx:if 动态创建和移除元素
* hidden 通过样式display:none控制显示与隐藏
*
* 循环渲染
* wx:for
* <view class="item" wx:for="{{3}}" wx:key="index">{{item}}</view>
* 内置好了item和index属性!!!
* 修改索引名和item项
* <view class="item" wx:for="{{3}}" wx:for-index="idx" wx:for-item="v" wx:key="idx">{{v}}</view>
*
* 小程序事件绑定
* bind:tap="事件名" 或 bindtap="事件名"
* bind:input 或 bindinput
* bind:change 或 bindchange
*
* 事件传参
* <button bindtap="事件名" data-参数名="参数值"></button>
* 获取: e.target.dataset.参数名
*
* 小程序中数据请求
* 限制:
* 只能请求HTTPS类型接口
* 必须将接口域名添加到信任列表中
* 配置request合法域名
* 步骤:登录微信小程序管理后台->开发->开发设置->服务器域名->修改request合法域名(放入自己要访问的域名 如:https://www.baidu.com)
* 发起请求
* wx.request({
* url: '',
* method: 'GET',
* data: {},
* success: (res) => {}
* })
*
* 小程序中不存在跨域问题:因为跨域只存在浏览器中,小程序宿主环境是微信客户端,因此不存在跨域
*
* 小程序中导航跳转
* 声明式跳转
* -- <navigator url=""></navigator>
* 注意点:
* 1. 跳转地址必须以 "/" 开头
* 2. 如果要跳转到tabbar, 必须设置"switchTab"(<navigator url="" open-type="switchTab"></navigator>)
* 3. 要后退到上一级或多级页面 open-type="navigateBack" delta="" (delta为数字,表示要后退的层级)
* 4. 跳转传参 url="/pages/list/list?id=1&name=2" 这种形式
* 编程式跳转
* 1. 普通跳转及传参
* wx.navigateTo({
* url: '/pages/logs/logs?id=1&name=2'
* })
* 2. 跳转tabbar
* wx.switchTab({
* url: '/pages/logs/logs'
* })
* 3. 后退
* wx.navigateBack({
* delat: 1
* }) 默认返回上一级
* 获取导航参数:onLoad(options)的options中获取
*
* 手动收起下拉刷新:wx.stopPullDownRefresh()
*
* 小程序生命周期
* -- 应用生命周期: 小程序启动->运行->销毁的过程
* 应用生命周期函数
* onLaunch(): 小程序初始化完成、全局只执行一次,做初始化工作
* onShow(): 小程序启动,或从后台进入前台时触发
* onHide(): 小程序从前台进入后台时触发
* -- 页面生命周期: 页面加载->渲染->销毁的过程
* onLoad(options): 页面加载,一个页面只执行一次(相当于created)
* onShow(): 页面显示
* onReady(): 页面初次渲染完成、一个页面只执行一次(才能获取到DOM,相当于mounted)
* onHide(): 页面隐藏
* onUnload(): 页面卸载、一个页面只执行一次
*
* wxs脚本:类似于html中的<script></script>作用(但本质上和JS是完全不同的两种语言)
* 用法:(如将小写转为大写)
* <view>{{m1.toUpper('zz')}}</view> // 会显示一个ZZ
* <wxs module="m1"> // 定义一个module名称
* module.exports.toUpper = function(str) {
* return str.toUpperCase()
* }
* </wxs>
*
* 使用外联wxs脚本
* <wxs src="脚本地址" module="m2"></wxs> // 脚本地址如:../utils/toUpper.wxs (在utils下创建toUpper.wxs文件)
* <view>{{m2.toUpper('zz')}}</view> // 会显示一个ZZ
*
* 小程序设置顶部title
* wx.setNavigationBarTitle({title: '自定义名称'})
* 或.json文件中配置navigationBarTitleText
*
* 数据请求:
* 判断是否还有下一页数据
* 公式: 当前页码(page) * 每页条数(pageSize) >= 总数据条数(total) // 满足则已经请求完,不再请求下一页数据
*
* 小程序中自定义组件
* 1. 创建components文件夹 -->
* 创建如test名的文件夹 -->
* test上右键,点击新建Component -->
* 回车生成四个文件.json .js .wxss. wxml
* 2. 局部引用组件
* 在页面.json中引入组件
* {
* "usingComponents": {
* 'my-test': "/components/test/test"
* }
* }
* 页面.wxml中使用<my-test></my-test>渲染组件
* 3. 全局引用组件 app.json中配置
* {
* "usingComponents": {
* 'my-test': "/components/test/test"
* }
* }
*
* 组件和页面的区别
* 1. .json文件不同,组件中需要声明component: true属性
* 2. .js文件组件中调用的是Component函数, 页面中调用的是Page()函数
* 3. 组建的事件处理函数需要定义到methods节点中, 页面中和data平级即可
*
* 组件样式注意点:
* 1. app.wxss中的全局样式对组件无效
* 2. 只有class选择器才有样式隔离效果(外界不影响组件,组件不影响外界),其他选择器都没有样式隔离
*
* 修改组件样式隔离(styleIsolation), 两种方法:
* 1. 组件.js中修改
* Component({
* options: {
* styleIsolation: 'isolated'
* }
* })
* 2. 组件.json文件中新增配置
* {
* "styleIsolation": "isolated"
* }
*
* styleIsolation: 选项
* 1. isolated: 启用样式隔离
* 2. apply-shared: 页面可影响组件,组件不能影响页面
* 3. shared: 页面和组件样式相互影响
*
* 自定义组件中的properties属性
* 用来接收外界传值到组件中的数据
* properties: {
* age: {
* type: Number,
* value: 0
* }
* },
* 组件中使用: <text>{{age}}</text>
* 组件js中使用: this.properties.属性名 获取
*
* data和properties区别
* 1. data倾向于存储私有数据, properties倾向于存储外界传给组件的数据
* 2. 都是可读可写的, 用法也相同,通过this调用
* 3. 也可以用this.setData修改properties中的值
* this.setData({age: this.properties.age + 1})
*
* 小程序中事件监听器(类似vue中watch作用)
* .js文件中
* Component({
* observer: {
* '字段A, 字段B': function(新A字段, 新B字段) {
* // do something
* }
* }
* })
*
* 小程序中纯数据字段: 不用于页面渲染的数据字段(提升页面渲染性能)
* 声明方式:
* Component({
* options: {
* pureDataPattern: /^_/ // 规定以下划线开头的数据为纯数据
* },
* data: {
* _a: '纯数据',
* b: '普通数据,页面渲染会用到'
* }
* })
*
* 组件生命周期函数
* created(): 还不能调用setData方法
* attached(): 数据已初始化完毕,可以发送数据请求
* ready()
* moved()
* detached(): 做一些清理性质工作
* error()
*
* 新生命周期 lifetimes 会替代旧的生命周期(推荐使用)
* Component({
* lifetimes: {
* created(){},
* attached(){},
* ready(){},
* moved(){},
* detached(){},
* error(){}
* }
* })
*
* 组件监听页面生命周期 pageLifetimes
* Component({
* pageLifetimes: {
* show(){},
* hide(){},
* resize(){}
* }
* })
*
* 组件定义多个插槽(slot)
* 组件.js ——> options 中配置
* options: { multipleSlots: true }
* 组件.wxml 中使用name区分
* <slot name="age"></slot>
* <slot name="sex"></slot>
* 页面中使用
* <view slot="age">18</view>
* <view slot="sex">女</view>
*
* 父子组件通信3种方式
* 1. 属性绑定: 用于父组件向子组件的指定属性设置数据,只能设置JSON数据 <text age={{age}}></text>
* 2. 事件绑定: 用于子组件向父组件传递数据,可传递任何数据
* 步骤:
* -- 父组件.js中自定义事件函数
syncCount(e) {
this.setData({
count: e.detail.count
})
}
-- 父组件.wxml中传递事件
<my-test class="text-color" count="{{count}}" bind:sync="syncCount"> // bind:自定义名称="syncCount"
-- 子组件中通过this.triggerEvent调用
this.triggerEvent('sync', {count: this.properties.count}) // sync为bind:中的自定义名称
-- 父组件自定义事件中通过e.detail获取数据
*
* 3. 获取组件实例: 用于父组件获取子组件实例 通过this.selectComponent(id或class选择器)获取子组件
* eg: getSonCom() {
* this.selectComponent('.mytest')
* }
*
* 组件中的behaviors:实现组件间代码共享特性,相当于vue中的mixins
* 1. 创建behaviors文件夹 -> my-behavior.js
* 2. my-behavior.js中写入逻辑
* module.exports = Behavior({
data: {
title: 'my-behavior'
}
})
3. 组件.js中引入
const myBehavior = require("../../Behavior/my-behavior")
Component({
behaviors: [myBehavior]
})
4. 组件.wxml中使用
<view>在behavior中定义的title是: {{title}}</view>
*
* 小程序中使用npm
* 三个限制:
* 1. 不支持依赖于Node.js内置库的包(fs等)
* 2. 不支持依赖于浏览器内置对象的包(jquery等)
* 3. 不支持依赖于C++插件的包
*
* 使用vant weapp
* 1. npm安装(建议指定版本@1.3.3)
* (在开发工具根目录空白区域->右键->外部终端窗口中打开->先npm init -y初始化 -> npm install ...)
* 2. 构建npm包
* 开发工具 -> 工具 -> 构建npm(完成后) -> 右侧详情按钮 -> 本地设置 -> 勾选使用npm模块
* 3. 修改app.json
* 将"style": "v2"去除,不关闭容易造成样式冲突
*
* vant定制主题样式
* 1. 定义变量: 属性名以两个减号开头 (如: --main-color: '#ee0000)
* 2. 使用变量: 通过var使用 (如: color: var(--main-color))
*
* 修改vant相关主题样式
* 1. app.wxss中,写入css变量,即对全局生效
*
* page { // page为根节点,对全局生效
* --button-danger-background-color: #C00000; // 变量名 参考vant weapp官方文档 -> 定制主题 -> 配置文件
* }
*
* 使用npm包进行API Promise化
* 通过额外配置,将小程序提供的基于回调函数的API修改为基于Promise的异步API,提高代码可读性,维护性,避免回调地狱
* 步骤:
* 1. 安装 npm install --save miniprogram-api-promise@1.0.4
* 2. 开发工具中重新构建npm(如果构建失败,删除miniprogram_npm后,重新构建)
* 3. 使用(在app.js中引入)
* import { promisifyAll } from 'miniprogram-api-promise'
const wxp = wx.p = {} // 以后可通过wx.p调用promise api
promisifyAll(wx, wxp)
页面中(.js)使用:
async getList() {
let res = await wx.p.request({
url: 'url',
method: 'GET',
data: {name: 'zz'}
})
if (res) {
// do something
}
},
*
* 全局数据共享
* 也叫状态管理,用于解决组件之间数据共享问题
* 小程序中使用mobx-miniprogram(用来创建store) + mobx-miniprogram-bindings(用来把store中数据绑定到组件上)实现
* 1. 安装这两个包 npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
* 2. 构建npm
* 3. 页面中使用
* 项目根目录创建store文件夹 - >index.js文件
* import { observable } from 'mobx-miniprogram'
export const store = observable({
// 数组字段
count: 0,
a: 1,
b: 2,
// get计算属性
get sum() {
return a + b
},
// action 修改数据 (注意不要使用箭头函数,this会指向错误!!!)
updateA: action(function(val) {
this.a += val
})
})
* 页面中(.js)使用
import { createStoreBindings } from 'mobx-miniprogram-bindings'
import { store } from '../../store/index'
// 在onload中绑定
onload: function() {
this.storeBinding = createStoreBindings(this, {
store,
fields: ['count', 'a', 'b', 'sum'], (注意别写错了 !!!fields)
actions: ['updateA']
})
}
// unUnload中清除
unUnload: function() {
this.storeBindings.destoryStoreBindings()
}
事件调用直接用this.updateA()
页面(.wxml)中使用
<view>{{count}}{{a}}{{b}}</view>
*
* 4. 组件中(.js)使用store
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from '../../store/index'
// 在Components
在Components({
behaviors: [storeBindingsBehavior],
storeBindings: {
store,
fields: {
a: () => store.a,
b: () => store.b,
sum: 'sum'
},
actions: {
updateA: 'updateA'
}
}
})
页面(.wxml)中使用
<view>{{count}}{{a}}{{b}}</view>
*
* 分包
* 将一个完整的小程序项目,按照需求划分为不同的自爆,在构建时打包成不同的分包,用户使用时按需进行加载
* 优点:
* 1. 优化小程序首次启动的下载时间
* 2. 多团队共同开发时可以更好地解耦协作
* 限制:
* 1. 素有分包大小不超过16M(主包 + 所有分包)
* 2. 单个分包/主包不超过2M
*
* 基本用法:
* 1. app.json中配置subpackages节点
* "subPackages": [
{
"root": "packageA", // 第一个分包根目录
"name": "p1", // 起一个别名p1
"pages": [ // 当前分包下所有页面的存放路径
"pages/index/index",
"pages/list/list"
]
},
{
"root": "packageB", // 第一个分包根目录
"pages": [
"pages/logs/logs",
"pages/tests/tests"
]
}
],
*
* 独立分包
* 可独立于主包和分包而单独运行
* 优点:提升分包页面启动速度,不用加载主包
* 配置(app.json):添加"independent": true属性即可
* "subPackages": [
{
"root": "packageA",
"pages": [
"pages/list/list"
],
"independent": true
}
]
*
*
* 独立分包和普通分包区别:是否依赖于主包才能运行
*
* 独立分包引用原则
* 1. 主包无法引用独立分包内的私有资源(!!!注意)
* 2. 独立分包之间不能互相引用私有资源
* 3. 独立分包和普通分包之间,不能互相引用私有资源
*
* 分包预下载
* 框架自动下载可能用到的资源
* 配置(app.json)
* "preloadRule": {
"pages/list/list": { // 要进行预下载页面的路径
"network": "all",
"packages": ["packageA", "packageB"] // 要与下载的分包名
}
},
*
*
*
*/
微信小程序开发知识点
于 2022-01-27 15:08:11 首次发布