【 uniapp - 黑马优购 | 登录与支付 1】登录组件布局实现、用户信息布局与渲染

news2024/11/16 19:33:20

在这里插入图片描述


在这里插入图片描述


个人名片:

🐼作者简介:一名大二在校生,讨厌编程🎋
🐻‍❄️个人主页🥇:小新爱学习.
🐼个人WeChat:见文末
🕊️系列专栏:🖼️

  • 零基础学Java——小白入门必备
  • 重识C语言——复习回顾
  • 计算机网络体系———深度详讲
  • 微信小程序开发——实战开发
  • 基于黑马优选的小程序开发实战教程

🐓每日一句:🍭努力的意义是给所爱之人一个美好的未来!


文章目录

  • 10. 登录与支付
    • 10.0 创建 settle 分支
    • 10.1 点击结算按钮进行条件判断
    • 10.2 登录
      • 10.2.1 定义 my 页面的编译模式
      • 10.2.2 实现登录和用户信息组件的按需展示
      • 10.2.3 实现登录组件的基本布局
      • 10.2.4 点击登录按钮获取微信用户的基本信息
      • 10.2.5 将用户的基本信息存储到 vuex
      • 10.2.6 登录获取 Token 字符串
      • 10.2.7 将 Token 存储到 vuex
    • 10.3 用户信息
      • 10.3.1 实现用户头像昵称区域的基本布局
      • 10.3.3 渲染第一个面板区域
      • 10.3.4 渲染第二个面板区域
      • 10.3.5 渲染第三个面板区域
      • 10.3.6 实现退出登录的功能
  • <font color =fsjfjf>接推广、写手兼职,详情添加下方wx,备注来意!!!


10. 登录与支付

10.0 创建 settle 分支

  1. 运行如下的命令,基于 master 分支在本地创建 settle 子分支,用来开发登录与支付相关的功能:
git checkout -b settle

10.1 点击结算按钮进行条件判断

说明:用户点击了结算按钮之后,需要先后判断是否勾选了要结算的商品、是否选择了收货地址、是否登录。

  1. my-settle 组件中,为结算按钮绑定点击事件处理函数:
<!-- 结算按钮 -->
<view class="btn-settle" @click="settlement">结算({{checkedCount}})</view>
  1. my-settle 组件的 methods 节点中声明 settlement 事件处理函数如下:
// 点击了结算按钮
settlement() {
  // 1. 先判断是否勾选了要结算的商品
  if (!this.checkedCount) return uni.$showMsg('请选择要结算的商品!')

  // 2. 再判断用户是否选择了收货地址
  if (!this.addstr) return uni.$showMsg('请选择收货地址!')

  // 3. 最后判断用户是否登录了
  if (!this.token) return uni.$showMsg('请先登录!')
}
  1. my-settle 组件中,使用 mapGetters 辅助函数,从 m_user 模块中将 addstr 映射到当前组件中使用:
export default {
  computed: {
    ...mapGetters('m_cart', ['total', 'checkedCount', 'checkedGoodsAmount']),
    // addstr 是详细的收货地址
    ...mapGetters('m_user', ['addstr']),
    isFullCheck() {
      return this.total === this.checkedCount
    },
  },
}
  1. store/user.js 模块的 state 节点中,声明 token 字符串:
export default {
  // 开启命名空间
  namespaced: true,

  // state 数据
  state: () => ({
    // 收货地址
    address: JSON.parse(uni.getStorageSync('address') || '{}'),
    // 登录成功之后的 token 字符串
    token: '',
  }),

  // 省略其它代码
}
  1. my-settle 组件中,使用 mapState 辅助函数,从 m_user 模块中将 token 映射到当前组件中使用:
// 按需从 vuex 中导入 mapState 辅助函数
import { mapGetters, mapMutations, mapState } from 'vuex'

export default {
  computed: {
    ...mapGetters('m_cart', ['total', 'checkedCount', 'checkedGoodsAmount']),
    ...mapGetters('m_user', ['addstr']),
    // token 是用户登录成功之后的 token 字符串
    ...mapState('m_user', ['token']),
    isFullCheck() {
      return this.total === this.checkedCount
    },
  },
}

10.2 登录

10.2.1 定义 my 页面的编译模式

  1. 点击 微信开发者工具 工具栏上的编译模式下拉菜单,选择 添加编译模式

在这里插入图片描述

  1. 勾选启动页面的路径之后,点击确定按钮:

在这里插入图片描述

10.2.2 实现登录和用户信息组件的按需展示

  1. components 目录中新建登录组件:

  2. components 目录中新建用户信息组件:

在这里插入图片描述

  1. my.vue 页面中,通过 mapState 辅助函数,导入需要的 token 字符串:
import badgeMix from '@/mixins/tabbar-badge.js'
// 1. 从 vuex 中按需导入 mapState 辅助函数
import { mapState } from 'vuex'

export default {
  mixins: [badgeMix],
  computed: {
    // 2. 从 m_user 模块中导入需要的 token 字符串
    ...mapState('m_user', ['token']),
  },
  data() {
    return {}
  },
}
  1. my.vue 页面中,实现登录组件和用户信息组件的按需展示:
<template>
  <view>

    <!-- 用户未登录时,显示登录组件 -->
    <my-login v-if="!token"></my-login>

    <!-- 用户登录后,显示用户信息组件 -->
    <my-userinfo v-else></my-userinfo>

  </view>
</template>

10.2.3 实现登录组件的基本布局

  1. 为 my-login 组件定义如下的 UI 结构:
<template>
  <view class="login-container">
    <!-- 提示登录的图标 -->
    <uni-icons type="contact-filled" size="100" color="#AFAFAF"></uni-icons>
    <!-- 登录按钮 -->
    <button type="primary" class="btn-login">一键登录</button>
    <!-- 登录提示 -->
    <view class="tips-text">登录后尽享更多权益</view>
  </view>
</template>
  1. 美化登录组件的样式:
.login-container {
  // 登录盒子的样式
  height: 750rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #f8f8f8;
  position: relative;
  overflow: hidden;

  // 绘制登录盒子底部的半椭圆造型
  &::after {
    content: ' ';
    display: block;
    position: absolute;
    width: 100%;
    height: 40px;
    left: 0;
    bottom: 0;
    background-color: white;
    border-radius: 100%;
    transform: translateY(50%);
  }

  // 登录按钮的样式
  .btn-login {
    width: 90%;
    border-radius: 100px;
    margin: 15px 0;
    background-color: #c00000;
  }

  // 按钮下方提示消息的样式
  .tips-text {
    font-size: 12px;
    color: gray;
  }
}

10.2.4 点击登录按钮获取微信用户的基本信息

需求描述:需要获取微信用户的头像、昵称等基本信息。

  1. 为登录的 button 按钮绑定 open-type="getUserInfo" 属性,表示点击按钮时,希望获取用户的基本信息:
<!-- 登录按钮 -->
<!-- 可以从 @getuserinfo 事件处理函数的形参中,获取到用户的基本信息 -->
<button type="primary" class="btn-login" open-type="getUserInfo" @getuserinfo="getUserInfo">一键登录</button>
  1. methods 节点中声明 getUserInfo 事件处理函数如下:
methods: {
  // 获取微信用户的基本信息
  getUserInfo(e) {
    // 判断是否获取用户信息成功
    if (e.detail.errMsg === 'getUserInfo:fail auth deny') return uni.$showMsg('您取消了登录授权!')

    // 获取用户信息成功, e.detail.userInfo 就是用户的基本信息
    console.log(e.detail.userInfo)
  }
}

10.2.5 将用户的基本信息存储到 vuex

  1. store/user.js 模块的 state 节点中,声明 userinfo 的信息对象如下:
// state 数据
state: () => ({
  // 收货地址
  // address: {}
  address: JSON.parse(uni.getStorageSync('address') || '{}'),
  // 登录成功之后的 token 字符串
  token: '',
  // 用户的基本信息
  userinfo: JSON.parse(uni.getStorageSync('userinfo') || '{}')
}),
  1. store/user.js 模块的 mutations 节点中,声明如下的两个方法:
// 方法
mutations: {
  // 省略其它代码...

  // 更新用户的基本信息
  updateUserInfo(state, userinfo) {
    state.userinfo = userinfo
    // 通过 this.commit() 方法,调用 m_user 模块下的 saveUserInfoToStorage 方法,将 userinfo 对象持久化存储到本地
    this.commit('m_user/saveUserInfoToStorage')
  },

  // 将 userinfo 持久化存储到本地
  saveUserInfoToStorage(state) {
    uni.setStorageSync('userinfo', JSON.stringify(state.userinfo))
  }
}
  1. 使用 mapMutations 辅助函数,将需要的方法映射到 my-login 组件中使用:
// 1. 按需导入 mapMutations 辅助函数
import { mapMutations } from 'vuex'

export default {
  data() {
    return {}
  },
  methods: {
    // 2. 调用 mapMutations 辅助方法,把 m_user 模块中的 updateUserInfo 映射到当前组件中使用
    ...mapMutations('m_user', ['updateUserInfo']),
    // 获取微信用户的基本信息
    getUserInfo(e) {
      // 判断是否获取用户信息成功
      if (e.detail.errMsg === 'getUserInfo:fail auth deny') return uni.$showMsg('您取消了登录授权!')
      // 获取用户信息成功, e.detail.userInfo 就是用户的基本信息
      // console.log(e.detail.userInfo)

      // 3. 将用户的基本信息存储到 vuex 中
      this.updateUserInfo(e.detail.userInfo)
    },
  },
}

10.2.6 登录获取 Token 字符串

需求说明:当获取到了微信用户的基本信息之后,还需要进一步调用登录相关的接口,从而换取登录成功之后的 Token 字符串。

  1. getUserInfo 方法中,预调用 this.getToken() 方法,同时把获取到的用户信息传递进去:
// 获取微信用户的基本信息
getUserInfo(e) {
  // 判断是否获取用户信息成功
  if (e.detail.errMsg === 'getUserInfo:fail auth deny') return uni.$showMsg('您取消了登录授权!')

  // 将用户的基本信息存储到 vuex 中
  this.updateUserInfo(e.detail.userInfo)

  // 获取登录成功后的 Token 字符串
  this.getToken(e.detail)
}
  1. 在 methods 中定义 getToken 方法,调用登录相关的 API,实现登录的功能:
// 调用登录接口,换取永久的 token
async getToken(info) {
  // 调用微信登录接口
  const [err, res] = await uni.login().catch(err => err)
  // 判断是否 uni.login() 调用失败
  if (err || res.errMsg !== 'login:ok') return uni.$showError('登录失败!')

  // 准备参数对象
  const query = {
    code: res.code,
    encryptedData: info.encryptedData,
    iv: info.iv,
    rawData: info.rawData,
    signature: info.signature
  }

  // 换取 token
  const { data: loginResult } = await uni.$http.post('/api/public/v1/users/wxlogin', query)
  if (loginResult.meta.status !== 200) return uni.$showMsg('登录失败!')
  uni.$showMsg('登录成功')
}

10.2.7 将 Token 存储到 vuex

  1. store/user.js 模块的 mutations 节点中,声明如下的两个方法:
mutations: {
  // 省略其它代码...

  // 更新 token 字符串
  updateToken(state, token) {
    state.token = token
    // 通过 this.commit() 方法,调用 m_user 模块下的 saveTokenToStorage 方法,将 token 字符串持久化存储到本地
    this.commit('m_user/saveTokenToStorage')
  },

  // 将 token 字符串持久化存储到本地
  saveTokenToStorage(state) {
    uni.setStorageSync('token', state.token)
  }
}
  1. 修改 store/user.js 模块的 节点如下:
// state 数据
state: () => ({
  // 收货地址
  address: JSON.parse(uni.getStorageSync('address') || '{}'),
  // 登录成功之后的 token 字符串
  token: uni.getStorageSync('token') || '',
  // 用户的基本信息
  userinfo: JSON.parse(uni.getStorageSync('userinfo') || '{}')
}),
  1. my-login 组件中,把 vuex 中的 updateToken 方法映射到当前组件中使用:
methods: {
  // 1. 使用 mapMutations 辅助方法,把 m_user 模块中的 updateToken 方法映射到当前组件中使用
  ...mapMutations('m_user', ['updateUserInfo', 'updateToken'])

  // 省略其它代码...

  // 调用登录接口,换取永久的 token
  async getToken(info) {
    // 调用微信登录接口
    const [err, res] = await uni.login().catch(err => err)
    // 判断是否 uni.login() 调用失败
    if (err || res.errMsg !== 'login:ok') return uni.$showError('登录失败!')

    // 准备参数对象
    const query = {
      code: res.code,
      encryptedData: info.encryptedData,
      iv: info.iv,
      rawData: info.rawData,
      signature: info.signature
    }

    // 换取 token
    const { data: loginResult } = await uni.$http.post('/api/public/v1/users/wxlogin', query)
    if (loginResult.meta.status !== 200) return uni.$showMsg('登录失败!')

    // 2. 更新 vuex 中的 token
    this.updateToken(loginResult.message.token)
  }
}

10.3 用户信息

10.3.1 实现用户头像昵称区域的基本布局

  1. my-userinfo 组件中,定义如下的 UI 结构:
<template>
  <view class="my-userinfo-container">

    <!-- 头像昵称区域 -->
    <view class="top-box">
      <image src="" class="avatar"></image>
      <view class="nickname">xxx</view>
    </view>

  </view>
</template>
  1. 美化当前组件的样式:
.my-userinfo-container {
  height: 100%;
  // 为整个组件的结构添加浅灰色的背景
  background-color: #f4f4f4;

  .top-box {
    height: 400rpx;
    background-color: #c00000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    .avatar {
      display: block;
      width: 90px;
      height: 90px;
      border-radius: 45px;
      border: 2px solid white;
      box-shadow: 0 1px 5px black;
    }

    .nickname {
      color: white;
      font-weight: bold;
      font-size: 16px;
      margin-top: 10px;
    }
  }
}
  1. my.vue 页面中,为最外层包裹性质的 view 容器,添加 class="my-container" 的类名,并美化样式如下:
page,
.my-container {
  height: 100%;
}
#10.3.2 渲染用户的头像和昵称
在 my-userinfo 组件中,通过 mapState 辅助函数,将需要的成员映射到当前组件中使用:

// 按需导入 mapState 辅助函数
import { mapState } from 'vuex'

export default {
  computed: {
    // 将 m_user 模块中的 userinfo 映射到当前页面中使用
    ...mapState('m_user', ['userinfo']),
  },
  data() {
    return {}
  },
}
  1. 将用户的头像和昵称渲染到页面中:
<!-- 头像昵称区域 -->
<view class="top-box">
  <image :src="userinfo.avatarUrl" class="avatar"></image>
  <view class="nickname">{{userinfo.nickName}}</view>
</view>

10.3.3 渲染第一个面板区域

  1. my-userinfo 组件中,定义如下的 UI 结构:
<!-- 面板的列表区域 -->
<view class="panel-list">
  <!-- 第一个面板 -->
  <view class="panel">
    <!-- panel 的主体区域 -->
    <view class="panel-body">
      <!-- panel 的 item 项 -->
      <view class="panel-item">
        <text>8</text>
        <text>收藏的店铺</text>
      </view>
      <view class="panel-item">
        <text>14</text>
        <text>收藏的商品</text>
      </view>
      <view class="panel-item">
        <text>18</text>
        <text>关注的商品</text>
      </view>
      <view class="panel-item">
        <text>84</text>
        <text>足迹</text>
      </view>
    </view>
  </view>

  <!-- 第二个面板 -->

  <!-- 第三个面板 -->
</view>
  1. 美化第一个面板的样式:
.panel-list {
  padding: 0 10px;
  position: relative;
  top: -10px;

  .panel {
    background-color: white;
    border-radius: 3px;
    margin-bottom: 8px;

    .panel-body {
      display: flex;
      justify-content: space-around;

      .panel-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-around;
        font-size: 13px;
        padding: 10px 0;
      }
    }
  }
}

10.3.4 渲染第二个面板区域

  1. 定义第二个面板区域的 UI 结构:
<!-- 第二个面板 -->
<view class="panel">
  <!-- 面板的标题 -->
  <view class="panel-title">我的订单</view>
  <!-- 面板的主体 -->
  <view class="panel-body">
    <!-- 面板主体中的 item 项 -->
    <view class="panel-item">
      <image src="/static/my-icons/icon1.png" class="icon"></image>
      <text>待付款</text>
    </view>
    <view class="panel-item">
      <image src="/static/my-icons/icon2.png" class="icon"></image>
      <text>待收货</text>
    </view>
    <view class="panel-item">
      <image src="/static/my-icons/icon3.png" class="icon"></image>
      <text>退款/退货</text>
    </view>
    <view class="panel-item">
      <image src="/static/my-icons/icon4.png" class="icon"></image>
      <text>全部订单</text>
    </view>
  </view>
</view>
  1. 对之前的 SCSS 样式进行改造,从而美化第二个面板的样式:
.panel-list {
  padding: 0 10px;
  position: relative;
  top: -10px;

  .panel {
    background-color: white;
    border-radius: 3px;
    margin-bottom: 8px;

    .panel-title {
      line-height: 45px;
      padding-left: 10px;
      font-size: 15px;
      border-bottom: 1px solid #f4f4f4;
    }

    .panel-body {
      display: flex;
      justify-content: space-around;

      .panel-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-around;
        font-size: 13px;
        padding: 10px 0;

        .icon {
          width: 35px;
          height: 35px;
        }
      }
    }
  }
}

10.3.5 渲染第三个面板区域

  1. 定义第三个面板区域的 UI 结构:
<!-- 第三个面板 -->
<view class="panel">
  <view class="panel-list-item">
    <text>收货地址</text>
    <uni-icons type="arrowright" size="15"></uni-icons>
  </view>
  <view class="panel-list-item">
    <text>联系客服</text>
    <uni-icons type="arrowright" size="15"></uni-icons>
  </view>
  <view class="panel-list-item">
    <text>退出登录</text>
    <uni-icons type="arrowright" size="15"></uni-icons>
  </view>
</view>
  1. 美化第三个面板区域的样式:
.panel-list-item {
  height: 45px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 15px;
  padding: 0 10px;
}

10.3.6 实现退出登录的功能

  1. 为第三个面板区域中的 退出登录 项绑定 click 点击事件处理函数:
<view class="panel-list-item" @click="logout">
  <text>退出登录</text>
  <uni-icons type="arrowright" size="15"></uni-icons>
</view>
  1. my-userinfo 组件的 methods 节点中定义 logout 事件处理函数:
// 退出登录
async logout() {
  // 询问用户是否退出登录
  const [err, succ] = await uni.showModal({
    title: '提示',
    content: '确认退出登录吗?'
  }).catch(err => err)

  if (succ && succ.confirm) {
     // 用户确认了退出登录的操作
     // 需要清空 vuex 中的 userinfo、token 和 address
     this.updateUserInfo({})
     this.updateToken('')
     this.updateAddress({})
  }
}
使用 mapMutations 辅助方法,将需要用到的 mutations 方法映射到当前组件中:

// 按需导入辅助函数
import { mapState, mapMutations } from 'vuex'

export default {
  methods: {
    ...mapMutations('m_user', ['updateUserInfo', 'updateToken', 'updateAddress']),
  },
}

接推广、写手兼职,详情添加下方wx,备注来意!!!

在这里插入图片描述


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/164515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式-原型模式

设计模式-原型模式一 官方定义二 案例演示解决方案一 - 一般实现方式实现过程案例分析解决方案二使用场景实现过程一实现过程 二案例分析三 浅拷贝和深拷贝浅拷贝问题演示实现过程案例分析解决方案-----深拷贝实现方式一&#xff1a;重写clone()方法扩展思考一 官方定义 原型模…

在VMware 虚拟机(Win7)中还原真机Ghost备份的Win10系统

要求&#xff1a; 将真机Ghost备份的Win10系统还原到VMware安装的虚拟机&#xff08;Win7&#xff09;上 真机&#xff08;物理机&#xff09;&#xff1a;win10pro_pure_20220709.GHO &#xff08;备份的GHO文件&#xff09;&#xff1b;安装模式&#xff1a;Win10UEFIGPT 虚…

HashMap源码学习:红黑树原理详解

前言 JDK1.8后的HashMap引入了红黑树&#xff0c;在学习HashMap源码之前&#xff0c;了解了红黑树原理&#xff0c;及其如何通过代码进行实现后&#xff0c;在整体的看HashMap的源码就会简单很多。 概述 红黑树的特性 根节点必须是黑色节点。节点是红色或黑色。所有叶子都是…

Redis原理

Redis内部使用的是文件事件处理器file event handler,它是单线程的,所以Redis叫做单线程模型。它采用IO多路复用机制同时监听多个socket,将产生事件的socket压入内存队列中,事件分派器根据socket上的事件类型来选择对应的事件处理器进行处理。文件事件处理器包含4个部分:多…

【Java寒假打卡】Java基础-线程池

【Java寒假打卡】Java基础-线程池概述基本使用Executors创建指定上限的线程对象线程池-ThreadPoolExecutorvolatile概述 基本使用 package com.hfut.edu.test12;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class test1 {publ…

java+springboot笔记2023003

java的版本发布&#xff1a; 编译型语言是指使用专门的编译器&#xff0c;针对特定平台&#xff08;操作系统&#xff09; 将某种高级语言源代码一次性“翻译”成可被该平台硬件执行的机器码&#xff08;包括机器指令和操作数&#xff09;&#xff0c;并包装成该平台所能识别的…

Linux下更新curl版本

一、前景 由于低版本的curl存在一定的漏洞&#xff0c;会对我们的服务器安全造成问题&#xff0c;所以&#xff0c;我们需要将curl由低版本安装到高版本。 二、步骤 1、首先检测服务器安装的curl版本 curl --version 2、查看服务器安装的curl的安装包 rpm -qa curl 3、卸载…

基于springboot+mybatis+mysql+jsp房屋租赁管理系统(含论文)

基于springbootmybatismysqljsp房屋租赁管理系统&#xff08;含论文&#xff09;一、系统介绍二、所用技术三、功能展示三、其它系统四、获取源码一、系统介绍 包括管理员、房东、租客三种角色&#xff0c;外加游客(未登录情况) 出租类型包含整租和合租 权限 游客 < 租客 …

适合编程初学者的开源项目:小游戏2048(鸿蒙ArkTS版)

目标 为编程初学者打造入门学习项目&#xff0c;使用各种主流编程语言来实现。 2048游戏规则 一共16个单元格&#xff0c;初始时由2或者4构成。 1、手指向一个方向滑动&#xff0c;所有格子会向那个方向运动。 2、相同数字的两个格子&#xff0c;相遇时数字会相加。 3、每次…

用 JavaScript 写一个新年倒计时

目录前言&#xff1a;主题&#xff1a;运行结果&#xff1a;对应素材&#xff1a;代码实现思路&#xff1a;运行代码&#xff1a;春节的由来&#xff1a;总结&#xff1a;前言&#xff1a; 在春节即将到来&#xff0c;钟声即将响起&#xff0c;焰火即将燃起的日子里&#xff0c…

Kubernetes_CRD自定义资源

系列文章目录 文章目录系列文章目录前言一、CRD操作命令1.1 定义一种资源并查看1.2 使用刚刚定义的资源二、CRD效果演示2.1 实践&#xff1a;定义一种资源并查看2.2 实践&#xff1a;使用刚刚定义的资源总结前言 CRD就是自定义资源&#xff0c;就是自定义 apiVersionKind 参考…

TreeMap 原理实现及常用方法

TreeMap概述 红黑树回顾 TreeMap构造 put方法 get 方法 remove方法 遍历 总结 一. TreeMap概述 TreeMap存储K-V键值对&#xff0c;通过红黑树&#xff08;R-B tree&#xff09;实现&#xff1b; TreeMap继承了NavigableMap接口&#xff0c;NavigableMap接口继承了Sort…

蓝桥杯STM32G431RBT6学习——LED

蓝桥杯STM32G431RBT6学习——LED 前言 LED为每年必考考点&#xff0c;也是入门的基础&#xff0c;国信长天的开发板LED硬件如下&#xff1a; 经典的锁存器控制&#xff0c;因为LED所用引脚与LCD重叠&#xff0c;因此通过锁存器进行控制其状态。当74HC573的LE引脚&#xff08…

C语言综合练习5:快译通下

1 词典文件介绍 前面建立的词典&#xff0c;只有两个单词&#xff0c;现在我们要建立一个上万个单词的词典&#xff0c;所有单词及其翻译都在一个名为dict.txt的文件&#xff08;词典文件&#xff09;中 每个单词有两行&#xff0c;其中一行是单词原文&#xff0c;下一行是对…

Redis中的事务和乐观锁实现

redis事务相关命令&#xff1a; 开启事务&#xff1a;multi 关闭事务&#xff1a;discard 提交事务&#xff1a;exec 正常执行事务情况&#xff1a; 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name zhangsan QUEUED 127.0.0.1:6379> set age 20 QUEUED 127.0.0.1…

AJAX这一篇就够啦~

AJAX这一篇就够啦~AJAX1、AJAX概述1.1 AJAX简介1.2 XML简介1.3 AJAX的特点2、HTTP相关2.1 HTTP概述2.2 请求报文2.3 响应报文2.4 常见的响应状态码2.5 不同类型的请求及其作用2.6 一般http请求 与 ajax请求3、原生AJAX的使用3.1 准备工作3.2 核心对象3.3 GET请求3.4 POST请求3.…

新岁序开,和Jina AI共同码梦! (奖品攻略大揭秘)

Jina AI 北京、深圳、柏林、湾区的小伙伴给您拜年啦&#xff01; Jina AI 开源社区致力于促进 多模态 AI 技术 的应用落地以及传播&#xff0c;一直以来&#xff0c;我们都为拥有这样一个全球化、多元化和高速发展的社区而感到自豪和感激&#xff01;正值新年之际&#xff0c;我…

从C和C++内存管理来谈谈JVM的垃圾回收算法设计-下

从C和C内存管理来谈谈JVM的垃圾回收算法设计-下引言基本概念对象GC ROOTS垃圾回收常见算法标记清除优缺点引用计数优缺点部分标记清除算法优缺点复制算法优缺点多空间复制算法标记整理(标记压缩)优缺点分代设计HotSpot具体实现跨代引用并发可行性经典垃圾回收器Serial新生代垃圾…

Binding常用辅助属性、多重绑定、优先级绑定

Binding常用辅助属性、多重绑定、优先级绑定 Binding常用辅助属性 StringFormat <Window.Resources><sys:Int32 x:Key"myInt">200</sys:Int32><sys:Single x:Key"mySingle">100.123456</sys:Single> </Window.Resourc…

Linux 中断控制器(五):中断号映射

中断号分为硬件中断号(HW ID)和软件中断号(IRQ number)。 这里有两个中断控制器,处理完毕进入 CPU。外设和中断控制器连接在一起,外设给中断控制器的是硬件中断号,如果中断控制器有级联,那么硬件中断号在不同的中断控制器中可能会重复。但是到了 CPU 以后,我们需要对不…