然后在vsc 里面就可以以wx-开头就会有提示了
alt + 上下箭头 移动代码
ctrl + alt + ↓ : 向下复制当前行
1.字符串和花括号之间一定不要存在空格,否则会导致识别失败
//以下是错误示范
<checkbox checked=" {{ischecked}}" ></checkbox>
MINA 原生框架
结构 | 传统web | 微信小程序 |
---|---|---|
结构 | HTML | WXML |
样式 | CSS | WCSS |
逻辑 | Javascript | Javascript |
配置 | JSON |
通过以上的对比,微信小程序多出了一层配置json
pages 页面文件
index 首页
logs 日志页面
utils 第三方的js库
app.js 项目的全局 入口文件
app.json 全局配置文件
app.wxss 全局样式配置
project.config.json 项目的配置文件 如appid
sitemap.json 微信索引配置文件
注: 配置app.js 的时候最好在微信开发工具里面配,会有提示
app.js 全局配置 包括小程序的所有 页面路径、界面表现、网络超时时间、底部tab等
//app.json
{
"pages":{
},
"window":{
}
}
可以在花括号中加入 表达式 – “语句”
表达式
指的是一些简单的 运算、数字运算、字符串拼接、逻辑运算。。。
语句
{{1+2}} //3
wx:if="{{true/false}}"
if, else , if else
wx:if
wx:elif
wx: else
hidden
什么场景下使用哪个
当标签不频繁切换显示 优先使用 wx:if
直接把标签从 页面结构移除
当标签频繁切换显示, 优先使用wx:hidden
通过控制样式 display
需要给input的标签绑定 input事件
绑定的关键字 bindinput
如何获取输入框的值
通过事件源对象来获取
e.detail.value
把输入框的值 赋值到data当中
不能直接
1.this.data.num= e.detail.value
2.this.num = e.detail.value
正确赋值:
this.setData({
num: e.detail.value
})
需要加入一个点击事件
<button bindtap="handletap" data-num="{{num}}">button>
bindtap(e){
//获取自定义属性 num
var num = e.currentTarget.dataset.num
//解构赋值
var {num} = e.currentTarget.dataset
}
规定屏幕宽为750rpx
iphone6屏幕宽度为375px
375px ==750rpx
假如存在一个设计稿440px 或者 page
440px = 750rpx
推算演变
page px = 750rpx
利用一个属性calc属性 css 和wxss都支持的属性
注意750和rpx不要留空格 符号两边要留
width:calc(750rpx * 100 / 375);
使用@import语句可以导入外联样式表,只支持相对路径。
@import “…/…/style/common.wxss”
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tugUbvA1-1643360178266)(C:\Users\Hg-huazai\AppData\Roaming\Typora\typora-user-images\image-20201214151713195.png)]
相对路径: 相对当前路径来说,从当前路径出发,
1.编辑器 vsc 插件easy less
在vs code 的设置中加入如下,配置 (p22 集)
"less.compile": {
"outExt": ".wxss"
}
重命名wxss文件为less 保存会自动生成wxss 文件
/*1.定义less变量*/
@color: pink;
text {
color: @color;
}
view:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OvpZmKFF-1643360178269)(C:\Users\Hg-huazai\AppData\Roaming\Typora\typora-user-images\image-20201214154113858.png)]
text:
1.只能嵌套text
2.长按可以复制(只有该标签有这个功能)
3.可以对大于号、小于号、回车、空格进行编码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BYr6cnJe-1643360178270)(C:\Users\Hg-huazai\AppData\Roaming\Typora\typora-user-images\image-20201214155055080.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1t2coU3j-1643360178271)(C:\Users\Hg-huazai\AppData\Roaming\Typora\typora-user-images\image-20201214165757766.png)]
1.图片存在默认的宽高 320 * 240
2.mode
3.小程序当中的图片 直接就支持 懒加载 lazy-load
1.lazy-load 会自己判断 当 图片 出现在 视口 上下 三屏的高度 之内的时候 自己开始加载图片
轮播图外层容器 swiper
每个轮播图项 swiper-item
swiper标签 存在默认样式
width 100%
height 150px image 也存在默认的宽高 320* 240
swiper 高度 无法实现由内容撑开
先找出了 原图的宽高 等比例 给swiper 定 宽高
image 的 mode=“widthFix”
swiper {
width: 100%;
height: calc(100vw * 325 / 1125);
}
image {
width: 100%;
}
导航组件 navigator
html
1.nodes 属性来实现
1.接收标签字符串, 常用
2.接收对象的数组
js
page ({
data: {
//1.标签字符串
html: 'hello
'
//2.对象数组
html: [
{
//1.div标签 name属性来指定
name: "div",
//2.标签上有哪些属性
attrs: {
class: "my_div",
style: "color: red;"
},
//3.子节点 children 要接收的数据类型和 nodes 第二种渲染方式的数据类型一致
children: [
{
name: 'p',
attrs: {},
//放文本
children: [
{
type: "text",
text: "hello"
}
]
}
]
}
]
}
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cQAZc76F-1643360178272)(C:\Users\Hg-huazai\AppData\Roaming\Typora\typora-user-images\image-20201215153642403.png)]
文档:https://developers.weixin.qq.com/miniprogram/dev/component/button.html
button 的开发功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qrOkZATv-1643360178273)(C:\Users\Hg-huazai\AppData\Roaming\Typora\typora-user-images\image-20201215154738195.png)]
客服功能: 需要去 微信公众平台(https://mp.weixin.qq.com/wxamp/home/guide?lang=zh_CN&token=771833294) -> 客服 -> 添加微信号
(https://developers.weixin.qq.com/miniprogram/dev/component/icon.html)
男
女
{{gender}}
//js
page({
data: {
gender: ''
},
handleChange(e){
//1.获取单选框中的值
let gender = e.detail.value;
//2.把值赋给 data 中的数据
this.setData({
//es6
gender
})
}
})
{{item.name}}
选中的水果{{checkboxlist}}
page ({
data: {
list: [
{id: 0,naem:"苹果", value: "apple"},
{id: 1, name: "梨", value: "grape"},
{id: 2, name: "香蕉", value: "bananer"},
],
checkedlist: [],
},
//复选框选中事件
handleItemChange(e){
//获取被选中的复选框的值
const checkedlist = e.datail.value;
//赋值
this.setData({
checkedlist
})
}
})
组件的回调函数放在methods:{}中
创建组件
跟目录下新增一个文件夹 “components”,再新建对应得文件夹,然后右击,点击新建Component;
此时的js文件并不是page了,而是:component
//组件的js文件
Component({
//组件的属性列表 (接收父向子传递的数据的)
properties: {
},
//数据的初始化
data: {
},
//组件的方法列表
methods: {
}
})
//json文件
{
"component": true, //当前文件是组件
"usingComponents": {} //引用其他自定义组件
}
声明组件
那个文件使用组件就在哪个文件的json声明
{
"usingComponents":{
//键值对
"组件吗": "组件路径"
"Tabs": "../../components/Tabs/Tabs" //相对路径,不用加后缀名
}
}
使用组件
//html
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isactive? 'active': ''}}"
bindtap="hanldeItemTap"
data-index="index"
>
{{item.name}}
view>
//js
Conponenst({
data:{
tabs: [
{id:0,name:'首页',isActive:true},
{id:1,name:'原创',isActive:fales},
{id:2,name:'分类',isActive:fales},
{id:3,name:'关于',isActive:fales},
]
},
methods: {
hanldeItemTap(e){
//获取索引
const {index} = e.currentTarget.dataset;
//获取data中的数组
// let {tabs} = this.data; 最好不要直接修改this.data的数据
//最严谨的做法,深拷贝一份 数组 再对这个数组的备份进行处理
let tabs = JSON.parse(JSON.stringify(this.data.tabs))
//循环数组
//[].forEach 遍历数组 遍历数组的时候修改了 v,也会导致原数组被改变
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false;)
//赋值
this.setData({
tabs
})
}
}
})
//小程序数组深拷贝
function copyArr(oldArr){
let newArr = [];
newArr = JSON.parse(JSON.stringify(oldArr));
return newArr;
}
父组件(页面) 向子组件 传递数据 通过 标签属性的方式来传递
子组件上进行接收
Component({
//里面存放的是 要从父组件中接收的数据 (把prpperties当成data使用就好)
properties: {
//要接收数据的名称
aaa: {
//type: 要接收的数据的类型
type: string,
//value 默认值(如果父组件没有传值的话,就使用该值)
value: ""
}
}
})
子向父传递数据 是通过事件的方式传递
在子组件的标签上加入一个 自定义事件
子组件的点击事件触发的时候
触发父组件的自定义事件 同时传递数据给 父组件
//this.triggerEvent("父组件自定义事件的名称",要传递的参数)
this.triggerEvent("itemChange",index)
components ({
methods: {
tabtap(e){
const {index} = e.currentTarget.detaset //假如index ==2
this.triggerEvent("itemChange",{index})
}
}
})
page ({
handleItemChang(e){
console.log(e.detail.index) //2
}
})
sole 标签 其实就是一个占位符 插槽
等到 父组件调用 子组件的时候 再传递 标签过来 最终 这些被传递的标签就会替换 slot 插槽 的位置
//子组件
父组件 直接 插标签 就可以替换sole了
全局的入口文件app.js
APP({
})
页面
Page({
})
组件
Component({
})
全局生命周期
APP({
//1.应用第一次启动的就会催发的事件
onLaunch(){
//在应用第一次启动的时候 获取用户个人的信息
console.log("onLaunch")
},
//2应用 被用户看到
onShow(){
console.log("onshow")
},
//3.应用 被隐藏
onHide(){
//暂停或者清除定时器
console.log("hide")
},
//4.应用代码 发生了报错的时候 就会触发
onError(err){
//在应用发生的代码报错的时候,收集用户的错误信息,通过异步请求 将错误的信息发送后台去
console.log(err)
},
//5.页面找不到就会催发
//应用第一次启动的时候, 如果找不到第一个入口页面 就会触发
onPageNotFound(){
console("onPageNotFound");
}
})
组件生命周期
查看控制台的storage 可查看缓存
先判断一下本地存储中有没有旧的数据
{当前时间戳,数据长什么样}
{time: Date.now(), data: [...]}
没有旧数据 直接发送新请求;
有旧的数据 同时 旧的数据也没有过期 就使用 本地存储中的旧数据即可
1.存储本地数据
getCates(){
request({
}).then(res=>{
this.Cates = res.data.message;
//把接口数据存入到本地存储中
wx.setStorageSync("cates, {time:Date.now(), data:this.Cates}")
})
}
2.获取本地存储中的数据
const Cates = wx.getStorageSync("cates");
if(!Cates){
//不存在 发送请求获取数据
this.getCates();
}
web中的本地存储 和 小程序中的本地存储的区别
打包原则:
引用原则
独立分包
独立分包的应用场景
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中,原因如下
独立分包配置
通过independent声明独立分包
独立分包引用原则
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源!例如:
分包预下载-配置分包的预下载
预下载分包的行为,会在进入指定的页面时触发,在APP.json 中,使用PreloadRule节点定义分包的预下载
分包预下载的限制
同一个分包中的页面享有共同的预下载大小限额2M例如
1.1开发文档->介绍(点击跳转微信公众平台宽网首页(https://mp.weixin.qq.com/))->开发->开发设置->服务器域名;
result.authSetting["scope.address"]
使用小程序的页面盏
获取当前的小程序的页面盏-数组 长度最大是10个页面
数组中 索引中最大的页面就是当前的页面
let pages = getCuttentPages(); //pages => 所有页面盏的数组
let currentPage = pages[pages.length-1]; //数组最大的索引;
一行超出显示省略号;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
多行显示省略号;
overflow: hidden;
display: -webkit-box; //必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。
-webkit-box-orient: vertical;//必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式
-webkit-line-clamp: 3; //用来限制在一个块元素显示的文本的行数
value.trim()
防抖 一般 输入框中 防止重复输入 重复发送请求
节流 一般 是用在页面上拉和下拉(上拉刷新、下拉加载)
pages {(
data:{
},
//定义全局的定时器
TimeId: -1,
//输入框的值改变 就会触发的事件
handleInput(e){
//1.获取输入框的值
const {value} = e.detail;
//2.检测合法性 (输入框去电两边空格是否有值)
if(!value.trem()){
//值不合法
return;
}
//清楚定时器
clearTimeout(this.TimeId);
//3.准备发送请求获取数据
this.TimeId = setTimeout(()=>{
this.qsearch(value); //发起请求
},1000)
}
)}