day-115-one-hundred-and-fifteen-20230718-微信小程序初步
微信小程序初步
注册微信小程序开发帐号并拿到开发者ID
- 进入官网,点击
立即注册
。 - 选择
微信小程序
进行注册。 - 点击
前往注册
。 - 按提示进行注册,最好事先准备一个没在微信那边使用的邮箱帐号。
- 重新登录微信小程序开发帐号。
- 在
首页
-小程序发布流程
-小程序开发与管理
–>找到开发设置
页面地址并跳转进行,就会看到开发者ID-AppID(小程序ID)
。这个路径实际上是在[开发
-开发管理
-开发设置
]中,如果没找到,就在微信开发者开发文档
-小程序
中查找。
下载小程序开发工具
- 下载小程序开发工具
- 下载最新稳定版本的。
- 按默认配置直接安装就好了。
- 创建一个新的项目
- 点击新建项目
- 选择新配置项
- 左侧控制台会有莫名其妙的报错,点击刷新就好了
- 设置格式化
- 让请求合法,允许使用本地网络
微信小程序的注意事项
- 微信小程序中使用rpx来代替px。
- rpx是微信小程序中css的尺寸单位,可以根据屏幕宽度进行自适配。
- 规定屏幕宽度为750px,譬如iphone6,屏幕宽度为375px,共有750个物理像素,则1rpx = 0.5px。
- rpx是微信小程序中css的尺寸单位,可以根据屏幕宽度进行自适配。
- 刷新出新的代码效果
默认的配置项
- app.json
{
//用于配置项目中用到的所有页面,这些路径都对应一个同名路由。
"pages": [
"pages/index/index",
"pages/interview/interview",
"pages/mime/mime",
"pages/lesson/lesson",
"pages/improve/improve"
],
//设置下方导航按钮的样式及对应跳转的页面。
"tabBar": {
"color": "#000000",//设置导航按钮的默认的字体颜色。
"selectedColor": "#0099ff",//设置导航按钮的选中时的字体颜色。
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "/images/home.png",
"selectedIconPath": "/images/home-selected.png"
},
{
"pagePath": "pages/interview/interview",
"text": "面试题",
"iconPath": "/images/interview.png",
"selectedIconPath": "/images/interview-selected.png"
},
{
"pagePath": "pages/lesson/lesson",
"text": "课程中心",
"iconPath": "/images/lesson.png",
"selectedIconPath": "/images/lesson-selected.png"
},
{
"pagePath": "pages/mime/mime",
"text": "个人中心",
"iconPath": "/images/mime.png",
"selectedIconPath": "/images/mime-selected.png"
}
]
},
//设置全局默认的样式。
"window": {
"backgroundTextStyle": "light",//全局的背景颜色。
"navigationBarBackgroundColor": "#fff",//默认上方导航栏的背景颜色。
"navigationBarTitleText": "珠峰学堂",//默认上方导航栏的文字。
"navigationBarTextStyle": "black"//默认上方导航栏的文字颜色。
},
"style": "v2",//设置微信内置的标签的默认样式的版本。
"sitemapLocation": "sitemap.json"
}
文件结构说明
/pages/
放置该项目的所有具体页面。/pages/index/
放置该项目的一个具体页面。/pages/index/index.js
该项目的一个具体页面的页面逻辑。/pages/index/index.json
该项目的一个具体页面的页面配置。/pages/index/index.wxml
该项目的一个具体页面的页面结构。/pages/index/index.wxss
该项目的一个具体页面的页面样式表。
/utils/
该项目的工具函数库。/utils/utils.js
该项目的一个全局工具函数库。
/app.js
该项目的全局逻辑。/app.json
该项目的全局配置项。/app.wxss
该项目的全局默认样式。/project.config.json
该项目相关的默认配置项。
小程序登录
常见标签
<view>
:用于创建一个视图容器,类似于 HTML 中的<div>
,用于包裹其他小程序组件。<text>
:用于显示文本内容,类似于 HTML 中的<span>
或<p>
。<image>
:用于显示图片,可以设置图片的来源和样式。<button>
:用于创建按钮,可以设置按钮的样式和点击事件。<input>
:用于创建输入框,用户可以在其中输入文本。
登录流程
配置编译后第一个显示的页面
- 修改pages数组,默认第一个就是第一个要显示的。
- 修改"entryPagePath"
“entryPagePath”: “pages/mime/mime”, - 设置编译模式。
页面变量
- pages/mime/mime.js
const app = getApp();
Page({
data: {
//...
},
functionName(){
console.log('同步方法')
},
async asyncFunctionName(){
console.log('异步方法')
},
})
-
pages/mime/mime.wxml
<view class="login"> <text bind:tap="functionName" >同步方法</text> <text bind:tap="asyncFunctionName" >异步方法</text> </view>
页面方法
-
pages/mime/mime.js
const app = getApp(); Page({ data: { avatarUrl:1111, }, })
-
pages/mime/mime.wxml
<view class="login"> <text class="login_text">{{avatarUrl}}</text> </view>
配置全局默认变量值
-
app.js
// app.js const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbizicTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0' App({ //一启动就运行 onLaunch() { }, globalData: {//全局的属性 avatarUrl: defaultAvatarUrl, baseURL:"http://192.168.1.36:3000" } })
-
pages/mime/mime.js
const app = getApp(); Page({ data: { avatarUrl:app.globalData.avatarUrl, }, })
-
pages/mime/mime.wxml
<view class="login"> <image class="avatar" src="{{avatarUrl}}"></image> <text class="login_text">{{avatarUrl}}</text> </view>
进行登录
- pages/mime/mime.wxml
<view
class="info"
bind:tap="toLogin"
>
<text class="login_text">点我快捷登录</text>
<view class="login_btn">
<text>未登录</text>
</view>
</view>
- pages/mime/mime.js
Page({
async toLogin() {
wx.login({
success: (res) => {
const code = res.code;
if (code) {
wx.request({
url: "http://localhost:3000/login",
data: {
code,
},
success(res) {
const { token, nickname, avatar } = res.data.data;
wx.setStorageSync("token", token);
},
fail(err) {
console.log(err);
},
});
}
},
});
},
});
用全局方法来进行登录
- app.js
// app.js
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbizicTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
App({
//一启动就运行
onLaunch() {
},
globalData: {//全局的属性
avatarUrl: defaultAvatarUrl,
baseURL:"http://192.168.1.36:3000"
}
})
- utils/request.js
export function getToken(){
return wx.getStorageSync('token')
}
export function setToken(token){
return wx.setStorageSync('token', token)
}
export function removeToken(){
return wx.removeStorageSync("token")
}
function request(url,options){
const token = getToken("token")
//如果token存在,则把token在放在请求头的authorization字段中传给微信服务端
if(token){
options.header = Object.assign(options.header||{},{
authorization:`Bearer ${token}`
})
}
return new Promise((resolve,reject)=>{
wx.request({
url: `${getApp().globalData.baseURL}${url}`,
...options,
success(res){
if(res.statusCode==401){
//....未登录时操作
}else if(res.statusCode == 403){
//...登录后操作
}
resolve(res.data)
},
fail(err){
reject(err)
}
})
})
}
export function get(url,options){
return request(url,options)
}
export function post(url,options){
return request(url,{method:"POST",...options})
}
- pages/mime/mime.wxml
<view class="login">
<view class="login-container">
<image class="avatar" src="{{avatarUrl}}"></image>
<view
class="info"
bind:tap="toLogin"
>
<text class="login_text">点我快捷登录</text>
<view class="login_btn">
<text>未登录</text>
</view>
</view>
<view class="info">
<text class="login_text">{{nickname}}</text>
</view>
</view>
</view>
- pages/mime/mime.js
import { get, setToken } from "../../utils/request";
// pages/mime/mime.js
const app = getApp();
Page({
data: {
avatarUrl: app.globalData.avatarUrl,
nickname: "",
avatar: "",
isLogin: false, //登录的状态
},
async toLogin() {
let res = await wx.login();
let code = res.code;
if (code) {
let result = await get("/login", {
data: {
code,
},
});
const { token, nickname = "", avatar = "" } = result.data;
setToken(token);
wx.setStorageSync("user", { nickname, avatar });
if (!nickname) {
const { confirm } = await wx.showModal({
title: "登录成功,您还未完善信息",
content: "去完善信息吧",
confirmText: "去完善",
});
if (confirm) {
//跳转到完善页面
//navigateTo 父页面不会消失,只是隐藏起来
//reLaunch 关闭原有页面,重新打开新页面
//switchTab tab页面切换,缺点就是没法传参
return wx.navigateTo({
url: "/pages/improve/improve",
});
}
}
this.setData({
//更新数据
nickname,
avatar,
isLogin: true,
});
}
},
});
- pages/improve/improve.wxml
<text>/pages/improve/improve.wxml</text>
- pages/improve/improve.js
// pages/index/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
路由跳转
wx.navigateTo()
父页面不会消失,只是隐藏起来wx.reLaunch()
关闭原有页面,重新打开新页面wx.switchTab()
tab页面切换,缺点就是没法传参
更新数据
- pages/index/index.wxml
<text bind:tap="addNum">num - {{num}}</text>
- pages/index/index.js
// pages/index/index.js
Page({
/**
* 页面的初始数据
*/
data: {
num: 1,
},
addNum(params) {
console.log("params", params);
console.log(`this.data.num`, this.data.num);
let theNum = this.data.num + 1;
console.log(`theNum`, theNum);
this.setData({
num: theNum,
});
},
});
真机调试
- 手机要与电脑连接同一个wiff,或者电脑连接的是的手机热点。
取得用户头像或图片
- pages/improve/improve.wxml
<div>e.detail.avatarUrl - {{avatarUrl}}</div>
<image class="avatar" src="{{avatarUrl}}"></image>
<button
class="avatar-wrapper"
open-type="chooseAvatar"
bind:chooseavatar="onChooseAvatar"
>
上传图片
</button>
- pages/improve/improve.js
Page({
data: {
avatarUrl: "",
},
onChooseAvatar(e) {
console.log(`用户选择图片后:e-->`, e);
console.log(
`用户选择的图片路径-在腾讯服务器的地址:e.detail.avatarUrl-->`,
e.detail.avatarUrl
);
this.setData({
avatarUrl: e.detail.avatarUrl,
});
},
});
取得表单项的数据
- pages/improve/improve.wxml
<form bindsubmit="toImprove">
<input
name="nickname"
type="nickname"
class="weui-input"
placeholder="请输入昵称"
/>
<button form-type="submit">确认信息</button>
</form>
- pages/improve/improve.js
Page({
toImprove(e) {
console.log("表单提交时:e", e);
console.log(
"表单中的一个选项的值:e.detail.value.nickname",
e.detail.value.nickname
);
},
});
路由页面重载
- 核心代码
wx.switchTab({
url: "/pages/mime/mime",
success: () => {
let pages = getCurrentPages(); //返回的这个当前页面就是最后一个页面
let currentPage = pages[pages.length - 1];
currentPage.onLoad();
},
});
- 示例:
Page({
onLoad() {
// 在生命周期中使用。
wx.switchTab({
url: "/pages/mime/mime",
success: () => {
let pages = getCurrentPages(); //返回的这个当前页面就是最后一个页面
let currentPage = pages[pages.length - 1];
currentPage.onLoad();
},
});
},
// 在自定义函数中使用。
myFunction() {
wx.switchTab({
url: "/pages/mime/mime",
success: () => {
let pages = getCurrentPages(); //返回的这个当前页面就是最后一个页面
let currentPage = pages[pages.length - 1];
currentPage.onLoad();
},
});
},
});
登录流程总代码
- app.js
// app.js
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbizicTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
App({
//一启动就运行
onLaunch() {
},
globalData: {//全局的属性
avatarUrl: defaultAvatarUrl,
baseURL:"http://192.168.1.36:3000"
}
})
- utils/request.js
export function getToken(){
return wx.getStorageSync('token')
}
export function setToken(token){
return wx.setStorageSync('token', token)
}
export function removeToken(){
return wx.removeStorageSync("token")
}
function request(url,options){
const token = getToken("token")
//如果token存在,则把token在放在请求头的authorization字段中传给微信服务端
if(token){
options.header = Object.assign(options.header||{},{
authorization:`Bearer ${token}`
})
}
return new Promise((resolve,reject)=>{
wx.request({
url: `${getApp().globalData.baseURL}${url}`,
...options,
success(res){
if(res.statusCode==401){
//....未登录时操作
}else if(res.statusCode == 403){
//...登录后操作
}
resolve(res.data)
},
fail(err){
reject(err)
}
})
})
}
export function get(url,options){
return request(url,options)
}
export function post(url,options){
return request(url,{method:"POST",...options})
}
- pages/mime/mime.wxml
<view class="login">
<view class="login-container">
<image class="avatar" src="{{isLogin?avatar:avatarUrl}}"></image>
<view
class="info"
bind:tap="toLogin"
wx:if="{{!isLogin}}"
>
<text class="login_text">点我快捷登录</text>
<view class="login_btn">
<text>未登录</text>
</view>
</view>
<view class="info" wx:else>
<text class="login_text">{{nickname}}</text>
</view>
</view>
</view>
<button bind:tap="logout">退出</button>
- pages/mime/mime.wxss
.login {
background: #1296db;
}
.login-container {
width: 650rpx;
margin: 0 auto;
align-items: center;
display: flex;
height: 250rpx;
color: #fff;
}
.avatar {
width: 150rpx;
height: 150rpx;
border-radius: 50%;
}
.info {
margin-left: 25rpx;
}
.login_text {
font-size: 35rpx;
}
.login_btn {
border: 1px solid #fff;
font-size: 30rpx;
border-radius: 5px;
text-align: center;
width: 140rpx;
padding: 5rpx;
margin-top: 20rpx;
}
- pages/mime/mime.json
{
"usingComponents": {},
"navigationBarTitleText": "个人中心"
}
- pages/mime/mime.js
import { get, getToken, setToken } from "../../utils/request";
// pages/mime/mime.js
const app = getApp();
Page({
data: {
avatarUrl: app.globalData.avatarUrl,
nickname: "",
avatar: "",
isLogin: false, //登录的状态
},
async toLogin() {
let res = await wx.login();
let code = res.code;
if (code) {
let result = await get("/login", {
data: {
code,
},
});
const { token, nickname = "", avatar = "" } = result.data;
setToken(token);
wx.setStorageSync("user", { nickname, avatar });
if (!nickname) {
const { confirm } = await wx.showModal({
title: "登录成功,您还未完善信息",
content: "去完善信息吧",
confirmText: "去完善",
});
if (confirm) {
//跳转到完善页面
//navigateTo 父页面不会消失,只是隐藏起来
//reLaunch 关闭原有页面,重新打开新页面
//switchTab tab页面切换,缺点就是没法传参
return wx.navigateTo({
url: "/pages/improve/improve",
});
}
}
this.setData({
//更新数据
nickname,
avatar,
isLogin: true,
});
}
},
logout() {
wx.clearStorageSync();
wx.reLaunch({
url: "/pages/mime/mime",
});
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
if (getToken()) {
const { nickname, avatar } = wx.getStorageSync("user") || {};
this.setData({
nickname,
avatar,
isLogin: true,
});
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {},
/**
* 生命周期函数--监听页面显示
*/
onShow() {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {},
});
- pages/improve/improve.wxml
<form bindsubmit="toImprove">
<button
class="avatar-wrapper"
open-type="chooseAvatar"
bind:chooseavatar="onChooseAvatar"
>
<image class="avatar" src="{{avatarUrl}}"></image>
</button>
<input
name="nickname"
type="nickname"
class="weui-input"
placeholder="请输入昵称"
/>
<button form-type="submit">确认信息</button>
</form>
- pages/improve/improve.wxss
/* pages/improve/improve.wxss */
.avatar-wrapper {
padding: 0;
width: 100rpx !important;
border-radius: 8px;
margin-top: 40rpx;
margin-bottom: 40rpx;
}
.avatar {
width: 100rpx;
height: 100rpx;
}
- pages/improve/improve.json
{
"usingComponents": {}
}
- pages/improve/improve.js
import { getToken } from "../../utils/request";
// pages/improve/improve.js
const app = getApp()
Page({
data: {
avatarUrl:app.globalData.avatarUrl
},
onLoad() {
},
onChooseAvatar(e){
//console.log(e.detail.avatarUrl)
this.setData({
avatarUrl:e.detail.avatarUrl
})
},
toImprove(e){
//console.log(e.detail.value.nickname);
wx.uploadFile({
filePath: this.data.avatarUrl,
header: {
Authorization: `Bearer ` + getToken(),
},
name: "avatar",
url: app.globalData.baseURL + "/upload",
formData: {
nickname: e.detail.value.nickname,
},
fail: (err) => {
console.log(err);
},
success : (res)=>{
// console.log("2",res.data);
const {nickname,avatar} = JSON.parse(res.data)
wx.setStorageSync('user', {nickname,avatar})
wx.switchTab({
url: '/pages/mime/mime',
success: () =>{
let pages = getCurrentPages(); //返回的这个当前页面就是最后一个页面
let currentPage = pages[pages.length-1]
currentPage.onLoad();
}
})
}
})
},
})