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()
// 获取键盘的高度
 
     
  	huqoujioa(e){
         // 键盘高度
         let { height } = e.detail // 获取键盘高度
         this.xunigao = `${height}px`
         // 键盘高度end
 	},

组建

// uniapp 内置组件。 跳转到响应的网页

2

属性名 类型 默认值 说明 试用
navigationBarTitleText String 字符串 导航栏标题文字内容 导航栏
navigationBarBackgroundColor HexColor #000000 导航栏背景色, 如#00000, 只支持16进制 导航栏
navigationBarTextStyle String white 导航栏标题颜色 , 仅支持black/white, 黑和白 导航栏
backgroundColor HexColor #fffff 窗口的背景色 窗口背景
backgroundTextStyle String dark 下啦 loading 的样式,仅支持dark/light 窗口背景
enablePullDownRefresh Boolean false 是否开启下啦刷新 页面效果
onReachBottomDistance Number 50 页面上拉触底时页面底部距离 页面效果
backgroundColor 16进制 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


// 相当于 a 标签

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

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

rich-text
// 富文本组件, 字符串渲染成 html 结构


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

 
  

常用的事件

小程序的API

事件监听

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

wx = window

事件绑定

类型 绑定方式 事件描述
tap bindtap 或 bind:tap 手指触摸后马上离开,类似于click
input bindinput 或 bind:input 文本框的输入事件
change bindchange 或 bind:change 状态改变时触发, 主要用于复选框
 按钮 

事件对象的属性列表

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

属性 类型 说明
type String 时间的类型
timeStamp Integer 页面打开到触发事件的毫米数
target Object 触发事件的组件的一些属性值集合
currentTarget Object 当前组件的一些属性值集合
detail Object 额外的信息
toches Array 触摸事件, 当前停留在屏幕中的触摸点信息的数据
changeToches Array 触摸事件, 当前变化的触摸点信息的数组

target 和 currentTarget 的区别

target 是触发事件的源头组件, 而 currentTarget 则是当前事件所绑定的组件。 
举例
	
		

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 // 是否启用新版组件样式

属性名 类型 默认值 说明 试用
navigationBarTitleText String 字符串 导航栏标题文字内容 导航栏
navigationBarBackgroundColor HexColor #000000 导航栏背景色, 如#00000, 只支持16进制 导航栏
navigationBarTextStyle String white 导航栏标题颜色 , 仅支持black/white, 黑和白 导航栏
backgroundColor HexColor #fffff 窗口的背景色 窗口背景
backgroundTextStyle String dark 下啦 loading 的样式,仅支持dark/light 窗口背景
enablePullDownRefresh Boolean false 是否开启下啦刷新 页面效果
onReachBottomDistance Number 50 页面上拉触底时页面底部距离 页面效果
backgroundColor 16进制 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(){ // 页面一加载, 就 立刻请求数据
	
}

页面导航

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

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

声明式导航

// 跳转到 tabBar 页面
  	
//  open-type 跳转的方式 的 switchTab 是必须跳转

// 跳转到 非tabBar 页面
 跳转到非tabBar页面 // 其中这个 open-type 可以忽略 

// 后腿的导航
 返回上一页 // 其中这个 open-type 可以忽略 

// 导航传参
  
//  在跳转页面地址后,进行页面的跳转传参 、 在跳转的地址后进行 ? 拼接字符串 (&) 符号进行传参的拼接 

编程式导航

跳转到 tabBar 页面

属性 类型 是否必选 说明
url string 需要跳转到 tabBar 页面的路径, 路径后不能带参数
sucess funcation 接口调用成功的回调函数
fail funcation 接口调用失败的回调函数
complete funcation 接口调用结束的回掉函数(成功或者失败都会执行)
// 页面结构
 跳转的 tabBAr  页面 

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


// 页面结构
 跳转的 非tabBAr   页面 

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

// 编程式导航进行跳转传参
 跳转的 非tabBAr   页面 

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

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

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

后退机制

// 页面结构
 后退导航 

// 跳转完成后, 进行后退机制
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
{{item}}


// 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 组件页面被隐藏的时候执行
resize Object 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 内置组件。 跳转到响应的网页

注意

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

了解目录结构

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


      	
// 相当于 a 标签

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

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

rich-text
// 富文本组件, 字符串渲染成 html 结构


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

 
  

Mustache 语法 , 差值表达式

// index.wxml
// 在小程序中无论是绑定文本, 还是绑定属性都是使用 message 语法
	 {{message}} 
	 {{message * 100}}  // 进行算数运算
	
      {{message === 'string' ? 4 : 9}}   // 进行三元表达式
// 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 回调函数接收数据

事件绑定

类型 绑定方式 事件描述
tap bindtap 或 bind:tap 手指触摸后马上离开,类似于click
input bindinput 或 bind:input 文本框的输入事件
change bindchange 或 bind:change 状态改变时触发, 主要用于复选框
 按钮 

事件对象的属性列表

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

属性 类型 说明
type String 时间的类型
timeStamp Integer 页面打开到触发事件的毫米数
target Object 触发事件的组件的一些属性值集合
currentTarget Object 当前组件的一些属性值集合
detail Object 额外的信息
toches Array 触摸事件, 当前停留在屏幕中的触摸点信息的数据
changeToches Array 触摸事件, 当前变化的触摸点信息的数组

target 和 currentTarget 的区别

target 是触发事件的源头组件, 而 currentTarget 则是当前事件所绑定的组件。 
举例
	
		

bindtap 语法格式

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

定义一个事件处理函数 , 他与 data 函数平级
例如:

bindinput 语法格式

index.wxml
	  
// 通过 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 进行渲染, 他只是一个容器

 	 aa 
 	 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"


	索引是: {{ index }}, item 项是 {{ item }}


// 如果 不想用 index 或者 item 的话

    // 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 // 是否启用新版组件样式

属性名 类型 默认值 说明 试用
navigationBarTitleText String 字符串 导航栏标题文字内容 导航栏
navigationBarBackgroundColor HexColor #000000 导航栏背景色, 如#00000, 只支持16进制 导航栏
navigationBarTextStyle String white 导航栏标题颜色 , 仅支持black/white, 黑和白 导航栏
backgroundColor HexColor #fffff 窗口的背景色 窗口背景
backgroundTextStyle String dark 下啦 loading 的样式,仅支持dark/light 窗口背景
enablePullDownRefresh Boolean false 是否开启下啦刷新 页面效果
onReachBottomDistance Number 50 页面上拉触底时页面底部距离 页面效果
backgroundColor 16进制 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 是要响应式数据
})

事件传参

全局的 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(){ // 页面一加载, 就 立刻请求数据
	
}

页面导航

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

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

声明式导航

// 跳转到 tabBar 页面
  	
//  open-type 跳转的方式 的 switchTab 是必须跳转

// 跳转到 非tabBar 页面
 跳转到非tabBar页面 // 其中这个 open-type 可以忽略 

// 后腿的导航
 返回上一页 // 其中这个 open-type 可以忽略 

// 导航传参
  
//  在跳转页面地址后,进行页面的跳转传参 、 在跳转的地址后进行 ? 拼接字符串 (&) 符号进行传参的拼接 

编程式导航

跳转到 tabBar 页面

属性 类型 是否必选 说明
url string 需要跳转到 tabBar 页面的路径, 路径后不能带参数
sucess funcation 接口调用成功的回调函数
fail funcation 接口调用失败的回调函数
complete funcation 接口调用结束的回掉函数(成功或者失败都会执行)
// 页面结构
 跳转的 tabBAr  页面 

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


// 页面结构
 跳转的 非tabBAr   页面 

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

// 编程式导航进行跳转传参
 跳转的 非tabBAr   页面 

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

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

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

后退机制

// 页面结构
 后退导航 

// 跳转完成后, 进行后退机制
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
{{item}}


// 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 组件页面被隐藏的时候执行
resize Object 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 中的文件

 {{m1.toUpper(username)}} 

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

外联的 wxs 脚本

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

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

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

// 使用
 {{m2.toLower(country)}}

  // module 必写, 路径必须是相对路径

小程序组件

自定义组件

创建组件

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

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

局部引入

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

// 再页面中的 .wxml 文件中,使用组件
 

全局引入

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

// 再页面中的 .wxml 文件中,使用组件
 

组件中的文件区别

组件带有样式隔离, 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 // 属性的默认值
        }
    }
})

// 使用
 

// 组件的获取
 {{max}} 

// js 文件

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 在组件实例被从页面节点树移除时执行, 组件实例在页面移除时候
error Object Error 每当组件方法抛出错误时执行, 只要报错就会触发
// created 生命周期是组件刚刚被创建好
	// 此时不能创建 setData 。通常在这个生命周期中, 只能应用该组建内的 this 添加一些自定义的属性字段
// attached, 是指组件完全初始化完毕, 进入页面节点树后, attached 生命周期函数会被触发
	// 此时, this.data 已被初始化完毕了。此时,可以干很多事情,例如发送请求

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

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

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

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

插槽

和 vue 一样

// 组件
	
         
     
// 页面调用的组件

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

 

组件通信

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

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



// 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
	 // 通过自定义事件的方式

// 子组件
	// 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 结构


 获取子组建的实例 


// 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 文件中和普通的用法没区别
可用节点 类型 是否必填 描述
propertoes Object Map 同组建的属性
data Object 同组建的数据
meethods Object 同自定义组件的方法
behaviors String Array 引入其他的 behavior
created Funcation 生命周期函数
attached Funcation 生命周期函数
ready Funcation 生命周期函数
moved Funcation 生命周期函数
detached Funcation 生命周期函数

使用 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/[email protected] -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 [email protected] - 下载完成,我们不能直接使用,而是需要再次重新构建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.  // 如何调用呢?
	 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 [email protected] [email protected]

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}}
    nameA + 1	
    
	// 页面的 .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'
  },
选项

你可能感兴趣的:(uni-app,javascript,前端)