20230718----重返学习-微信小程序初步

day-115-one-hundred-and-fifteen-20230718-微信小程序初步

微信小程序初步

注册微信小程序开发帐号并拿到开发者ID

  1. 进入官网,点击立即注册
  2. 选择微信小程序进行注册。
  3. 点击前往注册
  4. 按提示进行注册,最好事先准备一个没在微信那边使用的邮箱帐号。
  5. 重新登录微信小程序开发帐号。
  6. 首页-小程序发布流程-小程序开发与管理–>找到开发设置页面地址并跳转进行,就会看到开发者ID-AppID(小程序ID)。这个路径实际上是在[开发-开发管理-开发设置]中,如果没找到,就在微信开发者开发文档-小程序中查找。

下载小程序开发工具

  1. 下载小程序开发工具
  2. 下载最新稳定版本的。
  3. 按默认配置直接安装就好了。
  4. 创建一个新的项目
    1. 点击新建项目
    2. 选择新配置项
    3. 左侧控制台会有莫名其妙的报错,点击刷新就好了
  5. 设置格式化
  6. 让请求合法,允许使用本地网络

微信小程序的注意事项

  1. 微信小程序中使用rpx来代替px。
    • rpx是微信小程序中css的尺寸单位,可以根据屏幕宽度进行自适配。
      • 规定屏幕宽度为750px,譬如iphone6,屏幕宽度为375px,共有750个物理像素,则1rpx = 0.5px。
  2. 刷新出新的代码效果

默认的配置项

  • 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 该项目相关的默认配置项。

小程序登录

  1. 小程序登录

常见标签

  1. <view>:用于创建一个视图容器,类似于 HTML 中的 <div>,用于包裹其他小程序组件。
  2. <text>:用于显示文本内容,类似于 HTML 中的 <span><p>
  3. <image>:用于显示图片,可以设置图片的来源和样式。
  4. <button>:用于创建按钮,可以设置按钮的样式和点击事件。
  5. <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,
    });
  },
});

真机调试

  1. 手机要与电脑连接同一个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();
          }

        })
      }
    })
  },
  
})

简历

进阶参考

  1. 微信小程序官网
  2. 微信开发者开发文档-小程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值