当前位置: 首页 > news >正文

qiankun学习记录

什么是微前端

微前端是指存在于浏览器中的微服务,其借鉴了微服务的架构理念,将微服务的概念扩展到了前端。

如果对微服务的概念比较陌生的话,可以简单的理解为微前端就是将一个大型的前端应用拆分成多个模块,每个微前端模块可以由不同的团队进行管理,并可以自主选择框架,并且有自己的仓库,可以独立部署上线。

微前端的好处

1.团队自治
2.兼容老项目
3.跨技术栈

现有的微前端方案

1.iframe
通过iframe标签来嵌入到父应用中,iframe具有天然的隔离属性,各个子应用之间以及子应用和父应用之间都可以做到互不影响。

iframe的缺点:

  1. url不同步,如果刷新页面,iframe中的页面的路由会丢失。
  2. 全局上下文完全隔离,内存变量不共享。
  3. UI不同步,比如iframe中的页面如果有带遮罩层的弹窗组件,则遮罩就不能覆盖整个浏览器,只能在iframe中生效。
  4. 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。
2.single-spa
官网:https://zh-hans.single-spa.js.org/docs/getting-started-overviewsingle-spa是最早的微前端框架,可以兼容很多技术栈。

single-spa的缺点:

  1. 没有实现js隔离和css隔离
  2. 需要修改大量的配置,包括基座和子应用的,不能开箱即用
3.qiankun
qiankun是阿里开源的一个微前端的框架qiankun的优点:
- 基于single-spa封装的,提供了更加开箱即用的API
- 技术栈无关,任意技术栈的应用均可使用/接入,不论是 React/Vue/Angular/JQuery 还是其他等框架。
- HTML Entry的方式接入,像使用iframe一样简单
- 实现了single-spa不具备的样式隔离和js隔离
- 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
  • 基座(主应用):主要负责集成所有的子应用,提供一个入口能够访问你所需要的子应用的展示,尽量不写复杂的业务逻辑
  • 子应用:根据不同业务划分的模块,每个子应用都打包成umd模块的形式供基座(主应用)来加载
基座改造

基座用的是create-react-app脚手架加上antd组件库搭建的项目,也可以选择vue或者其他框架,一般来说,基座只提供加载子应用的容器,尽量不写复杂的业务逻辑。

  1. 安装qiankun
// 安装qiankun
npm i qiankun // 或者 yarn add qiankun
  1. 修改入口文件
// 在src/index.tsx中增加如下代码
import { start, registerMicroApps} from 'qiankun'
// 1.要加载的子应用列表
const apps = [{name: 'sub-react', // 子应用的名称entry: '//localhost:3001', // 默认会加载这个路径下的html,解析里面的jsactiveRule: '/sub-react',// 匹配的路由container: '#sub-app' // 子应用加载的容器},
] // 2. 注册子应用
registerMicroApps(apps, {beforeLoad: [async app => console.log('before load', app.name)],beforeMount: [async app => console.log('before mount', app.name)],afterMount: [async app => console.log('after mount', app.name)],afterUnmount: [async app => console.log('after unmount', app.name)]
})// 3. 启动微服务
start()
react子应用

使用create-react-app脚手架创建,webpack进行配置,为了不eject所有的webpack配置,我们选择用react-app-rewired工具来改造webpack配置。
2. 修改入口文件

// 在src/index.tsx中增加如下代码
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom'
import './public-path'let root: any;
// 将render方法用函数包裹,供后续主应用与独立运行调用
function render(props: any) {const { container } = props// 1.拿到root的divconst dom = container ? container.querySelector('#root') : document.getElementById('root')root = createRoot(dom)// 2.把app渲染到root上面// basename对应的是基座里面子应用列表的路由// 因为基座加载子应用的时候是匹配路由的root.render(<BrowserRouter basename='/sub-react'><App/></BrowserRouter>)
}// 判断是否在qiankun环境下,非qiankun环境下独立运行
if(!(window as any).__POWERED_BY_QIANKUN__) {render({})
}// 各个生命周期
// bootstrap 置灰在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用mount钩子,不会再重复触发 bootstrap
export async function bootstrap() {console.log('react app bootstrap');
}// 应用每次进入都会调用mount方法,通常我们在这里触发应用的渲染方法
export async function mount(props: any) {console.log('props==', props);render(props)
} // 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
export async function unmount(props: any) {root.unmount()
}
  1. 新增public-path.js
if (window.__POWERED_BY_QIANKUN__) {// 动态设置 webpack publicPath,防止资源加载出错// eslint-disable-next-line no-undef__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
  1. 修改webpack配置文件
// 在根目录下新增config-overrides.js文件并新增如下配置
const { name } = require("./package");module.exports = {webpack: (config) => {config.output.library = `${name}-[name]`;// 把项目打包成umd模块,方便qiankun去读取我们暴露出来的生命周期(bootstrap、mount、unmount)config.output.libraryTarget = "umd";config.output.chunkLoadingGlobal = `webpackJsonp_${name}`;return config;}
};
vue子应用
# 创建子应用,选择vue3+vite
npm create vite@latest
改造子应用
  1. 安装vite-plugin-qiankun依赖包
npm i vite-plugin-qiankun # yarn add vite-plugin-qiankun
  1. 修改vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun';export default defineConfig({base: '/sub-vue', // 和基座中配置的activeRule一致server: {port: 3002, // 端口cors: true, // 允许跨域origin: 'http://localhost:3002'  // 指定允许跨域请求的来源地址},plugins: [vue(),// 加一个qiankun,写子应用的名称,需要开发模式的需要配置useDevModeqiankun('sub-vue', { // 配置qiankun插件// 是否运行在开发模式下useDevMode: true})]
})
  1. 修改main.ts
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'let app: any;
// 判断是不是在qiankun环境下
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {createApp(App).use(router).mount('#app');
} else {renderWithQiankun({// 子应用挂载(来回切换的时候)mount (props){ // 挂载的时候app = createApp(App);app.use(router).mount(props.container.querySelector('#app'))},// 只有子应用第一次加载会触发bootstrap () { // 应用刚加载的时候console.log('vue app bootstrap');},// 更新update () { // 更新console.log('vue app update');},// 卸载unmount () { // 卸载console.log('vue app unmount');app?.unmount();}})
}
umi子应用

使用umi4去创建子应用,创建好后只需要简单的配置就可以跑起来

  1. 安装插件
npm i @umijs/plugins
  1. 配置.umirc.ts
export default {base: '/sub-umi',npmClient: 'npm',plugins: ['@umijs/plugins/dist/qiankun'],qiankun: {slave: {},}
};
// 在入口文件导出qiankun的生命周期
export const qiankun = {async mount(props:any) {console.log(props);},async bootstrap () {console.log('umi app bootstraped');},async afterMount(props: any) {console.log('umi app afterMount', props);},
}

补充

1.样式隔离

qiankun内部实现的是子应用之间的样式隔离,基座和子应用之间的样式么没有进行隔离

应用间的样式隔离原因:子应用之间的样式隔离很简单,加载子应用的样式,卸载的时候把子应用的样式进行卸载,加载下一个子应用的时候加载下一个子应用的样式

 1.样式隔离1.1 每个应用的样式使用固定的格式1.2 通过css-module的方式给每个应用自动添加上前缀修改基座应用公共样式的时候还是会影响子应用的样式,这时候可以把子应用的样式优先级提高一点 (样式隔离)
2.子应用间的跳转

2.1 主应用和微应用都是hash模式,主应用根据hash来判断微应用,则不用考虑这个问题

通过location.hash直接修改hash值
http://localhost:3001/#/react-app/list
修改为
http://localhost:3001/#/vue-app/list

2.2 history模式下应用之间的跳转或者微应用跳主应用页面,直接使用微应用的路由实例是不行的,原因是微应用的路由实例跳转都基于路由的base。

2.2.1 history.pushState()
2.2.2 将主应用的路由实例通过props传给微应用,微应用这个路由实例跳转
// 基座和子应用用的都是一个windows对象,可以在基座中复写并监听history.pushState()方法并做相应的跳转逻辑// 在app.tsx重写pushState
// 重写函数// 重写函数const _wr = function (type: string) {// 拿到windos 的history对象传过来的参数const org = (window as any).history[type]return function() {// 拿到org后对他重新调用下const rv = org.apply(this, arguments);const e: any = new Event(type)// 返回发布一个自定义事件e.arguments = argumentswindow.dispatchEvent(e)return rv}}// 把重写的函数赋值给window上pushStatewindow.history.pushState = _wr('pushState')// 在这个函数中做跳转后的逻辑const bindHistory = () => {const currentPath = window.location.pathname;setSelectedPath(routes.find(item => currentPath.includes(item.key))?.key || '')}// 绑定事件window.addEventListener('pushState', bindHistory)
公共依赖加载

3.1 场景:如果主应用和子应用都使用了相同的库或者包(antd, axios等),就可以用externals(外部扩展)的方式来引入,减少加载重复报导致资源浪费,就是一个 项目使用后另一个项目不必再重复加载。

3.2.1 主应用:将所有公共依赖配置webpack的externals,并且在index.html使用外链引入这些公共依赖
3.2.2 子应用:和主应用一样配置webpack的externals,并且在index.html使用外链引入这些公共依赖,注意,还需要给子应用的公共依赖加上ignore属性(这是自定义的属性, 非标准属性),
qiankun在解析时如果发现ignore属性就会自动忽略

以axios为例:
基座的配置

// 修改config-overrides.js
const { override, addWebpackExternals } = require('customize-cra')// 这个配置就是通过外链的方式去引入这个包
module.exports = override(addWebpackExternals({axios: "axios"})
)// 在publi目录下的index.html添加外链
<!-- 注意:这里的公共依赖的版本必须和子应用一致 -->
<script src="https://unpkg.com/axios@1.1.2/dist/axios.min.js"></script>

子应用的配置

// 在umi-app子应用中
// 修改.umirc.ts配置文件
export default {base: '/sub-umi',npmClient: 'npm',plugins: ['@umijs/plugins/dist/qiankun'],qiankun: {slave: {},},headScripts: [{ // 配置外链地址,和设置忽略,qiankun在解析时如果发现ignore属性就会自动忽略src: 'https://unpkg.com/axios@1.1.2/dist/axios.min.js', ignore: true}]
};
全局状态管理

一般来说,各个子应用是通过业务来划分的,不同业务线应该降低耦合度,尽量去避免通信,但是如果涉及到一些公共的状态或者操作,qiankun也是支持的。

qiankun提供了一个全局的GLobalState来共享数据,基座初始化之后,子应用可以监听到这个数据的变化,也能提交这个数据

// 基座的配置
// 在src/index.tsx中增加如下代码
import {  initGlobalState } from 'qiankun'
// 基座初始化
const state = { count: 1 }
const actions = initGlobalState(state);
// 基座项目监听和修改
actions.onGlobalStateChange((state, prev) => {// state: 变更后的状态; prev 变更前的状态console.log(state, prev);
})
actions.setGlobalState(state)
// 子应用的配置
// 在src/index.tsx中增加如下代码
// 在子应用的mount生命周期监听
export async function mount(props: any) {console.log('props==', props);// 子项目监听和修改// 然后在子应用中拿到这两个函数,然后给他设置一个count:2props.onGlobalStateChange((state,prev) => {// state: 变更后的状态, prev 变更前的状态console.log('子应用state===',state,prev)// 一般是将这个state存储到我们子应用的store,然后在其他组件中去用// 这样就是实现了一个简单基座和子应用之间的通信// 同样在其他子应用中想要用到基座传过来的状态也是这样用的,// 修改的话也是调用这个setGlobalState// 监听变化也是调用onGlobalStateChange})props.setGlobalState({ count: 2 })render(props)
} 

相关文章:

qiankun学习记录

什么是微前端 微前端是指存在于浏览器中的微服务&#xff0c;其借鉴了微服务的架构理念&#xff0c;将微服务的概念扩展到了前端。 如果对微服务的概念比较陌生的话&#xff0c;可以简单的理解为微前端就是将一个大型的前端应用拆分成多个模块&#xff0c;每个微前端模块可以…...

【C++ 20进阶(2):初始化 Initializer

【C 20进阶&#xff08;2&#xff09;&#xff1a;初始化 Initializer】 原文&#xff1a;https://blog.csdn.net/weixin_44259356/article/details/144377955 引言 本篇文章为系列文章将着重介绍C20新特性&#xff0c;一是希望可以和大家交流分享&#xff0c;二是也便于自己…...

vue3学习——事件监听(v-on)

我们可以使用 v-on 指令监听 DOM 事件&#xff1a; <button v-on:click"increment">{{ count }}</button> 因为其经常使用&#xff0c;v-on 也有一个简写语法&#xff1a; <button click"increment">{{ count }}</button> 此处…...

java全栈day13-后端Web实战2

接上述查询部门实现&#xff0c;完成后续要求 一、统一响应结果 1.1步骤 资料如下 对一开始的代码修改如下 结果如下 1.2测试 指定请求方式 结果 小结 二、前后端联调测试 资料如下&#xff1a; (不行&#xff0c;一定要不带空格和不带中文&#xff0c;要不然启动不了试了半天…...

C++/CX,一个智能的 C++/Windows 平台开发库!

以下是一篇关于C/CX的C学习文章&#xff1a; 开篇 嘿&#xff0c;大家好呀&#xff01;我是一行。今天咱们来一起探索一个超棒的C开发库——C/CX&#xff0c;它可是在Windows平台开发中非常智能且强大的工具哦&#xff0c;能让我们的开发变得更加高效便捷。让我们一起开启今天的…...

分布式 分布式事务 总结

前言 相关系列 《分布式 & 目录》《分布式 & 分布式事务 & 总结》《分布式 & 分布式事务 & 问题》 分布式事务 所谓分布式事务是指操作范围笼罩多个不同节点的事务。例如对于订单节点&库存节点而言&#xff0c;一次完整的交易需要同时调动两个节…...

数据结构(3)单链表的模拟实现

上一节我们进行了数据结构中的顺序表的模拟式现&#xff0c;今天我们来实现一下另外一个数据结构&#xff1a;单链表。 我们在实现顺序表之后一定会引发一些问题和思考&#xff1a; 1.顺序表在头部和中间插入数据会用到循环&#xff0c;时间复杂O&#xff08;N&#xff09; …...

HBU深度学习实验14.5-循环神经网络(1.5)

梯度爆炸实验 造成简单循环网络较难建模长程依赖问题的原因有两个&#xff1a;梯度爆炸和梯度消失。一般来讲&#xff0c;循环网络的梯度爆炸问题比较容易解决&#xff0c;一般通过权重衰减或梯度截断可以较好地来避免&#xff1b;对于梯度消失问题&#xff0c;更加有效的方式…...

Redis01

springbootredis 特点 1.高效性 2.支持多种数据结构 String,list,set,hash.zset 3.稳定性&#xff1a;持久化&#xff0c;主从复制&#xff08;集群&#xff09; 4.其他特性&#xff1a;支持过期时间&#xff0c;支持事务&#xff0c;消息订阅。 安装 1.下载安装包 redis官…...

数据库中decimal、float 和 double区别

在计算机科学中&#xff0c;decimal、float 和 double 是用于表示和处理数值的不同数据类型。 - decimal 是一种精确的十进制浮点数表示&#xff0c;通常用于需要高精度计算的场景&#xff0c;比如财务应用。它能够精确表示小数&#xff0c;并且不会出现浮点数运算误差。 - flo…...

HDR视频技术之五:HDR生产流程

在介绍 HDR 的生产流程之前&#xff0c;我们先介绍下视频制作与传输的一些基本知识。 内容类型&#xff1a; 直播内容&#xff08; live content&#xff09; ——所谓的直播内容即没有后处理过程以及创作者意图。分发给用户的信息是实时产生并且实时制作并派发的。常见的应用…...

CTFshow-爆破(Web21-28)

CTFshow-爆破(Web21-28) Web21 抓包 选则dic.zip里的字典爆破&#xff0c;记得添加前缀admin: 答案admin:shark63 burp里有一个自定义迭代器&#xff0c;可以设置前几部分&#xff0c;很好用 Web22 题目失效了直接看wp吧 360quake 使用空间搜索引擎—>360quake 搜索语法…...

C++重点和练习

作业题目&#xff1a; #include <iostream> using namespace std; class Rec {const int length;int width; public:void set_length(int l);void set_width(int w);int get_length();int get_width();void show(); };#include <iostream> using namespace std; c…...

UnityShaderLab-实现溶解效果

实现思路&#xff1a; 使用一张噪声图&#xff0c;与一个Cut值计算&#xff08;加或减&#xff09;&#xff0c;将计算后的值赋值给Alpha,然后小于0的片段就被丢弃掉了。 ShaderGraph实现&#xff1a; ShaderLab实现&#xff1a; Shader "Dissolve" {Properties{_…...

SQLite 数据库学习

1.install sudo apt update sudo apt install sqlitebrowser这是一个开源的图形用户界面工具&#xff0c;专门用于开发、管理和分析 SQLite 数据库。它支持创建或导入导出表、编辑数据、执行 SQL 查询等功能。 2.python 操作数据库 Python 内置了 sqlite3 模块&#xff0c;使…...

【LeetCode: 463. 岛屿的周长 + bfs】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…...

Bean的注入、单例和多例

目录 注入Bean对象 属性注入 构造注入 属性注入专题 注入集合/数组 级联简单类型赋值 Bean的单例和多例 注入Bean对象 简单类型使用value(除Date)&#xff0c;非简单类型使用ref 属性注入 name规则&#xff1a;必须提供set方法&#xff0c;去掉set&#xff0c;第一个字…...

java 使用JSqlParser和CCJSqlParser 解析sql

maven <dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>4.9</version> </dependency>解析SQL String sql "select aa,bb from b"; Statement statementCCJSq…...

Anaconda Conda Pip 的区别与联系

在Python生态中,Anaconda、Conda和Pip是三个非常重要的工具,它们在包管理和环境管理方面发挥着关键作用。 Anaconda Anaconda是一个为科学计算而设计的Python发行版,它集成了Conda、Python以及大量的数据科学相关库,如NumPy、Pandas等。Anaconda的主要优势在于它提供了一个…...

总结的一些MySql面试题

目录 一&#xff1a;基础篇 二&#xff1a;索引原理和SQL优化 三&#xff1a;事务原理 四&#xff1a;缓存策略 一&#xff1a;基础篇 1&#xff1a;定义&#xff1a;按照数据结构来组织、存储和管理数据的仓库&#xff1b;是一个长期存储在计算机内的、有组织的、可共享 的…...

【实验15】LSTM的记忆能力实验

目录 1 模型构建 1.1 LSTM层 1.1.1 自定义LSTM算子 1.1.2 nn.LSTM 1.1.3 将自定义LSTM与pytorch内置的LSTM进行对比 1.2 模型汇总 2 模型训练 2.1 训练指定长度的数字预测模型 2.2 多组训练 2.3 损失函数展示 3 模型评价 4 完整代码 5 LSTM模型门状态和单元状态的…...

SSH克隆github项目

1、生成密钥 ssh-keygen -t rsa -C "你的邮箱xxx.com" 全程回车即可&#xff08;不用输入ras文件名及密码&#xff09;、为了方便下面的公钥查看 2、配置公钥 查看公钥内容 cat c:\Users\xxx\.ssh\id_rsa.pub(修改为自己的路径及名字) 将公钥内容复制并粘贴至…...

计算机网络ENSP课设--三层架构企业网络

本课程设计搭建一个小型互联网&#xff0c;并模拟Internet的典型Web服务过程。通过此次课程设计&#xff0c;可以进一步理解Internet的工作原理和协议过程&#xff0c;并提高综合知识的运用能力和分析能力。具体目标包括&#xff1a; &#xff08;1&#xff09;掌握网络拓扑的…...

Node.js系统模块

【图书介绍】《Node.jsMongoDBVue.js全栈开发实战》-CSDN博客 《Node.jsMongoDBVue.js全栈开发实战&#xff08;Web前端技术丛书&#xff09;》(邹琼俊)【摘要 书评 试读】- 京东图书 (jd.com) 2.2.1 什么是系统模块 由于Node.js运行环境提供的API都是以模块化的方式进行开…...

React - useActionState、useFormStatus与表单处理

参考文档&#xff1a;react18.3.1官方文档 一些概念&#xff1a; React 的 Canary 和 Experimental 频道是 React 团队用于发布和测试新功能的渠道。 useActionState useActionState 是一个可以根据某个表单动作的结果更新 state 的 Hook。 const [state, formAction, isPe…...

GC常见垃圾回收算法,JVM分代模型

如何判断是垃圾&#xff1f;引用计数器和Root可达性算法 如何进行清除&#xff1f;标记清除、复制、标记整理 堆分代模型&#xff1f;Eden&#xff0c;Surevivor&#xff0c;Tenuring 一个对象从创建到消亡的过程&#xff1f; 对象什么时候进入老年代&#xff1f; 一、GC&a…...

深入探索 JVM:原理、机制与实战

一、JVM 概述 JVM&#xff08;Java Virtual Machine&#xff09;是 Java 程序运行的核心组件&#xff0c;它提供了一个独立于硬件和操作系统的执行环境&#xff0c;使得 Java 程序能够在不同平台上具有跨平台的特性。 JVM 主要由以下几部分组成&#xff1a; 类装载器&#xf…...

前端成长之路:HTML(2)

HTML中有两个非常重要的标签——表格和表单&#xff0c;在介绍之前需要先了解表格和表单的区别&#xff1a;表格是用于展示数据的&#xff1b;表单是用于提交数据的。本文主要介绍表格。 表格标签 表格主要是用于显示、展示数据的&#xff0c;并非是页面布局。它可以使本来难…...

python基础:(七)类

目录 一.创建和使用类二.使用类和实例2.1给属性指定默认值2.2修改属性的值2.2.1直接修改属性的值2.2.2通过方法修改属性的值2.2.3通过方法对属性的值进行递增 三.继承3.1子类的方法__init__()3.2给子类定义属性和方法3.3重写父类的方法 四.导入类4.1语法--1:4.2语法--2 前言 p…...

Spring AOP基础、快速入门

介绍 AOP&#xff0c;面向切面编程&#xff0c;作为面向对象的一种补充&#xff0c;将公共逻辑&#xff08;事务管理、日志、缓存、权限控制、限流等&#xff09;封装成切面&#xff0c;跟业务代码进行分离&#xff0c;可以减少系统的重复代码和降低模块之间的耦合度。切面就是…...

Golang使用etcd构建分布式锁案例

在本教程中&#xff0c;我们将学习如何使用Go和etcd构建分布式锁系统。分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要。它有助于维护一致性&#xff0c;防止竞争条件&#xff0c;并确保在任何给定时间只有一个进程独占访问资源。 我们将使用Go作为编程语言&am…...

深度学习:基于MindSpore的极简风大模型微调

什么是PEFT&#xff1f;What is PEFT&#xff1f; PEFT(Parameter Efficient Fine-Tuning)是一系列让大规模预训练模型高效适应于新任务或新数据集的技术。 PEFT在保持大部分模型权重冻结&#xff0c;只修改或添加一小部份参数。这种方法极大得减少了计算量和存储开销&#x…...

如何在 Android 项目中实现跨库传值

背景介绍 在一个复杂的 Android 项目中&#xff0c;我们通常会有多个库&#xff08;lib&#xff09;&#xff0c;而主应用程序&#xff08;app&#xff09;依赖所有这些库。目前遇到的问题是&#xff0c;在这些库中&#xff0c;libAd 需要获取 libVip 的 VIP 等级状态&#xf…...

HTML:表格重点

用表格就用table caption为该表上部信息&#xff0c;用来说明表的作用 thead为表头主要信息&#xff0c;效果加粗 tbody为表格中的主体内容 tr是 table row 表格的行 td是table data th是table heading表格标题 &#xff0c;一般表格第一行的数据都是table heading...

STM32 出租车计价器系统设计(一) 江科大源码改写

STM32 出租车计价器系统设计 功能目标 驱动步进电机模拟车轮旋转&#xff0c;并实现调速功能。 设置车轮周长和单价&#xff0c;检测车轮转速和运转时间。 计算并显示行驶里程和价格。 硬件材料 28BYJ48 五线四相步进电机和 ULN2003 驱动板模块 测速传感器模块 嵌入式小系统…...

Git基础操作快速入门

Git是一个免费开源分布式版本控制工具&#xff0c;是由Linux的作者Linus开发的第二个伟大作品。2005年由于BitKeeper软件公司对Linux社区停止了免费使用权。Linus迫不得己自己开发了一个分布式版本控制工具&#xff0c;从而Git诞生了 目前使用Git作为版本控制的开源软件&#…...

vue‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。

在Windows操作系统中,安装了nodeJs之后,并且也安装了vue依赖包,但是在cmd控制台运行vue的时候,会报错:vue‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。针对这个问题我提供如下解决办法,并且是有效的。 一、原因分析 关于尝试这个问题的主要原因,我分析主要…...

JAVA安全—SpringBoot框架MyBatis注入Thymeleaf模板注入

前言 之前我们讲了JAVA的一些组件安全&#xff0c;比如Log4j&#xff0c;fastjson。今天讲一下框架安全&#xff0c;就是这个也是比较常见的SpringBoot框架。 SpringBoot框架 Spring Boot是由Pivotal团队提供的一套开源框架&#xff0c;可以简化spring应用的创建及部署。它提…...

Milvus向量数据库05-常见问题整理

Milvus向量数据库05-常见问题整理 1-什么是PipeLine 这张图展示了一个文档处理和搜索系统的架构&#xff0c;主要分为两个部分&#xff1a;Ingestion Pipeline&#xff08;摄取管道&#xff09;和 Search Pipeline&#xff08;搜索管道&#xff09;。下面是对图中各部分的详细…...

strncpy在复制含有多个\0的字符串时遇到的问题

strncpy在复制含有多个\0的字符串的时候&#xff0c;会产生截断&#xff0c;因为strncpy在读取源字符串的时候&#xff0c;遇到了\0&#xff0c;函数会认为该字符串已经结束了&#xff0c;然后会向目标字符串内填充\0。 char buffer[100] "ak\0jl";for (int i 0; i…...

C++作业3

作业1&#xff1a; 1.定义一个矩形类Rec&#xff0c;包含私有属性length、width&#xff0c;包含公有成员方法&#xff1a; void set_length(int l);//设置长度 Void set_width(int w);//设置宽度 Int get_length();//获取长度&#xff0c;将长度的值返回给调用处 Int get_widt…...

重生之我在学Vue--第1天 Vue 3 基础与开发环境搭建

重生之我在学Vue–第1天 Vue 3 基础与开发环境搭建 文章目录 重生之我在学Vue--第1天 Vue 3 基础与开发环境搭建前言一、Vue 3 的特点与核心概念二、搭建开发环境1. 安装 Node.js2. 使用 Vite 创建 Vue 3 项目创建项目进入项目目录并安装依赖启动开发服务器 3. 理解项目结构 三…...

企业经营数据分析系统:提升决策能力的利器

搭建企业经营数据分析系统是当今企业绕不开的话题&#xff0c;企业想要在竞争激烈的市场当中突围而出&#xff0c;需要对于企业内部的各种数据了然于胸&#xff0c;同时对于外部的数据也有敏锐的把握能力&#xff0c;因此企业构建自身的经营性数据分析系统就显得尤其重要。作为…...

Linux笔记9 DNS域名解析服务器

简介 DNS&#xff08;Domain Name System&#xff09;是互联网上的一项服务&#xff0c;它作为将域名和IP地址相互映射的一个分 布式数据库&#xff0c;能够使人更方便的访问互联网。 DNS使用的是53端口&#xff0c; 通常DNS是以UDP这个较快速的数据传输协议来查询的&#x…...

鸿蒙高级开发者认证的主观题试题及答案

以下是一份鸿蒙高级开发者认证的主观题试题及答案示例,涵盖了鸿蒙开发中的多个关键技术和应用场景相关内容,希望对你有所帮助: 一、论述题(每题 20 分,共 60 分) 1. 阐述鸿蒙操作系统中分布式软总线的工作原理、核心优势以及在多设备协同应用开发场景下的应用方式,并举…...

leetcode_547 省份数量

该题主要运用了图的连通性 接着使用染色法解决该问题 染色法:标记所有节点为false 访问后 将其标记位true class Solution {int n; // 代表n个数据bool colors[201]; // 标记是否访问到void dfs(vector<vector<int>>& isConnected, int u) { // …...

【开源】一款基于SpringBoot 的全开源充电桩平台

一、下载项目文件 下载源码项目文件口令&#xff1a;动作璆璜量子屏多好/~d1b8356ox2~:/复制口令后&#xff0c;进入夸克网盘app即可保存&#xff08;如果复制到夸克app没有跳转资源&#xff0c;可以复制粘贴口令到夸克app的搜索框也可以打开&#xff08;不用点搜索按钮&#…...

react antd tabs router 基础管理后台模版

在构建 React 后台管理系统时&#xff0c;使用标签页的方式展示路由是一种高效且用户友好的设计模式。这种实现方式通常允许用户在多个页面之间快速切换&#xff0c;并保留页面的状态&#xff0c;类似于浏览器的多标签页功能。 需求分析 1.动态标签页&#xff1a;根据用户的导…...

uniapp uni-table最简单固定表头

需求&#xff1a;固定表头数据&#xff0c;在网上找了半天&#xff0c;啥都有&#xff0c;就是一直实现不了&#xff0c;最后更改代码实现 1.效果 2.主要代码讲解完整代码 表格的父级一定要设置高度&#xff0c;不然会错位&#xff0c;我看网上说设置position&#xff1a;fixed…...

从0到1实现项目Docker编排部署

在深入讨论 Docker 编排之前&#xff0c;首先让我们了解一下 Docker 技术本身。Docker 是一个开源平台&#xff0c;旨在帮助开发者自动化应用程序的部署、扩展和管理。自 2013 年推出以来&#xff0c;Docker 迅速发展成为现代软件开发和运维领域不可或缺的重要工具。 Docker 采…...