自定义导航 导航栏样式"navigationBarTitleText": "登录" -----> 自定义文字生命周期回调中onShareAppMessage回调中return 对象设置自定义内容。_switchtab 跳转到另一个tabb">
赞
踩
Page({
data: {
motto: 'Hello World',
id:18
}
})
单项数据流:Mustache 语法
a)模板结构中使用双大括号 {{data}}
<text id="{{id}}">{{motto}}</text>
<input type="text" value="{{motto}}"/>
a)表单项使用 model:value = ‘{{data}}’
<input type="text" model:value="{{motto}}"/>
b)坑!!!
<input type="text" model:value="{{a}}"/>
this.setData({message: ‘修改之后的数据’}, callback)
Page({
data: {
motto: 'Hello World',
a: 'abc'
},
onLoad(){
this.setData({
motto: 'change data'
})
}
})
2)非冒泡事件
bind绑定:事件绑定不会阻止冒泡事件向上冒泡
<view bindtap="handleTap" class='start_container'>
<text class='start'>开启小程序之旅</text>
</view>
catch 绑定: 事件绑定可以阻止冒泡事件向上冒泡
<view catchtap="handleTap" class='start_container'>
<text class='start'>开启小程序之旅</text>
</view>
<button catchtap="changeName" data-name='{{firstName}}'>点击修改名称</button>
获取: event.target.dataset.key || event.currentTarget.dataset.key
Event.target 和 event.currentTarget的区别
a.) Event.target是触发事件的对象,但不一样是绑定事件的对象,如: 事件委托,冒泡
b) currentTarget触发事件的对象一定是绑定事件的对象, 没有事件委托
wx:for="{{arr}}"
wx:key="唯一值或者index"
<view wx:for="{{ list }}" wx:key="id">
<view>{{ index }} -- {{ item.content }}</view>
</view>
同Vue一样,循环遍历的时候需要为每一个item添加唯一的key值
Key值分类:
a)Item本身就是唯一值,如: number,string
b)*this,代表item本身,同样需要item自身是唯一的,如;number,string
c)Item的唯一属性,如: id; 官网没有明确语法说明,只能在示例代码中找到
注意事项:
a)Wx:key后跟的变量不需要使用插值语法,即不需要使用大括号包裹
b)Item中如果有唯一值属性,可以直接使用
如:item = {id: 1}, 则wx:key = 'id'
1.默认的个体: item
2.默认的下标: index
3.自定义个体变量名称: wx:for-item=’myItem’
4.自定义下标变量名称: wx:for-index=’myIndex’
<view wx:for="{{ list }}" wx:key="id" wx:for-item="myItem" wx:for-index="myIndex">
<view>{{ myIndex}} -- {{myItem.content}}</view>
</view>
wx:if=’条件’
wx:elif=’条件’
wx:else
<view>
<!-- 条件渲染 -->
<view wx:if="{{ isShow }}">表白成功</view>
<view wx:else>表白失败</view>
<!-- <view wx:else="{{ !isShow }}">表白失败</view> -->
<view>-----------------</view>
<view wx:if="{{ sex === 0 }}">男</view>
<view wx:elif="{{ sex === 1 }}">女</view>
<view wx:else>未知</view>
</view>
1.hidden用法: <view hidden='{{true}}' ></view>
2.wx:if 等同于 v-if, 条件为false的时候不加载,条件切换的时候决定元素销毁或者重新加载渲染
3.hidden 等同于 v-show, 始终加载元素, 条件切换的时候决定元素的显示和隐藏
官方图示:官方图
生命周期函数 | 执行时机 | 执行次数 | 特点说明 |
---|---|---|---|
onLoad | 页面加载时触发 | 1 | 可以通过参数获取打开当前页面路径中的参数 |
onShow | 页面显示/切入前台时触发 | 多次 | 如页面没有被销毁,会重复多次显示隐藏,可以在此发送请求获取最新数据 |
onReady | 页面初始化渲染完成时触发 | 1 | 可以同UI界面进行交互 |
onHide | 页面隐藏/切入后台时触发 | 多次 | wx.navigateTo 或底部 tab 切换到其他页面,小程序切入后台等 |
onUnload | 页面卸载时触发 | 1 | wx.redirectTo或wx.navigateBack到其他页面时 |
个人见解
官网生命周期图示是错误的;错误部分:标注onLoad及onShow执行的位置不对
参考:小程序启动执行的所有流程
参考地址:
https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips/start_process.html
小程序适配单位: rpx
规定任何屏幕下宽度为750rpx
小程序会根据屏幕的宽度不同自动计算rpx值的大小
Iphone6下: 1rpx = 1物理像素 = 0.5px
组件传参 - 把标题"猜你喜欢", "人气推荐"传入到组件中
怎么传? — 标签直接帮属性即可
<goods-list title="猜你喜欢" list="{{likeList}}"></goods-list>
怎么接?
组件内使用 properties 接(不支持数组,支持对象和配置对象)
// 不支持数组写法
// properties: ["title"],
// 支持对象写法
// properties: {
// title: String,
// },
// 支持配置对象写法
properties: {
title: {
type: String,
required: true
},
list: {
type: Array,
required: true
}
},
使用标签和js都可以跳转
标签跳转
<navigator
url="/pages/goods/list/list?category2Id={{item.id}}"
></navigator>
同时携带了 query 参数(路由带参)
js跳转
wx.navigateTo({
url: '/pages/goods/list/list',
});
没带参数
wx.switchTab 跳转到tabbar页面
wx.redirectTo 关闭当前页面,跳转下一个页面,当前页面不在历史记录中
wx.navigateTo 跳转页面(有历史记录)
wx.navigateBack({ delta: 1 }) 回退页面,没有参数默认是1
wx.reLaunch 关闭所有的页面,打开到应用内的某个页面
查看页面的钩子函数和事件函数
https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html
onPageScroll(Object object)
监听用户滑动页面事件。
存入数据
a)wx.setStorage() 异步
b)wx.setStorageSync() 同步
读取数据
a)wx.getStorage()异步
b)wx.getStorageSync() 同步
删除数据
a)wx.removeStorage() 异步
b)wx.removeStroageSync() 同步
清空数据
a)wx.clearStorage() 异步
b)wx.clearStorageSync() 同步
https://developers.weixin.qq.com/miniprogram/dev/api/storage/wx.setStorage.html
https://developers.weixin.qq.com/miniprogram/dev/api/storage/wx.setStorage.html
路由地址中 + query传参数
url?a=123
wx.navigateTo({
url: '/pages/target/target?a=1&b=2',
});
onLoad(options){
const {a, b} = options;
}
pubsub-js
npm install pubsub-js
import PubSub from ‘pubsub-js’
PubSub.subscribe(‘eventName’, callback)
PubSub.publish(‘eventName’, data)
PubSub.unsubscribe(‘eventName’)
订阅事件
a)wx.navigateTo()跳转的时候在events选项中定义事件名及事件对应的回调
获取事件总线对象
a)目标页面中通过: 实例.getOpenerEventChannel()
b)示例: const eventChannel = this.getOpenerEventChannel()
触发事件
a)eventChannel.emit(‘事件名’, data)
const app = getApp()
app.currentAddress = currentAddress;
const app = getApp()
let currentAddress = app.currentAddress
获取数据{
"component": true,
"usingComponents": {},
"navigationStyle": "custom" -----> 自定义导航 导航栏样式
"navigationBarTitleText": "登录" -----> 自定义文字
}
1.使用组件的页面的json文件中注册使用组件
{
"usingComponents": {
"goods-list": "/components/goods-list/goods-list"
}
}
<goods-list title="猜你喜欢" list="{{ likeList }}"></goods-list>
npm init
老版本需要勾选
新版本已全面支持,没有当前选项
npm install packageName
<button open-type=’getUserInfo’></button>
wx.getUserInfo()
a) 依然可以使用,但不会出现授权弹窗
b) 获取到的用户名为 ‘微信用户’, 头像为灰色头像
8.6.2.3 登录流程说明
wx.login()
code是临时标识,只有5分钟内有效
发送code给服务器端
服务器端发送请求携带参数(code, appSecret, appId)给微信服务器获取openId
a) 微信接口API: GET https://api.weixin.qq.com/sns/jscode2session
appSecret,appId在小程序首页获取
服务器获取openId后进行加密返回给前端Token标识
npm i @vant/weapp -S --production
yarn add @vant/weapp –production
"packNpmRelationList": [
{
"packageJsonPath": "./package.json",
"miniprogramNpmDistDir": "./"
}
],
微信开发工具 —> 工具 —> 构建npm
{
"usingComponents": {
"van-action-sheet": "@vant/weapp/action-sheet/index",
"van-stepper": "@vant/weapp/stepper/index",
"van-icon": "@vant/weapp/icon/index",
"van-button": "@vant/weapp/button/index"
}
}
8.7.6 使用组件
<van-button block type="primary" round bindtap='handleSubmit'>确定</van-button>
a)异步加载组件
// subPackageA/pages/index.json
{
"usingComponents": {
"button": "../../commonPackage/components/button",
"list": "../../subPackageB/components/full-list",
"simple-list": "../components/simple-list"
},
"componentPlaceholder": {
"button": "view",
"list": "simple-list"
}
}
b)异步加载js文件
/* 回调函数形式 */
let findUserAddress, delAddress;
require('../../../../utils/api', utils => {
findUserAddress = utils.findUserAddress;
delAddress = utils.deleteAddress;
}, ({mod, errMsg}) => {
console.error(`path: ${mod}, ${errMsg}`)
})
/* promise形式 */
(async function(){
let utils = await require('../../../../utils/api')
console.log(utils)
findUserAddress = utils.findUserAddress;
delAddress = utils.deleteAddress;
})()
https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html
<button open-type=’share’ ></button>
wx.requestPayment()
https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_8_2.shtml
整体流程:
用户下单,发请求给商家服务器(这一步前端做),商家服务器生成订单,然后给腾讯服务发请求,生成预付单,生成腾讯生成预付单的目的是为了知道这个订单要收多少钱,腾讯服务知道收多钱之后反馈给商家服务器,生成支付签名信息返回给小程序
小程序端接收到商家返回的支付签名信息,调用 wx.requestPayment()
发起微信支付(这一步前端做)
发起之后要去腾讯服务鉴权,鉴定有没有实名、有没有绑定银行卡,鉴权成功之后告诉小程序可以调起微信支付,此时要去弹出密码输入框(这一步是调用完 requestPayment
)小程序自己和腾讯服务的交互
小程序弹出密码弹框,用户输入密码,授权付款,钱在腾讯服务上,所以授权要发送给腾讯服务,腾讯服务接到授权后,会把用户账号中的款扣了,把钱划给商家,返回支付成功告诉用户,提示"支付成功",这里的支付成功可以理解为"扣款成功"(这时会弹一个弹框,微信弹的)
在这个步骤的同时,会异步告诉商家服务,该用户已经付款,可以发货
点击微信弹出弹框确认之后,要回到商家的小程序,小程序也要提示用户"订单支付成功",所需小程序发请求给商家服务,商家服务接到请求之后,找腾讯服务确认用户是否支付成功,确认之后,返回给用户支付成功的数据,小程序展示"订单支付成功"页面
前端步骤:
调用创建订单接口,创建出订单,返回 orderId
拿着 orderId 获取支付信息
拿着支付信息调用 wx.requestPayment()
去支付
只有支付成功之后,才会走 wx.requestPayment()
的 success 回调
在支付成功之后,调用接口查询订单状态(已支付),跳转支付成功页
app.json
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html
{
entryPagePath string 否 可以用来配置小程序默认启动首页
"pages":[
"pages/index/index" //放在位置为第一个时候 会默认为启动页的首页
],
"window":{
"navigationBarBackgroundColor": "#9c0211",
"navigationBarTitleText": "慕尚花坊",
"navigationBarTextStyle":"white"
},
}
<swiper
class="banner-container"
indicator-dots
indicator-color="#fff"
indicator-active-color="#ff734c"
autoplay
circular
interval="2200"
duration="400"
>
<swiper-item
class="banner-item"
wx:for="{{ bannerList }}"
wx:key="id"
>
<image class="banner-img" src="{{ item.imageUrl }}"></image>
</swiper-item>
</swiper>
<view class="action">
<image class="action-img" src="{{backgroundImg}}" mode="widthFix"></image>
</view>
注意: image 组件的 mode="widthFix" 是设置宽度,保持图片的宽高比不变,自己去算高度
页面宽高设置100%是相对于父级的,而父级是 page 这个元素,这个元素需要设置 宽高100%才可以,这个元素样式在 app.wxss 中设置,这是个全局的,每个页面的根元素都是 page 这个元素
<!-- scroll-view 如果要使用flex布局,需要设置enable-flex属性 -->
<view class="category-container">
<view class="menu">
<scroll-view
class="menu-list"
scroll-y
>
<view class="menu-item active">
鲜花玫瑰
</view>
<view class="menu-item">
鲜花玫瑰
</view>
<view class="menu-item">
鲜花玫瑰
</view>
<view class="menu-item">
鲜花玫瑰
</view>
</scroll-view>
</view>
注意:scroll-view 如果要使用flex布局,需要设置enable-flex属性
button 组件添加 open-type="chooseAvatar"
属性点击才能展示出选择头像的弹框
input 组件添加 type="nickname"
属性才能弹出选择昵称的弹框
function request ({
url,
method = 'GET',
data,
header = {},
timeout = 30000
}) {
wx.showLoading({ title: '加载中' }); // 显示loading
const baseURL = `https://gmall-prod.atguigu.cn`
header = {
'content-type':'application/json',
...header
}
// 获取个人信息需要携带token
let token = wx.getStorageSync("TOKEN");
if (token) {
header.token = token
}
return new Promise((resolve, reject) => {
// wx.request 微信提供的,直接用,没有跨域这一说
wx.request({
url: baseURL + url, // 请求的url
method, // 请求方式
data, // 携带数据
header, // 请求头
timeout, // 超时时间
dataType: 'json', // 数据类型是json
responseType: 'text', // 响应类型是文本
success: (response) => { // 请求成功之后会执行success回调
let res = response.data // 拿到响应体(也就是后端返回的数据,包含code、data、message)
if (res && res.code == 200) {
resolve(res.data)
} else if (res.code == 208) { // 未登录的兜底处理,只要返回code是208都去登录页
wx.showModal({
title: '警告',
content: '未登录,请先登录',
showCancel: true,
cancelText: '取消',
cancelColor: '#000000',
confirmText: '确定',
confirmColor: '#3CC51F',
success: (result) => {
console.log(result)
if(result.confirm){ // 点击确认跳转登录页
wx.navigateTo({
url: '/pages/login/login'
});
}
}
});
} else {
// 弹出提示框
wx.showToast({ // 给用户提示
title: '请求失败',
icon: 'error', // none success error
// image: '/static/images/1.png',
duration: 1500
});
console.error(res) // 给程序员看的
reject(res || '请求失败')
}
},
fail: (err) => { // 请求失败执行的回调(断网的时候会走到fail中,超时也会只有fail,url错误(指url不是字符串)也会走fail)
wx.showToast({ // 给用户提示
title: '请求失败',
icon: 'error',
duration: 1500
});
console.error(err) // 给程序员看的
reject(err)
},
complete: () => { // 不管成功失败都会执行的回调
wx.hideLoading(); // 隐藏loading
}
});
})
}
export default request
在 app.json 中配置
{
"resolveAlias": {
"@/*": "/*"
},
}
地址: https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar
app.json 文件中配置
"tabBar": {
"color": "#333",
"selectedColor": "#ff582f",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "/static/tabbar/home-icon1.png",
"selectedIconPath": "/static/tabbar/home-icon1-1.png"
},
{
"pagePath": "pages/category/category",
"text": "分类",
"iconPath": "/static/tabbar/home-icon2.png",
"selectedIconPath": "/static/tabbar/home-icon2-2.png"
},
{
"pagePath": "pages/cart/cart",
"text": "购物车",
"iconPath": "/static/tabbar/home-icon3.png",
"selectedIconPath": "/static/tabbar/home-icon3-3.png"
},
{
"pagePath": "pages/personal/personal",
"text": "我的",
"iconPath": "/static/tabbar/home-icon4.png",
"selectedIconPath": "/static/tabbar/home-icon4-4.png"
}
]
},
onReachBottom的使用 页面触底回调
页面触底的时候要发送请求,需要页面触底的回调(于data配置项同级)
data: {
......
status: 'more' // 页面发请求的状态,总共有以下几个值: 'more'更多 'no-more'没有更多 'loading'加载中 'error'错误
},
// 页面触底回调
onReachBottom() {
if (this.data.status == 'no-more') {
return
}
// 翻页
this.setData({
page: this.data.page + 1
})
this.getGoodsList()
},
async getGoodsList() {
this.setData({ status: 'loading' })
// 组转数据
const { page, limit, category2Id } = this.data
let data = {}
if (category2Id) {
data.category2Id = category2Id
}
// 发送请求
try {
let result = await reqGoodsList(page, limit, data)
let goodsList = this.data.goodsList.concat(result.records) // 之前列表中的值不能清空
let status = 'more'
if (goodsList.length == result.total) { // 当获取到所有的数据之后,状态改为no-more
status = 'no-more'
}
......
这里使用 goosList.length 和 totoal 去判断也可以
将页面滚动到目标位置,支持选择器和滚动距离两种方式定位
wx.pageScrollTo({ // wx的API
scrollTop: 0, // 页面到顶部的距离
duration: 300 // 页面到顶部的时间
})
onPageScroll(Object object)
监听用户滑动页面事件。
所有小程序中的api在uni中都可以使用但是改变成了uni开头
npx degit dcloudio/uni-preset-vue#vite-ts uni_course
使用的是vite + TS创建的项目,没有依赖
cd uni_course
npm i
安装好依赖就可以启动项目了,在项目启动之前先了解项目目录结构
需要注意的:
manifest.json
文件中要配置 微信小程序的 appid
main.ts
import { createSSRApp } from "vue"; // 引入的是 vue 服务端渲染
import App from "./App.vue"; // 根组件
export function createApp() {
const app = createSSRApp(App); // 创建一个app实例,把App根组件传进去
return {
app, // 把实例抛出去
};
}
客户端渲染:发请求的时候,拿回来的 html 页面只有一个
<div id="app"></div>
元素,页面中所有的内容都是由 请求回来的css 和 js 生成的。服务端渲染:发请求的时候,拿回来的 html 页面是一个完整的 html 页面
服务端渲染最大的优点在于 SEO优化 友好,SEO优化是搜索引擎优化,优化的越好,搜索引擎搜出来的时候排名越靠前(不掏钱的前提下)
App.vue
发现App.vue
根组件中只有 script 和 style,没有 template,为什么?
App.vue
的 style 相当于是 小程序中的 app.wxss
App.vue
的 script 相当于是 小程序中的 app.js
pages.json
相当于是小程序的 app.json
,同时把每个页面的 json,也放在了 pages.json 中
npm run dev:mp-weixin
在 package.json 中发现启动微信小程序是该指令,执行之后,创建了一个 dist/dev 目录,在这个目录中由 mp-weixin
这个文件夹,这就是将 vue 编译成了小程序代码,使用 “微信开发者工具” 打开该项目,就可以看到了
当执行 npm run dev:mp-weixin
时候,dist/dev/mp-weixin
这个小程序代码每次都会清空掉重新构建
去 pages.json 中配置
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "谷粒课堂",
"navigationBarBackgroundColor": "#00cc99"
}
同时需要注意页面的配置项会覆盖全局的配置项,需要改页面的配置项
把首页的内容清空了
官网教程: https://uniapp.dcloud.net.cn/component/uniui/quickstart.html
在 v-card-list
组件中,用到了一个 icon ,这个 icon 使用 uni-ui
组件库
安装 sass 和 sass-loader
npm i sass sass-loader@10.1.1 -D
如果安装失败的话,最后加一个 -f 强制安装
安装 uni-ui
包
npm i @dcloudio/uni-ui
配置 easycom
在 pages.json 中配置 easycom
{
"easycom": {
"autoscan": true,
"custom": {
// uni-ui 规则如下配置
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},
pages:[]
}
接下来就可以在模板中使用了
A页面跳转B页面,携带参数过去,使用query携带参数,在另一个页面中的onLoad的参数中可以拿到传过来的参数
uni.navigateTo({
url: `/pages/course/index?courseId=${courseId}`,
});
在 A 页面将数据存储到storage中,跳转到 B 页面再取出来
A页面
wx.setStorageSync("courseId", courseId);
B 页面
let courseId = wx.getStorageSync("courseId");
在A页面将数据存储到 app 应用实例上,跳转到 B 页面再取出来
A 页面
const app = getApp()
app.courseId = courseId
B 页面
const app = getApp()
const courseId = app.courseId
安装
不在界面上显示的第三包使用步骤(工具类的,例如: pubsub、moment、lodash…)
npm i pubsub-js
直接 【工具】 -> 【构建npm】 即可 使用第三方包
在接收数据的组件中找到 pubsub ,绑定事件(订阅消息),留下回调,接收参数
使用 index 接收
Pubsub.subscribe('receiveData', (messagetype, arg) => {
console.log(messagetype, arg)
})
在发送数据的组件中找到 pubsub,触发事件(发布消息),传递参数
使用 logs 页面发送数据
Pubsub.publish('receiveData', '我爱你')
注意:这个传参用的是 新打开的页面(logs) 给 被盖住的页面(index) 传参
如果是 被盖住的页面(index) 给 新打开的页面(logs) 去使用 pubsub 传参,注意执行时机,只要触发事件在绑定事件之后,就能接收到参数
查看案例:https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.navigateTo.html
被覆盖的页面(index) -> 被打开的页面传参(logs)
被覆盖的页面(index)
wx.navigateTo({
url: '/pages/logs/logs',
success: (res) => {
// res.eventChannel 事件通道 - 触发事件事件传递参数
res.eventChannel.emit('xxx', '你是个好人')
}
})
被打开的页面(logs)
onLoad: function (options) {
// 事件通道
const eventChannel = this.getOpenerEventChannel() // 拿到事件通道
// 绑定事件,留下回调,接收参数
eventChannel.on('xxx', (arg) => {
console.log('事件通道 logs 接参', arg)
})
},
被打开的页面传参(logs) -> 被覆盖的页面(index)
被打开的页面传参(logs)
onLoad: function (options) {
// 5. 事件通道
const eventChannel = this.getOpenerEventChannel() // 拿到事件通道
eventChannel.emit('yyy', '我们不合适')
},
被覆盖的页面(index)
wx.navigateTo({
url: '/pages/logs/logs',
events: {
yyy: (arg) => {
console.log('index页面接收log参数', arg)
}
}
})
uni.$on()
uni.$emit()
uni.$once()
uni.$off()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。