篇幅较长,可以先收藏再看噢!欢迎转载,转载请附上本文链接。
本文链接:https://blog.youkuaiyun.com/fanxiaomeng92/article/details/105076903
前言
自2018年闲散时片段学过小程序之后,由于没有实际开发的需要,也包含其他因素,我就再没接触小程序了。由于今年有了开发需要,我又从0基础开始学习小程序。
俗话说的好:“师父领进门,修行在个人”。 一个好的师傅的引导也是非常重要且有必要的。
我总结了上次学习不成功的原因:
- 自己找的资料质量参差不齐,耗费精力不说,学到的也不一定是重点;
- 没有方向,自己不知道该学习哪方面,学的不系统,连贯不上;
因此,本次我精挑细选了网上的资源,不得不说,网上资源无数,挑一个你认为好的、适合你的坚持学习下来,比收集多个课程有效的多!
我选择的课程
我选择的课程是哔哩哔哩上(如上图用户)老师的小程序课程。
本文是我自己课后总结的,老师的视频更详细,全面,专业。
课程特点:
- 老师讲的非常的细致,对于小程序0基础者比如我,非常适合;(但是对于一些有部分经验的人来说可能过于细致)
- 比较系统且有理论基础,不止会让你“造轮子”,还会讲轮子背后的理论👍;
这个视频我已经全部学完了,我感觉非常有收获,因此,我决定在这个节点上输出一下。
1. 开发前
1.1 预备知识
1.2 开发前的准备
1.3 小程序的配置文件
1.4 小程序的双线程模型
问:谁是小程序的宿主环境?
答:微信客户端。
微信小程序为了执行小程序的各种文件(wxml、wxss、js),提供了小程序的双线程模型。
【双线程模型是什么】
简单来说:
渲染层:1个app有个多个页面,1个页面1个webView渲染页面;
逻辑层:js脚本运行于逻辑层,用JsCore运行脚本;
交互通信:两个线程会经由微信客户端(native)进行中转交互;
具体的大家可以学习小程序的“页面渲染过程”,更深层次的理解双线程模型。
1.5 小程序的启动流程
小程序入口 => app.json
1.6 page页面的生命周期
onLoad() //页面加载时调用
onShow() //页面显示时
onReady() //页面初次渲染完成时
onHide() //页面隐藏时
onUnload() //页面跳转时
1.7 wxs
1.7.1 定义
wxs是小程序的一套脚本语言,结合wxml,可以构建页面
官方:与javascript不同;
老师:基本一致。
1.7.2 为什么存在?
wxml中不能直接调用page/component中定义的函数。
实际开发中,我们有这样的需求,也就是用会函数来处理wxml中的数据。
1.7.3 特点&局限
- wxs的运行环境和其他JavaScript代码是隔离的,wxs中不能调用javascript中的函数,也不能使用小程序的API;
- wxs函数不能作为组件的事件回掉;
- wxs在iOS上比JavaScript快2-20倍,在android上无差异;
1.7.4 写法
// 定义一个wxs文件内部。例:
var name = 'myname';
module.exports = {
name: name
}
- wxs必须设modules属性,起个名;
- wxs内的代码默认私有,必须modules.exports导出,外部才能使用;
- wxs文件导入
<wxs src='文件的相对路径../../' module=‘起名’ />
- 可以单标签,也可以双标签;
2. 小程序登录
小程序端需要做的:
- 调用wx登录API获取code值:wx.login(),code有效期5分钟;
- 调用网络请求把code传到自己服务器,(如果这时候需要用户名和密码,则一并传过去)
- 服务器返回token。token保存storage中备用;
- 请求登录态标识的接口时,携带token
3. 事件
3.1 事件的冒泡与捕获
当界面产生一个事件时,事件分为捕获阶段和冒泡阶段。
capture:监听事件的捕获;
bind:进行事件的冒泡;——会一层层的传递
catch:阻止事件的进一步传递
<view capture-bind:tap='captureView'
bind:tap='bindView'
catch:tap='catchView'>
</view>
3.2 监听事件
bind监听事件的点击、长按、移动等,官方文档事件详解
<button bindtap='handleclick'>按钮</button>
//或者
<button bind:tap='handleclick'>按钮</button>
//.js
//只有在setData方法中设置属性数据,页面才会发生改变;
handleclick() {
this.setData({
// 属性名:属性值
})
}
- data-自定义参数名=“值”,传事件的参数
- 获取事件**传的参数 event.currentTarget.dataset **;
// 传递参数index
<block wx:for="abc" wx:key="*this">
<view bind:tap="handleBtn"
data-index="{{index}}">
{{item}}
</view>
</block>
//获取参数index,可以打印一下event
handleBtn(event){
const data = event.currentTarget.dataset;
console.log(data.index)
}
4. 组件
4.1 内置组件
- view是块级元素,块级元素独占一行;
- image组件默认尺寸 320 * 240 px——所有屏幕上;
- image默认不懒加载,若懒加载,则上下三凭开始加载;
- scroll-view:局部滚动,因为默认全局超出会自动滚动;
- 组件行内也可以设置样式,优先级:行内 > 页内 > 全局样式;
- px不自适应,rpx自适应,字体、尺寸都可用rpx 官方文档对rpx的描述;
- 有一个官方样式库可以帮助你更快的实现页面,样式库地址
内置组件有很多,官方文档里的用法和各种参数表述的都非常详细,官网文档传送门
4.2 组件化开发
把复杂的大问题,拆分为多个小问题。
- 自定义组件同样有js wxml wxss json文件;
- 自定义组件要在页面的json文件中的components:[ ]中注册才能使用;
- 自定义组件在页面的注册命名规范:小写字母、中划线、下划线的组合,不能“wx-”开头;
- 自定义组件可以套娃,也就是组件里还可以嵌套其他的自定义组件;
4.2.1 自定义组件的基本使用
自定义组件可以套娃,也就是说自定义组件1里面可以嵌套自定义组件2。
- 创建自定义组件
我创建一个名叫“mycpns”的组件
- 注册自定义组件
在你要用到这个组件的页面或者组件的json文件的usingComponents属性里注册这个组件。
⚠️【自定义组件起名规则】:
- 小写字母、中华线、下划线的组合;
- 不能以“wx-”开头;
- 调用自定义组件
//页面/组件.wxml
//可以单标签,也可以双标签
<mycpns/>
<mycpns></mycpns>
4.2.2 组件与页面之间的通信
页面 => 组件:传数据properties
- 在组件.js文件的properties属性中定义属性age和name。
// components/mycpns/mycpns.js
Component({
/**
* 组件的属性列表
*/
properties: {
age: String, //定义属性的方法1: 缺点是不可以设置默认值
name: { //定义属性的方法2
type: String, //name属性的类型
value: 'default' //name属性的默认值,可以为空''
}
},
- 在组件.wxml中写页面,调用属性数据
<!--components/mycpns/mycpns.wxml-->
<text>这里是自定义组件mycpns</text>
<view>name{{name}}</view>
<view>age{{age}}</view>
- 在页面中声明组件,调用组件的时候,传数据
// home.json
"usingComponents": {
"mycpns": "/components/mycpns/mycpns"
}
// home.wxml
<mycpns age="18" name="大明星"/>
页面 => 组件:传样式externalClasses
- 组件.js中定一个一个class名称
- 在组件.js中的externalClasses中设置传递样式
- 接收样式,并在wxss中实现样式
组件 => 页面:传自定义事件
- 定义事件方法
在组件.js中的methods中定义触发事件的方法,在方法中定义this.triggerEvent(“事件名”, {参数1: 值1, 参数2: 值2 }, {options})
/**
* 组件的方法列表
*/
methods: {
// 组件里按钮触发handlebutton方法
handlebutton: function(){
// 定义事件
this.triggerEvent("cpnsbutton", {address:"北京"}, {})
}
}
- 监听事件
<自定义组件名 bind:事件名=“方法名” />
然后在js文件中实现这个方法,参数1,参数2都在detail里。
<mycpns age="18" name="大明星" bind:cpnsbutton="handlehomecpns"/>
- 实现方法
handlehomecpns: function(event){
// event.detail数据
// event.detail.address 北京
}
页面 :调用组件修改数据/方法
4.3 template模版
template模版,可以定义代码片段,然后在不同的地方调用,复用机制的一种。
- 模版内的代码没有调用之前不会渲染;
- 必须要设置 name属性;
- 可以单标签,也可以双标签;
//定义模版
<template name='item'>
<view>{{currentText}}</view>
<button>{{btn}}</button>
</template>
//使用
<template is='item' data="{{currentText:'我是模板',btn:'按钮'}}"/>
4.4 block标签
4.4.1 元素
block不用渲染,性能好,不是组件,仅仅是包装元素。
4.4.2 优点
- 包裹需要遍历或者判断的内容;
- 提高代码可读性;
- 不会渲染,提高性能;
4.5 slot插槽
插槽,可以想像一下USB插槽,插线板插槽等,都是预留一些位置。
这里也一样,在项目中,有些结构一样,但是内容并不一样的时候,我们就可以用插槽预留位置,用啥插进去啥!
4.5.1 单插槽
预留定义:
使用:直接设置组件
// 自定义组件里
<view>这里是header</view>
<slot/>
<view>这里是footer</view>
<mycpns mycpnsstyle="red" age="18" name="大明星" bind:cpnsbutton="handlehomecpns">
<view>我是插入的slot</view>
</mycpns>
4.5.2 多插槽
- 预留插槽并命名
<view>这里是header</view>
<slot name="slot1"/>
<slot name="slot2"/>
<view>这里是footer</view>
- 开启多插槽开关
Component({
options:{
multipleSlots: true
}
})
- 插入组件
// 插槽的位置是受定义时候的影响,不受这里先后顺序的影响
<mycpns mycpnsstyle="red" age="18" name="大明星" bind:cpnsbutton="handlehomecpns">
<view slot="slot2">我是插入的slot2</view>
<view slot="slot1">我是插入的slot1</view>
</mycpns>
5. 其他知识
5.1 wx:for遍历
- wx:for遍历可以遍历数组、字符串、数字;
- 遍历时,默认下标名为index,当前项名为item;
- 可以自定义命名index和item;
data: {
movies: ['晚秋', '大空头', '华尔街之狼']
},
// 遍历数组
<view wx:for="{{movies}}">{{item}}</view>
// 遍历字符串“students”
<view wx:for="students">{{item}}</view>
// 遍历数字9 : 0-8
<view wx:for="{{9}}">{{item}}</view>
// wx:for-item="新item名"
//wx:for-index="新index名'
// 二维数组,第一层数组的item重命名为newItem
<block wx:for = "{{list}}" wx:for-item="newItem">
<view wx:for="{{newItem}}">
{{item}}
</view>
</block>
- wx:key我们一般给数组设置一个这个key,这样当数组变化时,若是新增数据,则新增元素,把新增的元素插入位置即可,优化性能。
// 通常设置下标为key
wx:key="index"
5.2 组件的隐藏/显示
//wx:if隐藏时,组件不存在,没有创建
wx:if = "{{false}}"
//hidden 隐藏时,组件存在
hidden = "{{true}}"
so,根据实际开发时,组件隐藏和显示的频率来确定用哪个更好!
5.3 逻辑判断
wx:if 如果
wx:elif 此外,如果
wx:else 其他所有情况
5.4 页面跳转
5.4.1 navigator组件
<navigator url="页面路径">保留当前页面跳转</navigator>
5.4.2 wx.方法跳转
wx.navigateTo({
url: `/pages/cardetail/cardetail`
})
5.5 箭头函数
箭头函数中的this可以一层一层向上查找,非箭头函数不能向上查找,需要自己获取对象;
5.6 全局变量
//app.js
globalData:{
name:'myname',
age:18
}
//使用方法
const app = getApp();
console.log(app.globalData.name);
5.7 导入
import导入:不能递归导入
include导入:可以递归导入,不能导入template模版/wxs
动手写起来才是硬道理!