UNi-APP

小程序

1. 起步 | uniapp - 黑马优购

插件

图片裁剪组件(更改自 作者: 因吹丝挺的图片裁剪兼容版) - DCloud 插件市场图片裁剪组件
tmt-calendar - DCloud 插件市场日历组件

API

wx.setNavigationBarTitle修改导航栏的字体
wx.showToast显示消息提示框,
uni.getSystemInfo()获取当前手机型号的信息
uni.setStorageSync('kw', JSON.stringify(存储的值))存入本地存储
JSON.parse(uni.getStorageSync('kw') || [])取出本地存储, 没有的话返回一个空数组
uni.previewImage()点击图片放大效果
uni.setTabBarBadge({})设置 tabBar 的数字徽标
uni.chooseAddress()小程序自带的地址栏
uni.openSetting({})让用户打开授权页面
uni.chooseImage(OBJECT)从本地相册选择图片或使用相机拍照。
uni.pageScrollTo()将页面滚动到目标位置
uni.createSelectorQuery().select('#dissan').boundingClientRect().exec()获取元素节点信息
uni.createAnimation()uniapp的动画

// 点击图片放大效果  
uni.previewImage({
	// urls: this.imgMsg,
	current:indexx,
	urls:['../../static/back.png'],
	longPressActions: {
        itemList: ['发送给朋友', '保存图片', '收藏'],
        success: function(data) {
            console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片')
        },
        fail: function(err) {
            console.log(err.errMsg)
        }
	}
})

uni.showToast({
    title: '数据请求失败!',
    duration: 1500,
    icon: 'none',
})

uni.setTabBarBadge({
    index: 2, // 索引
    text: this.total + '' // text 必须是个字符串, 不能是数字
})

// 获取节点信息
const query = uni.createSelectorQuery().in(this)
	query.select('#id').boundingClientRect(data =>{
	this.addHeight = (data.height-196) + 'px'
}).exec()

// 页面的滚的位置
uni.createSelectorQuery().select('#dissan').boundingClientRect(function(rect){
		uni.pageScrollTo({ duration:200,scrollTop:9999999 })
}).exec()
// 获取键盘的高度
 <input type="text"	@focus="huqoujioa"	>
     
  	huqoujioa(e){
         // 键盘高度
         let { height } = e.detail // 获取键盘高度
         this.xunigao = `${height}px`
         // 键盘高度end
 	},

组建

// uniapp 内置组件。 跳转到响应的网页
<web-view :src="urls"></web-view>

2

属性名类型默认值说明试用
navigationBarTitleTextString字符串导航栏标题文字内容导航栏
navigationBarBackgroundColorHexColor#000000导航栏背景色, 如#00000, 只支持16进制导航栏
navigationBarTextStyleStringwhite导航栏标题颜色 , 仅支持black/white, 黑和白导航栏
backgroundColorHexColor#fffff窗口的背景色窗口背景
backgroundTextStyleStringdark下啦 loading 的样式,仅支持dark/light窗口背景
enablePullDownRefreshBooleanfalse是否开启下啦刷新页面效果
onReachBottomDistanceNumber50页面上拉触底时页面底部距离页面效果
backgroundColor16进制16进制#292d38刷新的背景色
"navigationStyle": "custom",是否有顶部导航栏页面
{
  "globalStyle": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "黑马优购",
    "navigationBarBackgroundColor": "#C00000",
    "backgroundColor": "#FFFFFF"
  }
}

注意

模拟器不能 百分之百 还原 , 有时候会有问题, 所以,一切以真机为主

了解目录结构

JSON文件简介

app.json

sitemap.josn

类似于 PC 页面的是 SEO 优化

"action": "allow", // 允许被微信的爬虫工具搜索到
"action": "disallow", // 不允许被微信的爬虫工具搜索到

关闭后会报一个警告需要在 project.config.json 文件中的 ckeckSitemap: false 就可以 了

app.json

pages:[ // 谁在第一行, 谁就是第一个项目首页
	"pages/list/list" // 添加了一个 list 文件
] -- 文件存放路径
window :{  // -- 全局定义页面的背景色
      "navigationBarBackgroundColor": "#000000" // 设置页面的背景颜色
}
style: 'v2' 默认使用最新的样式
sitemapLocation: 'sitemap.json'

页面的JSON 文件中的覆盖 其他JSON 文件中的内容

  "navigationBarBackgroundColor": "#000000" // 设置页面的背景颜色

组件 XXML === HTML

试图内容

view
//	类似于div

<navigator url="地址" />
// 相当于 a 标签

scroll-view
// <seroll-view scroll-y> -y纵向滚动 -x横向滚动
//	可滚动的区域,常用于滚动效果 
例子: {
  <scroll-view class="ass" scroll-top="0" scroll-y>  // 固定宽度需要 , scroll-top 是滚动的距离
  	<view>sdasdasd</view>
  </scroll-view>
}

swiper 和 swiper-item
//	轮播图的容器, 里面的item是组件
    swiper 还有其他相应的属性, 如下: indicator-dots 是否显示面板指示点
    indicator-dots // 加上小圆点
    indicator-color 指示点颜色
    indicator-active-color 激活指示点颜色
    autoplay 是否自动切换
    interval 自动切换时间间隔
    circular 是否采用衔接滑动
	:duration 总共耗费多少秒
    current: 0当前显示第几个索引
text
 // selectable 属性可以长按复制
// 相当于 span ,只有 text 组件支持复制功能
<text selectable> XXX<text>

rich-text
// 富文本组件, 字符串渲染成 html 结构
<rich-text nodes="<h1 style='cloor: red'>'dadsadad'</h1>"></rich-text>

button
// 按钮组件, 通过open-type 属性调用微信提供的各个功能
// type 为颜色 , size 为大小, , plain 镂空的按钮

<image
// 图片组件, 默认大小300, 240
// mode 属性对图片进行调整
    mode值 说明
    scaleToFill // (默认值)缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image元素
    aspectFit //缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来可以完整的将    图片显示出来
    aspectFill // 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来图片通常    旨在水平或垂直方向是完整的,另一个方向将发生截取
    widthFix   // 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
    heightFix // 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
<swiper :indicator-dots="true" // 显示小圆点
		:autoplay="true" // 是否自动切换
		interval="3000" //自动切换时间3000隔
		duration="1000" // 总共好诗多久
		:circular="true",  //是否采用衔接滑动
		current="1" // 当前显示第几个	
		@animationfinish="" // 动画结束的事件
>

常用的事件

小程序的API

事件监听

以 on 开头, 用来监听某些事件的触发p

wx = window

事件绑定

类型绑定方式事件描述
tapbindtap 或 bind:tap手指触摸后马上离开,类似于click
inputbindinput 或 bind:input文本框的输入事件
changebindchange 或 bind:change状态改变时触发, 主要用于复选框
<view bintap="事件名称"> 按钮 </>

事件对象的属性列表

在获取事件时, 用 e. 来获取下列的事件

属性类型说明
typeString时间的类型
timeStampInteger页面打开到触发事件的毫米数
targetObject触发事件的组件的一些属性值集合
currentTargetObject当前组件的一些属性值集合
detailObject额外的信息
tochesArray触摸事件, 当前停留在屏幕中的触摸点信息的数据
changeTochesArray触摸事件, 当前变化的触摸点信息的数组

target 和 currentTarget 的区别

target 是触发事件的源头组件, 而 currentTarget 则是当前事件所绑定的组件。 
举例
	<view class="outer-view" bindtap="outerHandler">
		<button type="primary"> 按钮 </>
	</view>
// 当点击内部按钮时, 点击事件以冒泡的方式向外进行扩散, 也会触发外层 view 的 tap 的处理函数。此时对于外层 view 来说: 
//	e.target 指向触发事件的源头组件, 因此, e.target 是内部的按钮( button )组件
//	e.currentTarget 指向是当前触发事件的那个组件, 因此e.currentTarget 是当前 view 组件

wxss 模板样式

rpx 单位, @import 导入 。 rem 和 em 不能再小程序中使用

rpx 就是把一个屏幕大小分成750份,然后会在底层自动进行来渲染适配

爱疯6 中 1rpx === 0.5px || 1px === 2rpx

750rpx = 375px = 750物理像素
1rpx = 0.5px = 1物理像素

样式导入

@import '地址'; // 导入css 文件

全局配置文件,在pages中

app.json

pages // 记录当前小程序的所有页面的存放路径
window // 全局设置小程序窗口的外观
tabBar // 设置小程序底部 的 tabBar 效果
style // 是否启用新版组件样式

属性名类型默认值说明试用
navigationBarTitleTextString字符串导航栏标题文字内容导航栏
navigationBarBackgroundColorHexColor#000000导航栏背景色, 如#00000, 只支持16进制导航栏
navigationBarTextStyleStringwhite导航栏标题颜色 , 仅支持black/white, 黑和白导航栏
backgroundColorHexColor#fffff窗口的背景色窗口背景
backgroundTextStyleStringdark下啦 loading 的样式,仅支持dark/light窗口背景
enablePullDownRefreshBooleanfalse是否开启下啦刷新页面效果
onReachBottomDistanceNumber50页面上拉触底时页面底部距离页面效果
backgroundColor16进制16进制#292d38刷新的背景色
"navigationStyle": "custom",是否有顶部导航栏页面
{
  "globalStyle": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "黑马优购",
    "navigationBarBackgroundColor": "#C00000",
    "backgroundColor": "#FFFFFF"
  }
}

js操作

函数,在 js 文件中与 data 平级】

e.target.dataset.名

实现 tabBar 的导航栏

{
  "pages":[ // 只要是 tabBar 的页面, 必须是,最前面的, 否则 不能支持
    "pages/home/index", // 新建的导航栏页面
    "pages/home1/index",
    "pages/home2/index",
    "pages/index/index",
    "pages/logs/logs"
  ],
  "tabBar": { // 若要加入导航栏, 必须配置 tabBar 最少俩个 最多6个
      "selectedColor": "#C00000", // 选中的标题颜色
    "list": [{
      "pagePath": "pages/home/index", // 路径
      "text": "首页", // 名称
      "iconPath": "/images/tabs/home.png",   // 未选中的icon 图标
      "selectedIconPath": "/images/tabs/home-active.png" // 选中的icon 图标
    },{
      "pagePath": "pages/home1/index",
      "text": "首页",
      "iconPath": "/images/tabs/home.png",
      "selectedIconPath": "/images/tabs/home-active.png"
    }]
  }
}

小程序的 created 生命周期, 类似于

onLoad(){ // 页面一加载, 就 立刻请求数据
	
}

页面导航

就是页面之间的跳转, 编程式导航, 和声明式导航

声明式导航就是通过 <navigator> 来进行跳转, 编程式导航是调用 API j进行页面跳转

声明式导航

// 跳转到 tabBar 页面
<navigator url="跳转地址" open-type="switchTab"> </> 	
//  open-type 跳转的方式 的 switchTab 是必须跳转

// 跳转到 非tabBar 页面
<navigator url="/pages/info/indo" > 跳转到非tabBar页面</navigator> // 其中这个 open-type 可以忽略 

// 后腿的导航
<navigator delta="1" open-type="navigateBack" > 返回上一页</navigator> // 其中这个 open-type 可以忽略 

// 导航传参
<navigator url="/paage/info?name=zs&age=20" open-type="switchTab"> </> 
//  在跳转页面地址后,进行页面的跳转传参 、 在跳转的地址后进行 ? 拼接字符串 (&) 符号进行传参的拼接 

编程式导航

跳转到 tabBar 页面

属性类型是否必选说明
urlstring需要跳转到 tabBar 页面的路径, 路径后不能带参数
sucessfuncation接口调用成功的回调函数
failfuncation接口调用失败的回调函数
completefuncation接口调用结束的回掉函数(成功或者失败都会执行)
// 页面结构
<butten bindtap="gotoMessage"> 跳转的 tabBAr  页面 </>

// 通过编程式导航, 跳转的 tabBAr 页面
gotoMessage() {
    wx.switchTab ({
		url: '地址'
    })
}


// 页面结构
<butten bindtap="gotoMessage"> 跳转的 非tabBAr   页面 </>

// 通过编程式导航, 跳转的 非tabBAr 页面
gotoMessage() {
    wx.navigateTo({
		url: '地址'
    })
}

// 编程式导航进行跳转传参
<butten bindtap="gotoMessage"> 跳转的 非tabBAr   页面 </>

gotoMessage() {
    wx.navigateTo({
		url: '/page/info?name=zs&ganer=男'
    })
}

在切换页面传参后, 需要接受到当前传到页面的值时, 需要在生命周期中的 onLoad 中的生命周期函数,进行监听页面加载

onLoad: funcation(options){  // options 是跳转过来的接受的数据
	this.setData({
		data: options // 此时就是将 options 里的数据传入到 data 函数中
	})
}

后退机制

// 页面结构
<butten bindtap="gotoMessage"> 后退导航 </>

// 跳转完成后, 进行后退机制
gotoMessage() {
    wx.navigateBack() // 里面不需要写任何东西
}

页面事件

下啦刷新

我们开启下拉刷新通过 enablePullDownRefresh 改为 true 即可。

// 如果我们想要监听下啦刷新时通过 onPullDownRefresh 函数进行下啦刷新的监听
onPullDownRefresh {
    log('出发了 message 页面的下啦刷新')
}

// 通过下啦刷新后, 页面不会自动关闭, 我们需要
wx.stopPullDownRefresh() // 来自动关闭 这个下啦刷新的按钮

onPullDownRefresh { //通过下啦刷新后
    log('出发了 message 页面的下啦刷新')
    wx.stopPullDownRefresh()
}

上拉触底事件, 例如于上拉刷新

"onReachBottomDistance": "190" 在 JSON 配置文件中进行配置, 此方法是监听距离底部区域还有多少时, 进行上拉刷新的页面。

uni-app 
	//	在 pages.json 中的页面的 style 属性中添加 onReachBottomDistance
	 {
      "path": "goods_list/goods_list",
      "style": {
        "onReachBottomDistance": 150,
         "enablePullDownRefresh": true,  // 开启下啦刷新
         "backgroundColor": #ffffff  // 开启下啦刷新的颜色
      }

// 如果我们想要监听上啦刷新时通过 onReachBottom 函数进行上拉刷新的监听
  onReachBottom() {
	log('出发了 message 页面的上啦刷新')
  },
// 通过下啦刷新后, 页面不会自动关闭, 我们需要
wx.stopPullDownRefresh() // 来自动关闭 这个下啦刷新的按钮

onPullDownRefresh {
    log('出发了 message 页面的下啦刷新')
    wx.stopPullDownRefresh()
}

wx.showLoading(Object object ) 是通过 展示微信的轻提示

wx.hideLoading(Object object ) 是通过关闭微信的轻提示

// 调用 wx 的轻提示来显示
fetColors() {
	wx.showLoading({title: '数据加载中。。。。'}) // 来展示 loading 的效果
	wx.request({
		complate: () =>{ // 接口无论成功还是失败, 都会调用此函数
			wx.hideLoading() // 来关闭 loading 的效果
		}
	})
}
// 上拉触底进行节流的操作

案例

<!--pages/contant/contant.wxml-->
<text>pages/contant/contant.wxml</text>
<view wx:for="{{contant}}" 
wx:key="index"
style="width: 100%; height: 195rpx;background-color: rgba({{item}});">{{item}}</view>


// js 事件
 /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getDataPOST()
  },
  getDataPOST(){
    wx.showLoading({
      title: 'title',
    })
   wx.request({
     url: 'https://www.escook.cn/api/color',
     method:"get",
     success:({data:res}) =>{
       this.setData({
        contant: [...this.data.contant, ...res.data]
       })
     },
     complete: ()=>{
       wx.hideLoading()
     }
   })
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    this.getDataPOST()
  },

生命周期

小程序分为俩个生命周期:

应用生命周期 => 是指小程序从启动 => 运行 => 销毁的过程

页面生命周期 => 每个页面的加载 => 渲染 => 销毁的过程

这么是生命周期呢?

//生命周期函数: 是由小程序框架提供的内置函数, 会伴随着生命周期, 自动按次序执行

//生命周期函数的作用: 允许程序员在特定的时间点,执行某些特定的操作。例如, 页面刚加载的时候,可以在 onLoad 生命周期函数中初始化的数据。

//注意: 生命周期强调的是时间段, 生命周期函数强调的是时间点

应用生命周期

小程序的应用生命周期函数需要在 app.js 中进行声明。 示例代码如下 :

前台就是, 小程序在当前手机展示的页面

后台就是, 小程序不在当前手机展示的页面

// app.js 文件
App({
    // 小程序初始化完成时, 执行此函数, 全局只触发一次。可以做一些初始化的工作
    onLaunch(options){
        // 此方法可以在小程序初始化的时候,获取一些本地存储的数据
    }
    
    // 小程序启动, 或从后台进入前台显示时触发
    onShow(options){}

	// 小程序从前台进入后台实触发
	onHide(){}

	// 页面不存在的生命周期
	onPageNotFound()
})

页面生命周期

小程序的页面生命周期函数需要在页面的 .js 文件 中进行声明, 示例代码如下:

生命周期参数描述
show组件页面被展示时候
hide组件页面被隐藏的时候执行
resizeObject Size组件所在页面尺寸发生变化时候

// 页面的 .js 文件
Page({
	// 监听页面加载, 一个页面只调用一次
	onLoad(options){}
    
    // 监听页面显示
    onShow(){}
     
	// 监听页面初次渲染完成,一个页面只调用一次
     onReady() {
    	wx.setNavigationBarTitle({ // 页面第一次加载完成之后, 修改导航栏的文字颜色
   	   		title: "案例详情"
  		})
 	} 

	// 监听页面隐藏
	onHide(){}

	// 监听页面卸载, 一个页面只吊用一次
	onUnload(){
        getCurrentPages() // 获取当前页面的信息
    }

	// 通过下啦刷新后, 页面不会自动关闭, 我们需要
    onPullDownRefresh { //通过下啦刷新后
        log('出发了 message 页面的下啦刷新')
        wx.stopPullDownRefresh() // 来自动关闭 这个下啦刷新的按钮	
    }

	// 上拉刷新加载下一页数据
	onReachBottom(){}

	// 滚动的事件
	onPageScroll(event){}

	// 监听分享的
	onShareAppMessage(res) {
		return {
			title: "XXX的小程序",
			path: "/pages/home/home",
			imageUrl: "http://ss.iifaka.com/uploads/20220824/b07d91b05259c1b961ee7a2ed4a9229c.png",
		}
	},
})

UNI-APP

初始化项目

全局配置 page.json

属性类型描述
globalStyle设置默认页面的窗口表现
pages设置页面对的路径一级窗口表现
easycom组件自动引入规则
tabBar设置底部 tab 的表现
condition启动模式配置
subPackages分包预下载
preloadRule分包预下载规则

"pages" : [ 
		// 这里是路由配置
	],
	"tabBar": { // 这里就是配置tabbar的地方
		"color": "#8a8a8a", // 导航栏字体颜色
		"selectedColor": "#d4237a", // 选中后字体的颜色
		"borderStyle": "black", // 底部的border颜色,只能是“black”或者“white”
		"backgroundColor": "#ffffff", // 底部背景颜色
		"list": [{
				"pagePath": "pages/index/index", // 页面路径
				"text": "首页", // 底部导航文字,
				"iconPath": "static/logo.png", // 没选中前的图标路径
				"selectedIconPath": "static/logo.png" // 选中后的图标路径
			},
			{
				"pagePath": "pages/mine/mine",
				"text": "我的",
				"iconPath": "static/logo.png",
				"selectedIconPath": "static/logo.png"
			}
		]
	}

分包

// 独立分包谁都不可以引用,也是谁都不能引用

    	"subPackages": [
			{"root": "subpages",
			"name": "p1",
			"pages": [
			{
                 "path" : "news/news",
                    "style" :   {
                    "navigationBarTitleText": "",
                    "enablePullDownRefresh": false
                }
                }
            ],
              "independent": true // independent 是开启独立分包
            }
		
    // app.json
    	"preloadRule":{ // 分包预下载的功能
            "pages/contact/contact":{ // 触发分包预下载的页面路径
                // network 表示在指定网络模式下进行预下载
                // 可选值: all(不限制网络) 和 wifi (仅 wifi 模式下进行预下载)
                // 默认值: wifi
                "network": "all",
                // packages 表示进入页面后, 预下载哪些分包。
                // 可以通过 root 或 name 指定预下载哪些分包
                "packages": ["pkgA"]
            }
	}

// 安装 vuex
	// 1. 在store.js  导入 Vue 和 Vuex
    import Vue from 'vue'
    import Vuex from 'vuex'
    import moduleCart from './module/cart'

    // 2. 将 Vuex 安装为 Vue 的插件
    Vue.use(Vuex)

    // 3. 创建 Store 的实例对象
    const store = new Vuex.Store({
      // TODO:挂载 store 模块
      modules: { moduleCart },
    })

    // 4. 向外共享 Store 的实例对象
    export default store	

// 在main.js 中

┌─components            uni-app组件目录
│  └─comp-a.vue         可复用的a组件
├─pages                 业务页面文件存放的目录
│  ├─index
│  │  └─index.vue       index页面
│  └─list
│     └─list.vue        list页面
├─static                存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─main.js               Vue初始化入口文件
├─App.vue               应用配置,用来配置小程序的全局样式、生命周期函数等
├─manifest.json         配置应用名称、appid、logo、版本等打包信息
└─pages.json            配置页面路径、页面窗口样式、tabBar、navigationBar 等页面类信息
#1.5 把项目运行到微信开发者工具

giit 管理项目

  1. 在项目根目录中新建 .gitignore 忽略文件,并配置如下:

# 忽略 node_modules 目录
/node_modules
/unpackage/dist

注意:由于我们忽略了 unpackage 目录中仅有的 dist 目录,因此默认情况下, unpackage 目录不会被 Git 追踪

此时,为了让 Git 能够正常追踪 unpackage 目录,按照惯例,我们可以在 unpackage 目录下创建一个叫做 .gitkeep 的文件进行占位

  1. 打开终端,切换到项目根目录中,运行如下的命令,初始化本地 Git 仓库:

git init
  1. 将所有文件都加入到暂存区:

git add .
  1. 本地提交更新:

git commit -m "init project"

#1.6.2 把项目托管到码云

  1. 注册并激活码云账号( 注册页面地址:注册 - Gitee.com

  2. 生成并配置 SSH 公钥

  3. 创建空白的码云仓库

  4. 把本地项目上传到码云对应的空白仓库中

配置网络请求

请参考 @escook/request-miniprogram 的官方文档进行安装、配置、使用

官方文档:@escook/request-miniprogram - npm

// 由于平台的限制,小程序项目中不支持 axios,而且原生的 wx.request() API 功能较为简单,不支持拦截器等全局定制的功能。因此,建议在 uni-app 项目中使用 @escook/request-miniprogram 第三方包发起网络数据请求。

最终,在项目的 main.js 入口文件中,通过如下的方式进行配置:

import { $http } from '@escook/request-miniprogram'

uni.$http = $http
// 配置请求根路径
$http.baseUrl = 'https://www.uinav.com'

// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
  uni.showLoading({
    title: '数据加载中...',
  })
}

// 请求完成之后做一些事情
$http.afterRequest = function () {
  uni.hideLoading()
}
 async getSwiperList(){
          const { data: res } = await uni.$http.get('/api/public/v1/home/swiperdata')
          if (res.meta.status !== 200) {
                 return uni.showToast({
                   title: '数据请求失败!',
                   duration: 1500,
                   icon: 'none',
                 })
               }
           this.swiperList = res.message
      }

配置uni-app 分包

分包可以减少小程序首次启动时的加载时间

  1. 在项目根目录中,创建分包的根目录,命名为 subpkg

  2. pages.json 中,和 pages 节点平级的位置声明 subPackages 节点,用来定义分包相关的结构:

"subPackages": [
    {
      "root": "subpkg", // 分包的名称
      "pages": [] // 分包的页面
    }
  ]

封装一个 uni。showToasr 方法 ,是请求失败的提示

当数据请求失败之后,经常需要调用 uni.showToast({ /* 配置对象 */ }) 方法来提示用户。此时,可以在全局封装一个 uni.$showMsg() 方法,来简化 uni.showToast() 方法的调用。具体的改造步骤如下:

uni.$showMsg = function (title = '数据加载失败!', duration = 1500) {
  uni.showToast({
    title,
    duration,
    icon: 'none',
  })
}

// 使用
async getSwiperList() {
   const { data: res } = await uni.$http.get('/api/public/v1/home/swiperdata')
   if (res.meta.status !== 200) return uni.$showMsg()
   this.swiperList = res.message
}

配置 VueX

  1. 在项目根目录中创建 store 文件夹,专门用来存放 vuex 相关的模块

  2. store 目录上鼠标右键,选择 新建 -> js文件,新建 store.js 文件:

  3. .在 store.js 中按照如下 4 个步骤初始化 Store 的实例对象

    // 1. 在store.js  导入 Vue 和 Vuex
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    // 2. 将 Vuex 安装为 Vue 的插件
    Vue.use(Vuex)
    
    // 3. 创建 Store 的实例对象
    const store = new Vuex.Store({
      // TODO:挂载 store 模块
      modules: {},
    })
    
    // 4. 向外共享 Store 的实例对象
    export default store
  4. main.js 中导入 store 实例对象并挂载到 Vue 的实例上:

    // 1. 导入 store 的实例对象
    import store from './store/store.js'
    
    // 省略其它代码...
    
    const app = new Vue({
      ...App,
      // 2. 将 store 挂载到 Vue 实例上
      store,
    })
    app.$mount()

创建 vuex 模块

store 目录上鼠标右键,选择 新建 -> js文件,创建购物车的 store 模块,命名为 cart.js

  1. cart.js 中,初始化如下的 vuex 模块:

    export default {
      // 为当前模块开启命名空间
      namespaced: true,
    
      // 模块的 state 数据
      state: () => ({
        // 购物车的数组,用来存储购物车中每个商品的信息对象
        // 每个商品的信息对象,都包含如下 6 个属性:
        cart: [],
      }),
    
      // 模块的 mutations 方法
      mutations: {},
    
      // 模块的 getters 属性
      getters: {},
    }
  2. store/store.js 模块中,导入并挂载购物车的 vuex 模块,示例代码如下:

    import Vue from 'vue'
    import Vuex from 'vuex'
    // 1. 导入购物车的 vuex 模块
    import moduleCart from './cart.js'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      // TODO:挂载 store 模块
      modules: {
        // 2. 挂载购物车的 vuex 模块,模块内成员的访问路径被调整为 m_cart,例如:
        //    购物车模块中 cart 数组的访问路径是 m_cart/cart
        m_cart: moduleCart,
      },
    })
    
    export default store

vue怎么用, uni-app 怎么用

Mixins === 自定义组件的 - behaviors

注意:当我们一个代码, 需要在其他地方一起引用的时候, 我们可以用到 Mixins

此时可以使用 Vue 提供的 mixins 特性,提高代码的可维护性。

  1. 在项目根目录中新建 mixins 文件夹,并在 mixins 文件夹之下新建 tabbar-badge.js 文件,用来把设置 tabBar 徽标的代码封装为一个 mixin 文件:

    import { mapGetters } from 'vuex'
    
    // 导出一个 mixin 对象
    export default {
      computed: {
        ...mapGetters('m_cart', ['total']),
      },
      onShow() {
        // 在页面刚展示的时候,设置数字徽标
        this.setBadge()
      },
      methods: {
        setBadge() {
          // 调用 uni.setTabBarBadge() 方法,为购物车设置右上角的徽标
          uni.setTabBarBadge({
            index: 2,
            text: this.total + '', // 注意:text 的值必须是字符串,不能是数字
          })
        },
      },
    }
  2. 修改 home.vuecate.vuecart.vuemy.vue 这 4 个 tabBar 页面的源代码,分别导入 @/mixins/tabbar-badge.js 模块并进行使用:

    // 导入自己封装的 mixin 模块
    import badgeMix from '@/mixins/tabbar-badge.js'
    
    export default {
      // 将 badgeMix 混入到当前的页面中进行使用
     mixins:[mixinName,SSSSmixinName],
      // 省略其它代码...
    }

底部支付的模块

基于 uni-ui 提供的 GoodsNav 组件来实现商品导航区域的效果

  1. 在 data 中,通过 optionsbuttonGroup 两个数组,来声明商品导航组件的按钮配置对象:

判断是开发模式还是生产模式

if(process.env.NODE_ENV === 'development'){
    log('开发环境')
}  else {
    log('生产环境')
}


// 判断平台
#ifdef H5

#endif

安装 view-ui

npm i uview-ui

// 在main.js 中进行添加
    import uView from 'uview-ui'
    Vue.use(uView)

// 在 app.vue 
	@import 'uview-ui/index.scss'
// 在 uni.scss 引入
	@import 'uview-ui/theme.scss'

// 在 page.json 中, 按需引入
	{
    "easycom": {
        // 下载安装的方式需要前面的"@/",npm安装的方式无需"@/"
        // 下载安装方式
        "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
        // npm安装方式
        // "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
    }
}

XXXXXXXXXXXXXXXX

XXXXXXXX

XXXXXXXX

XXXXXXXX

XXXXXXXX

XXXXX1XXX

XXXXXXXX

XXXXXXXX

XXXXXXXXX1XXXXXXX

XXXXXXXX

小程序

1. 起步 | uniapp - 黑马优购

API

wx.setNavigationBarTitle修改导航栏的字体
wx.showToast显示消息提示框,
uni.getSystemInfo()获取当前手机型号的信息
uni.setStorageSync('kw', JSON.stringify(存储的值))存入本地存储
JSON.parse(uni.getStorageSync('kw') || [])取出本地存储, 没有的话返回一个空数组
uni.previewImage()点击图片放大效果
uni.setTabBarBadge({})设置 tabBar 的数字徽标
uni.chooseAddress()小程序自带的地址栏
uni.openSetting({})让用户打开授权页面
uni.chooseImage(OBJECT)从本地相册选择图片或使用相机拍照。
uni.pageScrollTo()将页面滚动到目标位置
uni.createSelectorQuery().select('#dissan').boundingClientRect().exec()获取元素节点信息

// 点击图片放大效果  
uni.previewImage({
        current:i , // 当前展示的图片索引
        urls: this.Asrray.map(item => {  // 把图片的数组返回出去
          return item.url
        })
   })

uni.setTabBarBadge({ // 底部导航栏徽标文字
    index: 2, // 索引
    text: this.total + '' // text 必须是个字符串, 不能是数字
})


// 页面的滚的位置
uni.createSelectorQuery().select('#dissan').boundingClientRect(function(rect){
		uni.pageScrollTo({ duration:200,scrollTop:9999999 })
}).exec()

组建

// uniapp 内置组件。 跳转到响应的网页
<web-view :src="urls"></web-view>

注意

模拟器不能 百分之百 还原 , 有时候会有问题, 所以,一切以真机为主

了解目录结构

JSON文件简介

app.json

project.config.json

项目配置文件

setting 保存了相关编译的配置, 例如打开 es6 的模板
projectname 保存的是项目名称
appid 保存的小程序账号id

sitemap.josn

类似于 PC 页面的是 SEO 优化

"action": "allow", // 允许被微信的爬虫工具搜索到
"action": "disallow", // 不允许被微信的爬虫工具搜索到
    
关闭后会报一个警告需要在 project.config.json 文件中的 ckeckSitemap: false 就可以 了

页面的.json配置文件

app.json

pages:[ // 谁在第一行, 谁就是第一个项目首页
	"pages/list/list" // 添加了一个 list 文件
] -- 文件存放路径
window :{  // -- 全局定义页面的背景色
      "navigationBarBackgroundColor": "#000000" // 设置页面的背景颜色
}
style: 'v2' 默认使用最新的样式
sitemapLocation: 'sitemap.json'

页面的JSON 文件中的覆盖 其他JSON 文件中的内容

  "navigationBarBackgroundColor": "#000000" // 设置页面的背景颜色

WXSS === CSS

// 微信新增了 rpx 的尺寸单位, 他将会自动的进行, 尺寸不同的变化。
app.wxss 是全局的css样式, 页面的wxss文件,是只支持自己也面的css 文件样式

// 支持
.class 和 #id
element 元素选择器
并集选择器, 后代选择器
::after 和 ::before 等伪类选择器

js文件

app.js // 是整个小程序项目的入口文件, 通过App() 函数来启动整个小程序
页面的.js 文件 // 是通过调用 Page() 函数来创建并运行页面
普通的.js 文件 // 是通过功能模块文件, 用来封装公共的函数或者属性提供页面使用

组件 XXML === HTML

试图内容

view
//	类似于div

<navigator url="地址" />
    <navigator url="跳转地址" open-type="switchTab"> </> 	
// 相当于 a 标签

scroll-view
// <seroll-view scroll-y> -y纵向滚动 -x横向滚动
//	可滚动的区域,常用于滚动效果 
例子: {
  <scroll-view class="ass" scroll-top="0" scroll-y>  // 固定宽度需要 , scroll-top 是滚动的距离
  	<view>sdasdasd</view>
  </scroll-view>
}

swiper 和 swiper-item
//	轮播图的容器, 里面的item是组件
    swiper 还有其他相应的属性, 如下: indicator-dots 是否显示面板指示点
    indicator-dots // 加上小圆点
    indicator-color 指示点颜色
    indicator-active-color 激活指示点颜色
    autoplay 是否自动切换
    interval 自动切换时间间隔
    circular 是否采用衔接滑动
	:duration 总共耗费多少秒
    current: 0当前显示第几个索引
text
 // selectable 属性可以长按复制
// 相当于 span ,只有 text 组件支持复制功能
<text selectable> XXX<text>

rich-text
// 富文本组件, 字符串渲染成 html 结构
<rich-text nodes="<h1 style='cloor: red'>'dadsadad'</h1>"></rich-text>

button
// 按钮组件, 通过open-type 属性调用微信提供的各个功能
// type 为颜色 , size 为大小, , plain 镂空的按钮

<image
// 图片组件, 默认大小300, 240
// mode 属性对图片进行调整
    mode值 说明
    scaleToFill // (默认值)缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image元素
    aspectFit //缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来可以完整的将    图片显示出来
    aspectFill // 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来图片通常    旨在水平或垂直方向是完整的,另一个方向将发生截取
    widthFix   // 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
    heightFix // 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
<swiper :indicator-dots="true" // 显示小圆点
		:autoplay="true" // 是否自动切换
		interval="3000" //自动切换时间3000隔
		duration="1000" // 总共好诗多久
		:circular="true",  //是否采用衔接滑动
		current="1" // 当前显示第几个	
		@animationfinish="" // 动画结束的事件
>

Mustache 语法 , 差值表达式

// index.wxml
// 在小程序中无论是绑定文本, 还是绑定属性都是使用 message 语法
	<view> {{message}} </view>
	<view> {{message * 100}} </view> // 进行算数运算
	<image src="{{ message }}" />
    <view>  {{message === 'string' ? 4 : 9}} </view>  // 进行三元表达式
// index.js
	data:{
		message: 'hello word'
	}

常用的事件

小程序的API

事件监听

以 on 开头, 用来监听某些事件的触发p

wx = window

同步API

特点1:以 Sync 结尾的 API 都是同步 API
特点2:同步 API 的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
举例: wx.setStorageSync('key', 'value') 向本地存储中写入内容

异步 API

特点:类似于 jQuery 中的 $.ajax(options) 函数,需要通过 success、fail、complete 接收调
用的结果
举例: wx.request() 发起网络数据请求,通过 success 回调函数接收数据

事件绑定

类型绑定方式事件描述
tapbindtap 或 bind:tap手指触摸后马上离开,类似于click
inputbindinput 或 bind:input文本框的输入事件
changebindchange 或 bind:change状态改变时触发, 主要用于复选框
<view bintap="事件名称"> 按钮 </>

事件对象的属性列表

在获取事件时, 用 e. 来获取下列的事件

属性类型说明
typeString时间的类型
timeStampInteger页面打开到触发事件的毫米数
targetObject触发事件的组件的一些属性值集合
currentTargetObject当前组件的一些属性值集合
detailObject额外的信息
tochesArray触摸事件, 当前停留在屏幕中的触摸点信息的数据
changeTochesArray触摸事件, 当前变化的触摸点信息的数组

target 和 currentTarget 的区别

target 是触发事件的源头组件, 而 currentTarget 则是当前事件所绑定的组件。 
举例
	<view class="outer-view" bindtap="outerHandler">
		<button type="primary"> 按钮 </>
	</view>
// 当点击内部按钮时, 点击事件以冒泡的方式向外进行扩散, 也会触发外层 view 的 tap 的处理函数。此时对于外层 view 来说: 
//	e.target 指向触发事件的源头组件, 因此, e.target 是内部的按钮( button )组件
//	e.currentTarget 指向是当前触发事件的那个组件, 因此e.currentTarget 是当前 view 组件

bindtap 语法格式

因为小程序中没有,形参和实参。 所以小程序以 data-* 来编写, 具体请看下方

定义一个事件处理函数 , 他与 data 函数平级
例如:
<button bindtap='Click' type="primary"> 按钮 </>

// 事件传值用 data-info="{{值}}" , 以下实例传了个2, 切记 加上 {{}} 为数字, 无为字符串。 且 info 可以为任何字母, 可以有无数个, 打印出来的为, 一个对象。 此为事件传参 
<button bindtap='chuanzhi' data-info="{{2}}"  type="primary"> 按钮 </>  
	// data-* 的花括号是以数字, 不包裹是字符串

//js代码
Page({
  data:{
    info: 1
  },
    Click(e){
      // console.log(e.target.dataset.info);
      this.setData({  // 来修改 data 的数据
        info: this.data.info + e.target.dataset.info  //e.target.dataset 是相当于 js 的形参
      })
    }
})

bindinput 语法格式

index.wxml
	<input value='{{ss}}' bindinput="inputhandle"> </> 
// 通过 bindinput 来响应input 的事件, 里面的value 为 data 中的变量

index.js
	Page({
        inputhandle(e) { // 通过 e.detail.value 来拿到输入的数值
            log(e.detail.value)
        }
    })

条件渲染

wx:if=""
wx:elif=""
wx:else
// 或者 hidden
    hidden 属性, true 为隐藏, false 为显示
// 相当于
v-if , v-elif, v-else

// 如若一次性要渲染多个标签, 可以用 block 进行渲染, 他只是一个容器
<block wx:if="{{true}}">
 	<view> aa </>
 	<view> bb </>
</>	

总结
wx:if 和 hidden 的区别?
    wx:if // 以动态创建和移除元素的方式, 控制元素的展示和隐藏, 直接删除dom 节点,频繁切换
    hidden // 以切换样式的方式,(display: none/block), 控制元素的显示和隐藏, 在dom元素上显示。
    相当于, v-if === wx:if 和 v-show  ==== hidden

for 循环

wx:for=“{{ 数组的名字 }}” wx:key="id", 对应 vue 中的 :key

如若要更改索引和 item 项,则需要用到 wx:for-index="idx" ; wx:for-item="itemName"

<view wx:for=“{{ 数组的名字 }}” wx:key="index">
	索引是: {{ index }}, item 项是 {{ item }}
</>

// 如果 不想用 index 或者 item 的话
<view wx:for="{{arr}}" wx:for-index="idx" wx:for-item="itemName">
    // index 替换成了 idx  , itemName 替换成了 item

wxss 模板样式

rpx 单位, @import 导入 。 rem 和 em 不能再小程序中使用

rpx 就是把一个屏幕大小分成750份,然后会在底层自动进行来渲染适配

爱疯6 中 1rpx === 0.5px || 1px === 2rpx

750rpx = 375px = 750物理像素
1rpx = 0.5px = 1物理像素

样式导入

@import '地址'; // 导入css 文件

window

全局配置文件,在pages中

app.json

pages // 记录当前小程序的所有页面的存放路径
window // 全局设置小程序窗口的外观
tabBar // 设置小程序底部 的 tabBar 效果
style // 是否启用新版组件样式

属性名类型默认值说明试用
navigationBarTitleTextString字符串导航栏标题文字内容导航栏
navigationBarBackgroundColorHexColor#000000导航栏背景色, 如#00000, 只支持16进制导航栏
navigationBarTextStyleStringwhite导航栏标题颜色 , 仅支持black/white, 黑和白导航栏
backgroundColorHexColor#fffff窗口的背景色窗口背景
backgroundTextStyleStringdark下啦 loading 的样式,仅支持dark/light窗口背景
enablePullDownRefreshBooleanfalse是否开启下啦刷新页面效果
onReachBottomDistanceNumber50页面上拉触底时页面底部距离页面效果
backgroundColor16进制16进制#292d38刷新的背景色
"navigationStyle": "custom",是否有顶部导航栏页面
{
  "globalStyle": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "黑马优购",
    "navigationBarBackgroundColor": "#C00000",
    "backgroundColor": "#FFFFFF"
  }
}

js操作

函数,在 js 文件中与 data 平级】

e.target.dataset.名

修改响应式数据

需要用到this.setData() , 函数

// 例子
this.setData({
	count : this.data.count + 1 // count 是要响应式数据
})

事件传参

<button bindtap="brnHandler" data-info='{{2}}'> dasda </> 
// info 代表参数的名字, 2 为参数的值, {{}} 里面为数字, 要想为字符串则不加{{}}

全局的 tabBar

最少包含俩个, 最多包含5个

实现 tabBar 的导航栏

{
  "pages":[ // 只要是 tabBar 的页面, 必须是,最前面的, 否则 不能支持
    "pages/home/index", // 新建的导航栏页面
    "pages/home1/index",
    "pages/home2/index",
    "pages/index/index",
    "pages/logs/logs"
  ],
  "tabBar": { // 若要加入导航栏, 必须配置 tabBar 最少俩个 最多6个
      "selectedColor": "#C00000", // 选中的标题颜色
    "list": [{
      "pagePath": "pages/home/index", // 路径
      "text": "首页", // 名称
      "iconPath": "/images/tabs/home.png",   // 未选中的icon 图标
      "selectedIconPath": "/images/tabs/home-active.png" // 选中的icon 图标
    },{
      "pagePath": "pages/home1/index",
      "text": "首页",
      "iconPath": "/images/tabs/home.png",
      "selectedIconPath": "/images/tabs/home-active.png"
    }]
  }
}

网络请求

小程序只能请求 https 开头的网络请求

如果要用到合法域名,先将域名配置到信任列表中

微信小程序管理后台 => 开发 => 开发设置 => 服务器域名 => 修改 request 合法域名

// get 请求
wx.request({
	url: '地址',
	method: 'GET',
	data:{
		name: 'ZW', age: 22
	},
	success:(res) =>{ // 成功之后的回掉函数
		log(res)
	}
})

// POST 请求
wx.request({
	url: '地址',
	method: 'POST',
	data:{
		name: 'ZW', age: 22
	},
	success:(res) =>{ // 成功之后的回掉函数
		log(res)
	}
})

详细请看下面 uniAPP

import { $http } from '@escook/request-miniprogram'

uni.$http = $http
// 配置请求根路径
$http.baseUrl = 'https://www.uinav.com'

// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
  uni.showLoading({
    title: '数据加载中...',
  })
}

// 请求完成之后做一些事情
$http.afterRequest = function () {
  uni.hideLoading()
}
const {data: res} = await uni.$http.get('地址')

封装的请求

import { $http } from '@escook/request-miniprogram'
uni.$http = $http
$http.baseUrl = 'https://www.escook.cn'
// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
  uni.showLoading({ title: '数据加载中...', })
}
// 请求完成之后做一些事情
$http.afterRequest = function (options) {
  console.log(options)
  const { data, statusCode, errMsg } = options
  if(statusCode === 200){ 
    uni.hideLoading()
    return data
  } else{
      uni.showToast({
          title: errMsg,
         duration: 1500,
           icon: 'none',
    })
    // return Promise.reject((new Error(errMsg)))
  }
  uni.hideLoading()
}
uni.$showMsg = function(title = '数据请求失败!', duration = 1500) {
  uni.showToast({
    title,
    duration,
    icon: 'none'
  })
}






import request from './request'
export const api = (a) =>{
  return uni.$http.get('/apsi/get', query: a)
}

async qing(){
	await api(a)
}

小程序的 created 生命周期, 类似于

onLoad(){ // 页面一加载, 就 立刻请求数据
	
}

页面导航

就是页面之间的跳转, 编程式导航, 和声明式导航

声明式导航就是通过 <navigator> 来进行跳转, 编程式导航是调用 API j进行页面跳转

声明式导航

// 跳转到 tabBar 页面
<navigator url="跳转地址" open-type="switchTab"> </> 	
//  open-type 跳转的方式 的 switchTab 是必须跳转

// 跳转到 非tabBar 页面
<navigator url="/pages/info/indo" open-type="navigator" > 跳转到非tabBar页面</navigator> // 其中这个 open-type 可以忽略 

// 后腿的导航
<navigator delta="1" open-type="navigateBack" > 返回上一页</navigator> // 其中这个 open-type 可以忽略 

// 导航传参
<navigator url="/paage/info?name=zs&age=20" open-type="switchTab"> </> 
//  在跳转页面地址后,进行页面的跳转传参 、 在跳转的地址后进行 ? 拼接字符串 (&) 符号进行传参的拼接 

编程式导航

跳转到 tabBar 页面

属性类型是否必选说明
urlstring需要跳转到 tabBar 页面的路径, 路径后不能带参数
sucessfuncation接口调用成功的回调函数
failfuncation接口调用失败的回调函数
completefuncation接口调用结束的回掉函数(成功或者失败都会执行)
// 页面结构
<butten bindtap="gotoMessage"> 跳转的 tabBAr  页面 </>

// 通过编程式导航, 跳转的 tabBAr 页面
gotoMessage() {
    wx.switchTab ({
		url: '地址'
    })
}


// 页面结构
<butten bindtap="gotoMessage"> 跳转的 非tabBAr   页面 </>

// 通过编程式导航, 跳转的 非tabBAr 页面
gotoMessage() {
    wx.navigateTo({
		url: '地址'
    })
}

// 编程式导航进行跳转传参
<butten bindtap="gotoMessage"> 跳转的 非tabBAr   页面 </>

gotoMessage() {
    wx.navigateTo({
		url: '/page/info?name=zs&ganer=男'
    })
}

在切换页面传参后, 需要接受到当前传到页面的值时, 需要在生命周期中的 onLoad 中的生命周期函数,进行监听页面加载

onLoad: funcation(options){  // options 是跳转过来的接受的数据
	this.setData({
		data: options // 此时就是将 options 里的数据传入到 data 函数中
	})
}

后退机制

// 页面结构
<butten bindtap="gotoMessage"> 后退导航 </>

// 跳转完成后, 进行后退机制
gotoMessage() {
    wx.navigateBack() // 里面不需要写任何东西
}

页面事件

下啦刷新

我们开启下拉刷新通过 enablePullDownRefresh 改为 true 即可。

// 如果我们想要监听下啦刷新时通过 onPullDownRefresh 函数进行下啦刷新的监听
onPullDownRefresh {
    log('出发了 message 页面的下啦刷新')
}

// 通过下啦刷新后, 页面不会自动关闭, 我们需要
wx.stopPullDownRefresh() // 来自动关闭 这个下啦刷新的按钮

onPullDownRefresh { //通过下啦刷新后
    log('出发了 message 页面的下啦刷新')
    wx.stopPullDownRefresh()
}

上拉触底事件, 例如于上拉刷新

"onReachBottomDistance": "190" 在 JSON 配置文件中进行配置, 此方法是监听距离底部区域还有多少时, 进行上拉刷新的页面。

uni-app 
	//	在 pages.json 中的页面的 style 属性中添加 onReachBottomDistance
	 {
      "path": "goods_list/goods_list",
      "style": {
        "onReachBottomDistance": 150,
         "enablePullDownRefresh": true,  // 开启下啦刷新
         "backgroundColor": #ffffff  // 开启下啦刷新的颜色
      }

// 如果我们想要监听上啦刷新时通过 onReachBottom 函数进行上拉刷新的监听
  onReachBottom() {
	log('出发了 message 页面的上啦刷新')
  },
// 通过下啦刷新后, 页面不会自动关闭, 我们需要
wx.stopPullDownRefresh() // 来自动关闭 这个下啦刷新的按钮

onPullDownRefresh {
    log('出发了 message 页面的下啦刷新')
    wx.stopPullDownRefresh()
}

wx.showLoading(Object object ) 是通过 展示微信的轻提示

wx.hideLoading(Object object ) 是通过关闭微信的轻提示

// 调用 wx 的轻提示来显示
fetColors() {
	wx.showLoading({title: '数据加载中。。。。'}) // 来展示 loading 的效果
	wx.request({
		complate: () =>{ // 接口无论成功还是失败, 都会调用此函数
			wx.hideLoading() // 来关闭 loading 的效果
		}
	})
}
// 上拉触底进行节流的操作

案例

<!--pages/contant/contant.wxml-->
<text>pages/contant/contant.wxml</text>
<view wx:for="{{contant}}" 
wx:key="index"
style="width: 100%; height: 195rpx;background-color: rgba({{item}});">{{item}}</view>


// js 事件
 /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getDataPOST()
  },
  getDataPOST(){
    wx.showLoading({
      title: 'title',
    })
   wx.request({
     url: 'https://www.escook.cn/api/color',
     method:"get",
     success:({data:res}) =>{
       this.setData({
        contant: [...this.data.contant, ...res.data]
       })
     },
     complete: ()=>{
       wx.hideLoading()
     }
   })
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    this.getDataPOST()
  },

生命周期

小程序分为俩个生命周期:

应用生命周期 => 是指小程序从启动 => 运行 => 销毁的过程

页面生命周期 => 每个页面的加载 => 渲染 => 销毁的过程

这么是生命周期呢?

//生命周期函数: 是由小程序框架提供的内置函数, 会伴随着生命周期, 自动按次序执行

//生命周期函数的作用: 允许程序员在特定的时间点,执行某些特定的操作。例如, 页面刚加载的时候,可以在 onLoad 生命周期函数中初始化的数据。

//注意: 生命周期强调的是时间段, 生命周期函数强调的是时间点

应用生命周期

小程序的应用生命周期函数需要在 app.js 中进行声明。 示例代码如下 :

前台就是, 小程序在当前手机展示的页面

后台就是, 小程序不在当前手机展示的页面

// app.js 文件
App({
    // 小程序初始化完成时, 执行此函数, 全局只触发一次。可以做一些初始化的工作
    onLaunch(options){
        // 此方法可以在小程序初始化的时候,获取一些本地存储的数据
    }
    
    // 小程序启动, 或从后台进入前台显示时触发
    onShow(options){}

	// 小程序从前台进入后台实触发
	onHide(){}

	// 页面不存在的生命周期
	onPageNotFound()
})

页面生命周期

小程序的页面生命周期函数需要在页面的 .js 文件 中进行声明, 示例代码如下:

生命周期参数描述
show组件页面被展示时候
hide组件页面被隐藏的时候执行
resizeObject Size组件所在页面尺寸发生变化时候

// 页面的 .js 文件
Page({
	// 监听页面加载, 一个页面只调用一次
	onLoad(options){}
    
    // 监听页面显示
    onShow(){}
     
	// 监听页面初次渲染完成,一个页面只调用一次
     onReady() {
    	wx.setNavigationBarTitle({ // 页面第一次加载完成之后, 修改导航栏的文字颜色
   	   		title: "案例详情"
  		})
 	} 

	// 监听页面隐藏
	onHide(){}

	// 监听页面卸载, 一个页面只吊用一次
	onUnload(){
        getCurrentPages() // 获取当前页面的信息
    }

	// 通过下啦刷新后, 页面不会自动关闭, 我们需要
    onPullDownRefresh { //通过下啦刷新后
        log('出发了 message 页面的下啦刷新')
        wx.stopPullDownRefresh() // 来自动关闭 这个下啦刷新的按钮	
    }

	// 上拉刷新加载下一页数据
	onReachBottom(){}

	// 滚动的事件
	onPageScroll(event){}

	// 监听分享的
	onShareAppMessage(res) {
		return {
			title: "XXX的小程序",
			path: "/pages/home/home",
			imageUrl: "http://ss.iifaka.com/uploads/20220824/b07d91b05259c1b961ee7a2ed4a9229c.png",
		}
	},
})

WXS脚本 // 不能用于回掉函数, 不能调用js 文件 和 API

wxs 就是 wxs 的脚本

wxs 不支持es6 以上的语法形式, 支持 var 定义变量, 普通函数。

wxs 遵循了 CommonJS 规范, module 对象、 require() 对象、 module.exports 对象

内嵌 wxs 脚本

// 类似于 wxs 的标签, 就像 jasascript 代码可以编写在html 中的文件

<view> {{m1.toUpper(username)}} </>

<wxs module='m1'> // 必写
   module.exports.toUpper = funcation(str){
    	return str.toUpperCase() // 将字符串转换成大写的
} 
</>

外联的 wxs 脚本

需要新建一个 .wxs 的脚本文件

funcation toLower(str){
	retutn toLowerCase() // 将字符串转换成小写的
}

module.exports ={ // 向外导出来, 这个函数
    toLower: toLower // 因为 微信不支持 es6 的语法 所以不能简写,只能写全了
}

// 使用
<view> {{m2.toLower(country)}}</>

<wxs src="../../" module="m2"> </> // module 必写, 路径必须是相对路径

小程序组件

自定义组件

创建组件

新建 components => test 文件夹 下在新建 Component 就会创建好 .js .json .wxml .wxss

// 在组件中的 .json 文件中需要设置 "compontent": true 属性。 此方法是说明他是个组件

局部引入

// 在 页面的 .json 文件中引入组件
{
	"usingComponents" : {
		"my-test1": "/compontents/test1/test1"
	}
}

// 再页面中的 .wxml 文件中,使用组件
<my-test1> </>

全局引入

// 在 app.json 文件中, 引入组件
{
	"pages":[],
	"window":{},
	"usingComponents":{
		'my-text2': "/compontents/test1/test1"
	}
}

// 再页面中的 .wxml 文件中,使用组件
<my-text2> </>

组件中的文件区别

组件带有样式隔离, but 只隔离 class 选择器,id/标签等其他选择器不隔离

// 在组件中的 .json 文件中需要设置 "compontent": true 属性。 此方法是说明他是个组件

// 组件中的 .js 文件中调用的是 Compontent() 函数, 页面的是要写入 Page 函数中

// 组件的事件处理函数需要定义到的 methods 节点中, 页面的是写入与data 平级的即可

如果想要组件里的样式和页面的样式互相影响,执行以下操作

// 在组件的 .js 文件中新增以下配置
Compontent({
	options:{
		stylesolation: 'isolared' // isolared 是组件与页面互不影响
     
	}
})

//或者在 .json 中新增如下配置
{
	"styleIsolation": "isolated"
}

// isolated : 启用样式隔离,使用class 类名互不影响

//apply-shared : 表示 页面的样式可以影响到组件, 但组件不可以影响到页面 

//shared : 表示,可以相互影响
// 组件的 data 数据,和 vue 的 data 函数一样
// 组件的 methods 和 vue 的 methods 一样

组件的 properties 属性传递方法, 类似于组建之间的传值

Compontent({ 
    properties:{ // 这个方法不和 view 一样可读不可写。他是可读可写的
        max:{
            type: Number, // 定义的数据类型
            vaalue: 10 // 属性的默认值
        }
    }
})

// 使用
<my-test1 max="10" > </>

// 组件的获取
<view> {{max}} </>

// js 文件
<button bindtap="showInfo">showInfo</button>
showInfo() {
      this.setData({
        max: this.properties.max - 1
      })
 }

数据监听器和 watch 一样

Compontent({ 
    observers:{ // 监听器
       '字段A, 字段B': funcation(字段A的新值, 字段B的新值){
       	
       }
    }
})

// 监听对象的属性变化
Compontent({ 
    observers:{ // 监听器
       '对象.属性A, 对象.属性A': funcation(属性A的新值, 属性B的新值){
       		// 为属性 A 赋的新值,就会触发
        	// 为属性 B 赋的新值,就会触发
        	// 整个对象变化, 也会触发
       }
    }
})

// 如果要监听对象下面所有的属性变化可以用 ** 来代替, 任何属性变化都会,执行
observers:{
	'rgb.**': funcation(obj) {
        this.setDate({
            fullColor:`${r}, ${g},${b}`
        })
    }
}

纯数字字段

就是 当一个变量不会在 页面中展示, 也不会传递给其他组件,仅仅在当前页面中展示时候,此时可以把此变量存入到 纯数据字段

可以提升性能

// 在 Compontent 构造器中的 options 节点中, 指定 pureDataPattern 为一个正则表达式, 字段名符合这个正则将会成为纯数字字段

Compontent({
    options:{
        // 指定所有以 _开头的变量,存储为纯数字字段
        pureDataPattern: /^_/
    },
    data:{
       a: true, // 普通数据字段
       _b: true // 纯数字字段
    }
})

组件的生命周期

注意小程序的生命周期要全部写入 lifetimes: {} 对象中

生命周期函数参数描述说明
created在组件刚刚被创建时执行, 组件的 DOM 树没有被执行
attached在组件实例进入页面节点树时执行, 就是页面的组件刚被放入节点树的时候
ready在组件在制图层布局完成后执行, 就是组件刚被渲染完成
moved在组件实例被移动到节点树另一个位置时执行, 组件的位置被移动
detached在组件实例被从页面节点树移除时执行, 组件实例在页面移除时候
errorObject Error每当组件方法抛出错误时执行, 只要报错就会触发
// created 生命周期是组件刚刚被创建好
	// 此时不能创建 setData 。通常在这个生命周期中, 只能应用该组建内的 this 添加一些自定义的属性字段
// attached, 是指组件完全初始化完毕, 进入页面节点树后, attached 生命周期函数会被触发
	// 此时, this.data 已被初始化完毕了。此时,可以干很多事情,例如发送请求

组件所在页面的生命周期, 写入组件页面

生命周期参数描述
show组件页面被展示时候
hide组件页面被隐藏的时候执行
resizeObject Size组件所在页面尺寸发生变化时候

组件所在页面的生命周期函数, 需要定义在 pageLifetimes 节点中, 示例代码’

Compontent({
    pageLifetimes:{
        hide(){},
        show() {},
        resize() {}
    }
})

插槽

和 vue 一样

// 组件
	<view>
        <slot> </>
     </>
// 页面调用的组件

// 如果要启用多个插槽时,需要在 当前的 js 文件进行如下配置
Compontent({
	options:{
        multipleSlorts: true // 此方法可以定义多个 slot 插槽
    }
})
// 然后就可以, 定义了
<slot name="before" > </> // 只需要加个名字就好

<view slot="before"> </>

组件通信

// 属性绑定
	用于父组件向子组建的指定属性设置数据, 仅能设置 JSON 兼容的数据
    
// 事件绑定
    用于子组建向父组件传递数据, 可以传递任意数据

// 获取组件实例
    父组件可以通过 this.selectCompontent() 获取子组建实例对象, 这样就可以直接访问子组建的任意数据和方法
// 父组件向子组建传值, 和vue 一样
<view class="saview">父组件中的值 {{count}}</view>

<my-text6 :count="{{count}}"></my-text6>

// js
properties:{ // 接收
    count:{
      type: Number
    }
 },

子组建更改了,父组建传来的值, 但要在父组件中回显

// 事件绑定用于实现子向父传值, 可以传递任何类型的数据。
	在父组件的 js 文件中, 定义一个函数,这个函数即将通过自定义事件的形式, 传递给子组建
    在父组件的 wxml 文件中, 通过自定义事件的形式,将步骤1 中定义的函数引用, 传递给子组建
    在子组建中, 通过调用 this.triggerEvent('自定义事件名称', {'/* 参数对象 */'}),将数据发到父组件
    在父组件的 js 中, 通过 e.detail 获取子组建传递过来的数据    

代码

 // 父组件
	// js
	syncCount(e){ // e 就是子组建,传递来的值
        log(e.detail) // e.detail 就是子传递来的值
        this.setDat({
            count: e.detail.value
        })
    }

	// wxml
	<my-test5 count="{{count}}" bind:sync="syncCount" ></> // 通过自定义事件的方式

// 子组件
	// js
	addCount(){
        this.setData({count: this.properties.count + 1}) // 子组建通父组件的值
        // 触发自定义事件, 将数值同步给父组件
        this,triggerEvent('sync', {value: this.properties.count}) // sync 就是父组件传递来的自定义事件, value 是把修改的值,传递给父组件
    }

父子组件之间的通信 - - 实例

// 可在父组件里调用 this.selectComponent("id或class选择器"),获取子组建的实力对象,从而直接访问子组建的任意数据和方法。调用一个选择器,例如  this.selectComponent(".my-compontent")

代码

// wxml 结构
<my-test3 count="{{count}}" bind:sync="syncCount" class="custmA" id="cA"></>

<butten bindtap="getChild"> 获取子组建的实例 </>


// js 结构
getChild(){
	const child = this.selectComponent(".custmA") // 也可以传递id 选择器
    child.setDate({count: child.properties.count + 1}) // 调用子组建 setData 的方法
    child.子组建的方法() // 调用子组建的 addCount 方法
}

// 	切记子组建要写如 bind:sync="syncCount" 来进行双向绑定
addCount(){
        this.setData({count: this.properties.count + 1}) // 子组建通父组件的值
        // 触发自定义事件, 将数值同步给父组件
        this,triggerEvent('sync', {value: this.properties.count}) // sync 就是父组件传递来的自定义事件, value 是把修改的值,传递给父组件
    }

自定义组件的 - behaviors

behaviors 是小程序中, 用于实现组件间代码共享的特性, 类似于 Vue.js 中的 ‘mixins’

behaviors 里的东西都是共享的。behaviors 可以引用 behaviors ,组件也可以引用多个behaviors

创建

// 调用 Behavior(Object object) 方法即可创建一个共享的 begavior 实例对象, 给所有组件共享

// 先创建一个 behaviors 的文件,my-behaviors.js 文件

module.exports = Behavior({
	data:{
        username: 'zs'
    },
    properties:{} // 属性节点
    methods: {} // 方法
})

导入

// js
const myBehavior = 	require('地址')

Compontent:{
    behavior: [myBehavior]
}

//在 wxml 文件中和普通的用法没区别
可用节点类型是否必填描述
propertoesObject Map同组建的属性
dataObject同组建的数据
meethodsObject同自定义组件的方法
behaviorsString Array引入其他的 behavior
createdFuncation生命周期函数
attachedFuncation生命周期函数
readyFuncation生命周期函数
movedFuncation生命周期函数
detachedFuncation生命周期函数

使用 npm 包

不支持依赖于 Node.js 内置库的包

不支持依赖于 浏览器内置对象的包

不支持依赖于C++ 插件的包

Vant Weap的 开源协议是 MIT 的协议, MIT协议是可以商用的 @1.3.3

// 快速 上手
https://vant-ui.github.io/vant-weapp/#/quickstart

1. npm init -y

2.npm i @vant/weapp@1.3.3 -S --production

引入 Vant 组件

// 在app.json或index.json中引入组件,详细介绍见快速上手。
"usingComponents": {
  "van-button": "@vant/weapp/button/index"
}

定义CSS 变量

element {
	--main-bg-color: 222 // 定义了个 css 变量。 
    // 引用 css 变量
    color: var(--main-bg-color)
}

// 定制 Vant  的主题颜色
 	// app.wxss
	page({
        // 定制警告按钮的背景色和边框颜色
        --button-danger-background-color: #000000; //背景色
        --button-danger-border-color: #222222; 	// 边框颜色
        // 如何查看其他的主题颜色呢, 可以通过 Vant 自定义主题中的配置文件查找
    })

小程序 API Promise 化

// 因为小程序官方提供的 API 都是基于回调函数实现的, 例如网络请求 的 API 

wx.request({
	method: '',
	url: '',
	data:{},
	success:() => {}, // 成功的回掉函数
	fail: () => {}, // 失败的回掉函数
	complate: () => {} // 请求完成的会掉函数
})

// 那么我们需要把 异步的 API 改成 Promise 化

1. 安装 npm i --save miniprogram-api-promise@1.0.4 - 下载完成,我们不能直接使用,而是需要再次重新构建npm包 
// 因为 npm 会把包下载到 node-module 文件下, 小程序无法识别。 我们需要吧 包移动到 miniprogram_npm 下

2. 先删除掉 miniprogram_npm 文件, 点击 工具 => 构建 npm 包

3.
	// app.js 文件下
	import { promisifyAll } from 'miniprogram-api-promise'
	const wxp = wx.p = {} // 将小程序的对象, 挂载到 wx.p 空对象上
	promisifyAll(vx, wxp) // wx 是顶级对象, 把对象挂载到 wxp

4.  // 如何调用呢?
	<van-button type="danger" bindtap="getInfo"> vant按钮</>
	
	async getInfo() {
        const {data: res} = await wx.p.request({
            method: "GET", url: '地址', data:{name: 'za', age: 20}
        })
        log(res)
    }

全局数据共享

又叫: 状态管理, 是为了解决组件之间数据共享的问题,

好比 vuex

// mobx-miniprogram 是用来创建 Store 实例对象
// mobx-miniprogram-bindings 用来 Store 中的共享数据或者方法, 绑定到组件或者页面中使用
1.npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1

2.// 创建 Store 实例对象,并将其导出 
	// 创建 sotre 文件 => 	store.js
    import { observable, action } from 'mobx-miniprogram'
    export const store =  observable({
      nameA: 1, // 创建了俩个共享的数据
      nameB: 2,
        // 定义计算属性, 必须以 get 开头, 他是只读的
      get sum() {
          return this.numA + this.numB	
      },
      // actions 方法, 用来修改 store 中的数据
      // 若要修改 action 的值, 则可以利用 action 的会掉函数
       updateNum1: action(function(stop)){
          this.numA += step         
       }
    })
    
    
// 在页面中绑定 Store 的成员
    // 页面文件
    {{nameA}} + {{nameB}} = {{sum}}
    <van-button type="danger" bindtap="nameAJIA" data-setup="{{1}}">nameA + 1</van-button>	
    
	// 页面的 .js 文件
    import { createStoreBindings } from 'mobx-miniprogram-bindings'
	import { store } from '地址'
	Page({
        nameAJIA(e){
   		     this.updateNum1(e.target.dataset.setup) // updateNum1 是挂载的内容个
 	     },
        onLoad(){
            this.storeBindings = createStoreBindings(this, { // 把他绑定到一个方法中
                store, // 数据源
                fields: ['numA', 'numB', 'sum'], // store 里面的变量,绑定过来
                actions: ["updateNum1"] // store 绑定过来的方法
            })
        },
        onUnload: funcation(){ // 页面卸载	后清除这个方法
        	this.storeBindings.destroyStoreBindings()
  		}
    })
    
   

分包

可以优化启动时间, 多协作共同开发时可以更好的解耦协作

//小程序可以把包,分成一个主包,若干个分包。 
//主包: 一般由当前项目的启动页面或TabBar页面, 以及一些公共资源
//分包: 只包含当前分包的页面或者私有资源

//当用户进入页面,先下载主包, 在进入到其他页面才会下载页面
//切记: 所有包的大小不能超过 16MB ,单个分包的大小不能超过 2MB

配置分包

// 打包原则

小程序是按 subpackages 的配置进行分包的, subpackages 之外的目录将被打包到主包

主包也有自己的 pages (就是最外层的 pages 字段)

tabBar 页面必须在主包内

分包之间不能互相嵌套

// 引用原则

主包无法引用分包的私有资源

分包之间不能相互引用

分包可以引用主包内的公共资源

独立分包

独立分包, 本质上也是一个包, 正常情况下只能通过主包才能进入分包。 而独立分包,可以独立于主包和其他页面的分包进行单独运行

// 独立分包谁都不可以引用,也是谁都不能引用

"subpackages": [
    {
      "root": "pkgA",
      "name": "p1",
      "pages": [
        "pages/cat/cat",
        "pages/dog/dog"
      ]
    },
    {
      "root": "pkgB",  // 分包
      "name": "p2", // 分包名称
      "pages": [ // 分包的页面
        "pages/apple/apple"
      ],
      "independent": true // independent 是开启独立分包
    }
  ],

分包预下载

表示小程序在某个页面时候, 由框架自动预下载可能依赖的分包,从而提升进入分包页面的启动速度。

// app.json
    	"preloadRule":{ // 分包预下载的功能
            "pages/contact/contact":{ // 触发分包预下载的页面路径
                // network 表示在指定网络模式下进行预下载
                // 可选值: all(不限制网络) 和 wifi (仅 wifi 模式下进行预下载)
                // 默认值: wifi
                "network": "all",
                // packages 表示进入页面后, 预下载哪些分包。
                // 可以通过 root 或 name 指定预下载哪些分包
                "packages": ["pkgA"]
            }
	}

mo

import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from '../store/store'

behaviors:[storeBindingsBehavior],// 与 data 同级
  storeBindings:{
    store, // 数据源
    fields:{
      // nameA: () => store.nameA,
      // nameB: () => store.nameB,
      sum: 'sum'
    },
    actions:{
      // updateNum1: 'updateNum1'
 }

Vant

在自定义组件中使用 Vant Weapp 组件时,需开启, js 文件
styleIsolation: 'shared'

  options:{
    styleIsolation: 'shared'
  },
选项
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值