微前端——无界wujie
B站课程视频
课程视频
课程课件笔记:
1.微前端
2.无界
现有的微前端框架:iframe、qiankun、Micro-app(京东)、EMP(百度)、无届
前置
初始化
新建一个文件夹
1.通过npm i typescript -g
安装ts
2.然后可以使用tsc --init
初始化项目,这样项目目录下会有tsconfig.json
配置文件
3.再新建index.ts
4.使用tsc -w
命令可以实时的编译index.ts
出一个index.js
文件
5.通过index.html
引入index.js
即可
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./index.js"></script>
</head>
<body>
</body>
</html>
webComponents初使用
主要是为了样式隔离
wu-jie初体验
在index.ts
文件中书写
// webComponents 的写法
window.onload = () => {// 初始化class Wujie extends HTMLElement {// 类的基本用法constructor() {super()// this.attachShadow创建shadowdom并打开就具有样式隔离的性质,不会影响外层的样式let dom = this.attachShadow({mode: 'open'})// 获取templatelet template = document.querySelector('#wujie') as HTMLTemplateElement// 并绑定,这里是把template的内容深度克隆一份给dom,而不是直接给,true表示深度克隆dom.appendChild(template.content.cloneNode(true))// 这样就把template的内容渲染到了<wu-jie></wu-jie>的组件里面console.log(this.getAttr('url'), this.getAttr('age'))}// 获取传参this.getAttribute 传入属性名即可private getAttr(attr: string) {return this.getAttribute(attr)}}// webComponents挂载,注意名字不能启成驼峰的但是-横线连接可以,第二个参数是上面类的名字// 类似vue组件 原生js写的一个组件 可以在html中使用了<wu-jie></wu-jie>window.customElements.define('wu-jie', Wujie)
}
在上述建立的index.html
中书写
<body><!-- 相当于组件,也可以传参 --><wu-jie url='xxxxx' age='18'></wu-jie><div>我是外层的div</div><template id="wujie"><div>我是 template 里面的div</div><style>div{background: red;}</style></template>
</body>
无届的三个生命周期
//生命周期自动触发有东西插入
connectedCallback () {console.log('类似于vue 的mounted');
}
//生命周期卸载
disconnectedCallback () {console.log('类似于vue 的destory');
}
//跟watch类似
attributeChangedCallback (name:any, oldVal:any, newVal:any) {console.log('跟vue 的watch类似,有属性发生变化自动触发');
}
pnpm介绍
1.全局安装npm i pnpm -g
2.使用 pnpm -v
可以查看版本号
3.pnpm
比 npm
的优势,在pnpm
中文网的动机这样写pnpm官网
简单来说就是,但有100个vue项目,每个项目都会去安装相应的依赖包,这样导致磁盘的缩小和安装速度慢(每次都会重新下载依赖包),很麻烦。
但是pnpm使用软链接
、硬链接
和仓库
解决
硬链接
1.使用cmd查看提示,表示 /H就是硬链接
2.创建命令含义 mklink /H 硬链接的名字 通过谁创建
例如:在pnpm
文件目录下建立index.js
文件,并通过mklink /H ying.js index.js
创建了硬链接
3.并且目录下多出了一个ying.js
4.然后打开文件发现ying.js
中内容和index.js
中一样
5.而且当修改index.js
中的内容时,ying.js
中的内容会跟着修改,因为他们共享的同一个磁盘地址
软链接(符号链接)
1.创建软链接需要管理员权限,所以管理员打开cmd后进入目录可以使用cd ../../
等回退到根目录下,然后直接 D:
进入相应盘,再cd
命令
2.默认就是软链接 mklink ruan.js index.js
即可,不用加任何修饰符
3.成功创建后VScode中会有一个标志
4.且文件管理器中查看也是一个0字节的,因为他只记录一个路径(快捷方式,并不会占用资源),点击会跳转,指向的还是index.js
pnpm如何利用硬链接、软链接解决上述问题
1.使用pnpm init
命令创建package.json
2.以安装vue包为例,使用pnpm i vue
安装vue依赖,可以看到node_modules下面有vue的软链接(快捷方式,地址指向)
3.实际上上述软链接指向在.pnpm
包下找到真正的vue@3.3.13的包下面的vue
文件夹,这个vue硬链接指向.pnpm store
4.实际上就对应了pnpm官网的这张图,非扁平化的方式(可能嵌入,因为这个库可能还依赖其他库,这样依次来)
绿色黄色实线为软链接、红色虚线为硬链接
pnpm的CLI命令管理
假设你之前使用的npm
安装包,会生成一个package-lock.json
,或者使用yarn
安装过,会生成一个yarn.lock
但是你再通过pnpm import
命令 他会把你的上述的软件包管理器的 lockfile 生成 pnpm-lock.yaml
文件
monorepo项目
创建monorepo项目目录
1.使用命令npm init vue
创建vue项目,并创建项目名为main
2.创建web
文件目录存放子应用
3.创建vue子应用,使用npm init vite
选择vue+typescript
4.创建react子应用,使用npm init vite
选择react+typescript
5.在web文件夹下有多个子应用,分别安装有点繁琐,所以在monorepo
文件夹下使用命令pnpm init
生成文件,并手动创建pnpm-workspace.yaml
文件和配置。配置
官网是:
packages:# all packages in direct subdirs of packages/- 'packages/*'# all packages in subdirs of components/- 'components/**'# exclude packages that are inside test directories- '!**/test/**'替换为自己的目录
packages:# all packages in direct subdirs of packages/- 'main/*'# all packages in subdirs of components/- 'web/**'
此时目录如下:
6.替换好pnpm-workspace.yaml
之后可以在根目录直接pnpm i
即可自动为所有的项目安装包
最外层根目录下的node_modules
是所有项目公共的包,而vue项目或者react项目里面的node_modules
是他们单独所需要的,这样结构更加清晰。
子项目启动:
假设这时候我们要跨级执行命令,想要执行react-demo
项目中package.json
的dev
命令,可以使用pnpm -F react-demo dev
,其中F是过滤filter
子模块复用:
1.新建目录common
下,并进入,想要common目录下的东西其余子项目(vue、react等都可以使用)
2.使用pnpm init
初始化生成package.json文件。在pnpm-workspace.yaml
中写
packages:# all packages in direct subdirs of packages/- 'main/*'# all packages in subdirs of components/- 'web/**'- 'common'
3.安装axios包了pnpm i axios
3.新建index.ts,编写一些公共代码
import axios from 'axios'// 公共的提取出来
export const a = axios.get('xxx')
4.进入main目录使用命令pnpm -F main add common
则把common添加进main项目的依赖中,查看main/package.json
文件里面有
5.然后就可以在main/src/main.ts
中引入
import { a } from 'common'
6.同理,也可以去给react-demo项目添加或者vue-demo添加:pnpm -F vue-demo add common
,一样查看那个package.json
有common包,然后可以导入进行使用
无届
安装
1.使用pnpm i wujie
,在main.ts中引入wujie并配置启动的参数
import { startApp } from 'node_modules/wujie/esm/index'
// 启动的参数
startApp({name, url, el})
2.如果是vue项目,可以直接安装npm i wujie-vue3
进行安装
import Wujie from 'wujie-vue3'
app.use(router).use(Wujie)
3.然后分别启动好子应用,记录端口就可以在App.vue中使用了
<template><div><h1>这是主应用</h1><!-- 分别是子应用,子应用启动之后各自的端口 --><WujieVue url="http://127.0.0.1:5174" name="vue3"></WujieVue><WujieVue url="http://127.0.0.1:5175" name="react"></WujieVue></div>
</template>
在main.ts中,全部代码如下:
import './assets/main.css'import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import Wujie from 'wujie-vue3' // 引入一下对应的框架
import { preloadApp } from 'wujie'const app = createApp(App)app.use(router).use(Wujie) // 注册无界
app.mount('#app')// exac预加载为true即可,那么components/react.vue和vue3.vue就会有url
preloadApp({ name: "vue3", url: "http://127.0.0.1:5173", exec: true})
preloadApp({ name: "react", url: "http://127.0.0.1:5174", exec: true})
封装无届
1.创建的目录
封装无届
1.创建的目录文件如下:
其中使用pnpm init
创建package.json
使用tsc --init
创建 tsconfig.json
2.使用pnpm i wujie
安装无届
3.使用pnpm i vue -D
把vue装在开发环境中
4.安装webpack,使用pnpm i webpack webpack-cli -D
5.安装typescript,使用 pnpm i typescript -D
6.安装typescript解析器,使用pnpm i ts-loader -D
书写相关配置代码
配置代码部分可以看源码参照下面的代码
写完后使用 npm run lib
打包
1.在env.d.ts中书写
import { defineComponent, h, getCurrentInstance, onMounted, watch, onBeforeUnmount } from 'vue'
import type { App, PropType } from 'vue'
import { Props } from './type'
import { startApp, bus } from 'wujie'// 函数式定义组件
const wujie = defineComponent({props: {width: { type: String, default: "" },height: { type: String, default: "" },name: { type: String, default: "", required: true },loading: { type: HTMLElement, default: undefined },url: { type: String, default: "", required: true },sync: { type: Boolean, default: undefined },prefix: { type: Object, default: undefined },alive: { type: Boolean, default: undefined },props: { type: Object, default: undefined },attrs: { type: Object, default: undefined },replace: { type: Function as PropType<Props['replace']>, default: undefined },fetch: { type: Function as PropType<Props['fetch']>, default: undefined },fiber: { type: Boolean, default: undefined },degrade: { type: Boolean, default: undefined },plugins: { type: Array as PropType<Props['plugins']>, default: null },beforeLoad: { type: Function as PropType<Props['beforeLoad']>, default: null },beforeMount: { type: Function as PropType<Props['beforeMount']>, default: null },afterMount: { type: Function as PropType<Props['afterMount']>, default: null },beforeUnmount: { type: Function as PropType<Props['beforeUnmount']>, default: null },afterUnmount: { type: Function as PropType<Props['afterUnmount']>, default: null },activated: { type: Function as PropType<Props['activated']>, default: null },deactivated: { type: Function as PropType<Props['deactivated']>, default: null },},setup(props, { emit }) {// 读取当前组件实例// this.$refs.wujie // 在vue2中可以通过this获取当前组件实例const instance = getCurrentInstance() // vue3中通过getCurrentInstance获取组件实例// 封装启动函数const init = () => {// startApp({name, url, el})//初始化无界startApp({name: props.name,url: props.url,el: instance?.refs.wujie as HTMLElement,loading: props.loading,alive: props.alive,fetch: props.fetch,props: props.props,attrs: props.attrs,replace: props.replace,sync: props.sync,prefix: props.prefix,fiber: props.fiber,degrade: props.degrade,plugins: props.plugins,beforeLoad: props.beforeLoad,beforeMount: props.beforeMount,afterMount: props.afterMount,beforeUnmount: props.beforeUnmount,afterUnmount: props.afterUnmount,activated: props.activated,deactivated: props.deactivated,})}watch([props.name, props.url], () => {init() // 如果发生变化就重新执行startApp})const handlerEmit = (event:string, ...args:any[]) => {emit(event, ...args)}onMounted(() => {// 发布订阅模式bus.$onAll(handlerEmit) init()})onBeforeUnmount(() => {bus.$offAll(handlerEmit)})// 定义渲染函数return ()=> h('div', {style: {width: props.width,height: props.height},ref: "wujie" // 方便之后读取})}
})
// install 方法给vue使用的,app.use(router).use(wujie)会调用install
wujie.install = function(app: App) {app.component('WujieVue', wujie)
}export default wujie
2.type.ts
中写
import type { plugin } from 'wujie'
type lifecycle = (appWindow: Window) => any;
interface Props {/** 唯一性用户必须保证 */name: string;/** 需要渲染的url */url: string;/** 需要渲染的html, 如果用户已有则无需从url请求 */html?: string;/** 渲染的容器 */loading?: HTMLElement;/** 路由同步开关, false刷新无效,但是前进后退依然有效 */sync?: boolean;/** 子应用短路径替换,路由同步时生效 */prefix?: { [key: string]: string };/** 子应用保活模式,state不会丢失 */alive?: boolean;/** 注入给子应用的数据 */props?: { [key: string]: any };/** js采用fiber模式执行 */fiber?: boolean;/** 子应用采用降级iframe方案 */degrade?: boolean;/** 自定义运行iframe的属性 */attrs?: { [key: string]: any };/** 自定义降级渲染iframe的属性 */degradeAttrs?: { [key: string]: any };/** 代码替换钩子 */replace?: (codeText: string) => string;/** 自定义fetch,资源和接口 */fetch?: (input: RequestInfo, init?: RequestInit) => Promise<Response>;/** 子应插件 */plugins: Array<plugin>;/** 子应用生命周期 */beforeLoad?: lifecycle;/** 没有做生命周期改造的子应用不会调用 */beforeMount?: lifecycle;afterMount?: lifecycle;beforeUnmount?: lifecycle;afterUnmount?: lifecycle;/** 非保活应用不会调用 */activated?: lifecycle;deactivated?: lifecycle;
};export { Props }
3.webpack.config.js
中写
const { Configuration } = require('webpack')
const path = require('path')/*** @type {Configuration} //配置智能提示*/const config = {entry: "./src/index.ts", // 入口文件mode: "none",output: {filename: "index.js",path: path.resolve(__dirname, 'lib')},externals: { // 防止打包后的代码包含wujie和vue代码显得过多vue: "vue",wujie: "wujie"},module: {rules: [{test: /\.ts$/,use: "ts-loader"}]}}module.exports = config
SWC和babel
SWC官网
1.swc比babel快20倍,如果是4核情况下,快70倍
使用pnpm add -D @swc/score swc-loader
安装命令
2.然后替换webpack.config.js
中的use
module: {rules: [{test: /\.ts$/,use: "ts-loader" // babel的ts-loader,换成swc-loader}]}
3.因为swc底层是rust写的,rust性能是js的好几倍所很快
4.然后再打包npm run lib
打包后还不能直接使用,
因为前端有很多代码规范,AMD, CMD,CommonJS,ESModule,所以统一配置一个UMD,
5.安装pnpm i -D @swc/cli @swc/core
以便使用swc-cli
6.新建配置文件.swcrc
{"$schema": "https://json.schemastore.org/swcrc","jsc": {"parser": {"syntax": "typescript", // js是ecmascript// "jsx": false,// "dynamicImport": false,// "privateMethod": false,// "functionBind": false,// "exportDefaultFrom": false,// "exportNamespaceFrom": false,// "decorators": false,// "decoratorsBeforeExport": false,// "topLevelAwait": false,// "importMeta": false},// "transform": null,"target": "es5","loose": false,"externalHelpers": false,// Requires v1.2.50 or upper and requires target to be es2016 or upper."keepClassNames": false},"minify": false}
7.在根目录的package.json
的 scripts中编写打包命令写"esm": "swc src/index.ts -d esm"
,
8.控制台执行 npm run swc
即可打包在esm
文件中
9.修改增添package.json中
设定一些版本号和启动的入口
"name": "vuejie-setup",
"version": "0.0.1","main": "lib/index.js",
"module": "esm/index.js",
添加files
"files": ["lib","esm","index.d.ts"],
10.在根目录下的index.d.ts
声明文件中写
// import { bus, preloadApp, destroyApp, setupApp } from "wujie";
import type { App } from 'vue';declare const WujieVue: {// bus: typeof bus;// setupApp: typeof setupApp;// preloadApp: typeof preloadApp;// destroyApp: typeof destroyApp;install: (app: App) => void
};export default WujieVue;
发布包
1.切换镜像 mmp use
,输入 npm
2.使用 npm adduser
命令,然后输入npm的用户名
3.使用npm login
4.使用 npm publish
发布
使用
1.在MONOREPO
项目中切换进主应用cd main
2.命令安装pnpm i vuejie-setup
3.在main.ts中引入import Wujie from 'vuejie-setup'
4.使用npm run dev
启动各种主应用或者子应用查看效果
无届的预加载和FPS
1.requestldleCallback函数
MDN的解释
2.FPS扩展
无届的传参
总共三种方法
第一种方法
无届的架构是把JS单独存放在了iframe中,那么iframe可以通过window和父级进行通讯,所以第一种传参就是通过
window.parent.变量名
进行读取。
1.在vue-demo/App.vue中添加按钮,绑定函数获取a
<script setup lang="ts">
const send = () => {alert(window.parent.a) //
}
</script>
<button @click="send">点击</button>
2.在控制台输入变量 var a = '控制台的输入'
3.点击按钮,发现可以弹出
第二种方法
通过props 传参,子应用不需要绑定无界,主应用接进来之后会自动捕获vue实例,所以子应用可以访问到无界实例对象获取参数
1.例如在主应用的components/App.vue
组件中挂载数据,通过props传参
<template><WujieVue :props="{name: '张三', age: '18'}" url="http://127.0.0.1:5173" name="vue3"></WujieVue>
</template>
2.然后在vue-demo子项目中的App.vue中写JS代码
const send = () => {// alert(window.parent.a) // 第一种方法console.log(window.$wujie) // 第二种方式
}
3.为了防止上述$wujie
报错,可以在main.ts
中添加
declare global {interface Window {$wujie: {props: Record<string, any>bus: {$emit: any}}}
}
4.打印的结果如下(可以看到还有bus,第三种方法获取)
4.上述可以访问props console.log(window.$wujie)
进行打印
d第三种方案eventBus发布订阅
可以双向数据传递,直接使用wujie的bus.$on
1.在 主应用的App.vue中通过bus.$on
绑定数据
<script lang="ts">
import { bus } from 'wujie'
bus.$on('vue3', (data: any) => {console.log(data, '我是主应用的bus.$on')
})
</script>
2.在子应用vue-demo的App.vue中通过实例直接使用
const send = () => {// alert(window.parent.a)// console.log(window.$wujie.props) // 获取到App.vue下的propswindow.$wujie.bus.$emit('vue3', '我是子应用vuedemo')
}
模块联邦
1.创建文件如下,目录
2.安装下面四个依赖包
npm i webpack webpack-cli webpack-server html-webpack-plugin -D
3.书写代码,略,结果如下,总之host里面没有的List数据却通过引入到了remote的数据进行展示
4.pnpm run build
进行打包host项目下
点开dist/bundle.js,可以看到使用CDN的方式进行引入的
之前:10个项目引用同一个模块,通过把这个项目发布到npm上面,然后这是个项目可以install这个模块,但是当这个模块发生改变的时候,例如从1.0.0 -> 1.0.1,那么这十个项目得重新下载install一遍
现在的CDN,当你的模块修改了,直接就是最新的版本,通过这个链接,远程调用联邦的技术正是用的这种
报错
1.在tsconfig.app.json
中报错:没有 “node” 模块解析策略的情况下,无法指定选项 “-resolveJsonModule”。
修改tsconfig.app.json
文件中 compilerOptions 选项配置 “moduleResolution”: “node”
{"extends": "@vue/tsconfig/tsconfig.dom.json","include": ["env.d.ts", "src/**/*", "src/**/*.vue"],"exclude": ["src/**/__tests__/*"],"compilerOptions": {"composite": true,/** 模块解析策略,ts默认用node的解析策略,即相对的方式导入, 可选值:node、classic* 如果未指定,则 --module commonjs 默认为 node,否则默认为 classic(包括 --module 设置为 amd、system、umd、es2015、esnext 等)* Node 模块解析是 TypeScript 社区中最常用的,推荐用于大多数项目。 * 如果您在 TypeScript 中遇到导入和导出的解析问题,请尝试设置 moduleResolution: “node” 以查看它是否解决了问题。*/"moduleResolution": "node", "baseUrl": ".","paths": {"@/*": ["./src/*"]}}
}
参考自
一些文件爆红
1.找不到模块“./App.vue”或其相应的类型声明
2.ts.config.app.json找不到文件vue tsconfig tsconfig dom json
如果报错vite找不到之类的,以及奇怪的错误请删除两个子应用重新建立和安装和初始化最外层的包pnpm init
ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL vue-demo@0.0.0 dev: `vite` Exit status 1
一些常用的命令
pnpm i 和 pnpm init
pnpm i
是 pnpm install的简写,表示安装包,会根据package.json的包版本进行安装,
pnpm init
是初始化一个项目,一般只会在空项目文件下创建package.json
一些必要的包
pnpm run dev 和 pnpm run start
前者是开发环境,后者是打包之后的生产环境运行项目
使用脚手架建立项目
因为涉及诸多配置,建议按照vite、webpack官网来看
使用vite脚手架建立vue、react项目
使用webpack脚手架建立vue、react项目
相关文章:
微前端——无界wujie
B站课程视频 课程视频 课程课件笔记: 1.微前端 2.无界 现有的微前端框架:iframe、qiankun、Micro-app(京东)、EMP(百度)、无届 前置 初始化 新建一个文件夹 1.通过npm i typescript -g安装ts 2.然后可…...
连锁便利店管理系统有什么用
连锁便利店管理系统对于连锁便利店的运营和管理非常有用。以下是一些常见的用途: 1. 库存管理:连锁便利店通常需要管理多个门店的库存,管理系统可以帮助实时掌握各个门店的库存情况,包括商品数量、进货记录、库存调拨等。这样可以…...
Vue 的两种实现:VSCode 中配置 vue 模板快捷方式的过程
1、创建配置文件: 其一、打开 VSCode ,CtrlShiftP, 打开搜索框: 其二、输入:user, 并点击进去 Snippets:Configure User Snippets 其三、输入 vue3js 并回车: 其四、打开项目,发现配置文件 vue3js.code-sn…...
electron 切换至esm
前言 好消息,经过不知道多少年的讨论。 electron28.0.0开始(23.08.31),默认支持esm了。 see https://github.com/electron/electron/issues/21457 使用方法 升级至electron^28.0.0简单地在package.json中添加"type":…...
【新版】软考 - 系统架构设计师(总结笔记)
个人总结学习笔记,仅供参考!!!! →点击 笔者主页,欢迎关注哦(互相学习,共同成长) 笔记目录 📢【系统架构设计系列】系统架构设计专业技能 计算机组成与结构操作系统信…...
Spring MVC 方法中添加参数、HttpServletRequest 和 HttpServletResponse 对象
在这个例子中,我们添加了 HttpServletRequest 和 HttpServletResponse 对象作为控制器方法的参数。这样,你就可以在方法内部同时访问请求参数、请求对象和响应对象,从而进行更灵活的 HTTP 请求和响应处理。 RestController public class MyC…...
单片机的RTC获取网络时间
理解网络同步校准RTC的原理需要考虑NTP、SNTP、RTC这三个关键组件的作用和交互。下面详细解释这个过程: 1. NTP(Network Time Protocol): 协议目的:NTP是用于同步计算机和设备时钟的协议。它通过在网络上与时间服务器通…...
Android 13 内置可卸载的搜狗输入法
环境 系统:Android 13 芯片厂商:展锐 需求 默认只有英文输入法,没有中文,需要中文输入法,且可以卸载的。 实测为搜狗输入法,百度等其它输入法也同样适用。 实现 在SDK目录中创建packages/apps/SogouIM…...
持续集成交付CICD:GitLabCI 封装Python类 并结合 ArgoCD 完成前端项目应用发布
目录 一、实验 1. 环境 2. Python代码实现获取文件 3.Python代码实现创建文件 4.Python代码实现更新文件 5.GitLab更新库文件与运行流水线 6.ArgoCD 完成前端项目应用发布 二、问题 1.Python获取GitLab指定仓库文件报错 2. K8S master节点运行Python代码报错 一、实验…...
第十三章 常用类(Math 类、Arrays 类、System类、Biglnteger 和BigDecimal 类、日期类)
一、Math 类(P481) Math 类包含,用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。 (1)abs:绝对值 (2)pow:求幂 (3)c…...
2023年12月24日学习总结
今日to do list: 做kaggle上面的流量预测项目☠️ 学习时不刷手机🤡 okkkkkkkkkkkkkk 开始👍🍎 0、我在干什么? 我在预测一个名字叫做elborn基站的下行链路流量,用过去29天的数据预测未来10天的数据 1、…...
第26关 K8s日志收集揭秘:利用Log-pilot收集POD内业务日志文件
------> 课程视频同步分享在今日头条和B站 大家好,我是博哥爱运维。 OK,到目前为止,我们的服务顺利容器化并上了K8s,同时也能通过外部网络进行请求访问,相关的服务数据也能进行持久化存储了,那么接下来…...
芯科科技以卓越的企业发展和杰出的产品创新获得多项殊荣
2023年共获颁全球及囯內近20个行业奖项 Silicon Labs(亦称“芯科科技”)日前在全球半导体联盟(Global Semiconductor Alliance,GSA)举行的颁奖典礼上,再次荣获最受尊敬上市半导体企业奖,这是公…...
计算机视觉基础(11)——语义分割和实例分割
前言 在这节课,我们将学习语义分割和实例分割。在语义分割中,我们需要重点掌握语义分割的概念、常用数据集、评价指标(IoU)以及经典的语义分割方法(Deeplab系列);在实例分割中,需要知…...
CNAS中兴新支点——什么是软件压力测试?软件压力测试工具和流程
一、含义:软件压力测试是一种测试应用程序性能的方法,通过模拟大量用户并发访问,测试应用程序在压力情况下的表现和响应能力。软件压力测试的目的是发现系统潜在的问题,如内存泄漏、线程锁、资源泄漏等,以及在高峰期或…...
jQuery: 整理3---操作元素的内容
1.html("内容") ->设置元素的内容,包含html标签(非表单元素) <div id"html1"></div><div id"html2"></div>$("#html1").html("<h2>上海</h2>") …...
22、商城系统(四):项目jar包配置(重要),网关配置,商品服务基础数据设置
目录 0.重要:整个项目的配置 最外层的pom.xml renren-fast renren-generator xpmall-common xpmall-coupon...
循环链表的学习以及问题汇总
[TOC](循环链表常见的问题) # 问题一: **报错** ![报错内容](https://img-blog.csdnimg.cn/direct/57a4dcc6993a495c8db9c3dbfade4a78.png) **报错原因:**因为没有提前对_tag_CircleListNode重命名为CircleListNode,所以,在定义…...
C++期末复习总结继承
继承是软件复用的一种形式,他是在现有类的基础上建立新类,新类继承了现有类的属性和方法,并且还拥有了其特有的属性和方法,继承的过程称为派生,新建的类称为派生类(子类),原有的成为…...
CloudCanal x Debezium 打造实时数据流动新范式
简述 Debezium 是一个开源的数据订阅工具,主要功能为捕获数据库变更事件发送到 Kafka。 CloudCanal 近期实现了从 Kafka 消费 Debezium 格式数据,将其 同步到 StarRocks、Doris、Elasticsearch、MongoDB、ClickHouse 等 12 种数据库和数仓,…...
Nodejs+Express搭建HTTPS服务
最近开发需要搭建一个https的服务,正好最近在用nodejs和express,于是乎想到就近就使用这两东西来搭建一个https的服务吧。这里搭建过程总共需要两步,第一步生成证书,第二步使用https模块启动服务。 生成自签名证书 这里因为是自…...
设计模式之-策略模式,快速掌握策略模式,通俗易懂的讲解策略模式以及它的使用场景
系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用…...
【leetcode100-019】【矩阵】螺旋矩阵
【题干】 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 【思路】 不难注意到,每进行一次转向,都有一行/列被输出(并失效);既然已经失效,那我…...
【计算机视觉中的多视图几何系列】深入浅出理解针孔相机模型
温故而知新,可以为师矣! 一、参考资料 《计算机视觉中的多视图几何-第五章》-Richard Hartley, Andrew Zisserman. 二、针孔模型相关介绍 1. 重要概念 1.1 投影中心/摄像机中心/光心 投影中心称为摄像机中心,也称为光心。投影中心位于一…...
轻量级Python IDE使用(三)——函数
1、函数 1.1、函数的概述 在程序设计中,函数的使用可以提升代码的复用率和可维护性。 系统内建函数pow()进行幂运算: a pow(2,4)自定义函数func() def func(a,b):return a ** b afunc(2,4) print(a)自定义函数func(),功能是输出a的b次幂 1.2、函数的定义 py…...
计算机图形学理论(3):着色器编程
本系列根据国外一个图形小哥的讲解为本,整合互联网的一些资料,结合自己的一些理解。 CPU vs GPU CPU支持: 快速缓存分支适应性高性能 GPU支持: 多个 ALU快速板载内存并行任务的高吞吐量(在每个片段、顶点上执行着色…...
ubuntu20.04安装timeshift最新方法
总结: 现在可以使用如下代码安装 sudo apt-get update sudo apt-get install timeshift原因: 在尝试Timeshift系统备份与还原中的方法时, sudo apt-add-repository -y ppa:teejee2008/ppa运行失败。 更改为以下代码: sudo a…...
小狐狸ChatGPT付费创作系统小程序端开发工具提示打开显示无法打开页面解决办法
最新版2.6.7版下载:https://download.csdn.net/download/mo3408/88656497 很多会员在上传小程序前端时经常出现首页无法打开的情况,错误提示无法打开该页面,不支持打开,这种问题其实就是权限问题,页面是通过调用web-v…...
DQL-基本查询
概念: 1,数据库管理系统一个重要功能就是数据查询,数据查询不应只是简单返回数据库中存储的数据,还应该根据需要对数据进行筛选以及确定数据以什么样的格式显示 2,MySQL提供了功能强大、灵活的语句来实现这些操作 3…...
漏洞复现-红帆OA iorepsavexml.aspx文件上传漏洞(附漏洞检测脚本)
免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…...
Leetcode 2976. Minimum Cost to Convert String I
Leetcode 2976. Minimum Cost to Convert String I 1. 解题思路2. 代码实现 题目链接:2976. Minimum Cost to Convert String I 1. 解题思路 这道题思路上其实是非常直接的,本质上就是给出有向图之后,求出有向图上任意两点之间的最短距离&…...
ZKP Mathematical Building Blocks (2)
MIT IAP 2023 Modern Zero Knowledge Cryptography课程笔记 Lecture 3: Mathematical Building Blocks (Yufei Zhao) Fiat Shamir heuristic Turn an interactive proof to a non-interactive proofP can simulate V whenever V picks a random valueP can simulate V’s ran…...
blender径向渐变材质-着色编辑器
要点: 1、用纹理坐标中的物体输出连接映射中的矢量输入 2、物体选择一个空坐标,将空坐标延z轴上移一段距离 3、空坐标的大小要缩放到和要添加材质的物体大小保持一致...
2023美团机器人研究院学术年会成功举办
2023年12月19日,深圳市美团机器人研究院学术年会在清华大学深圳国际研究生院成功落下帷幕。会议回顾了研究院成立一年来的进展和成果,并邀请了各界专家共同讨论机器人技术的未来发展趋势。此外,年会期间还举办了首届低空经济智能飞行管理挑战…...
swing快速入门(二十七)
注释很详细,直接上代码 上一篇 新增内容 1.为按钮指定图标 2. 列表框的并列 3.菜单项绑定快捷键 4.控件悬浮提示信息 5.菜单项设置小图标 6.五种布局风格右键选择切换 package swing21_30;import javax.swing.*; import java.awt.*; import java.awt.event.…...
Vue 封装echarts柱状图(Bar)组件
目的:减少重复代码,便于维护 显示效果 组件代码 <template><div class"ldw-data-content-box"><div class"ldw-chilren-box"><div class"title" v-if"title">{{ title }}</div>…...
异常(Java)
1.异常的概念 在 Java 中,将程序执行过程中发生的不正常行为称为异常 。 1.算数异常 System.out.println(10 / 0); // 执行结果 Exception in thread "main" java.lang.ArithmeticException: / by zero 2.数组越界异常 int[] arr {1, 2, 3}; System.out.…...
vue的插槽解析
插槽 好处:组件的内容结构可定制 用slot插槽进行占位 语法: 子组件中通过slot进行占位 理解:父组件,在子组件标签嵌套的内容就会被渲染到slot地方 一、默认插槽 //子组件 <slot>slot插槽</slot> //方法一<slot name"…...
Spring(3)Spring从零到入门 - Spring整合技术及AOP事务管理
Spring(3)Spring从零到入门 - Spring整合技术及AOP事务管理 文章目录 Spring(3)Spring从零到入门 - Spring整合技术及AOP事务管理4 Spring整合技术示例4.1 Spring整合Mybatis4.1.1 Mybatis开发回顾4.1.2 整合Spring分析4.1.3 Spri…...
适配器模式学习
适配器模式(Adapter)将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 适配器模式分为类适配器模式和对象适配器模式两种,前者类之间的耦合度比后者高,且要…...
NET中使用Identity+CodeFirst+Jwt实现登录、鉴权
目录 前言 一、创建上下文类 1.自定义MyContext上下文类继承IdentityDbContext 2.在Program中添加AddDbContext服务 二、使用Migration数据迁移 1.在控制台中 依次使用add-migration 、updatebase 命令 2.如何修改表名 3.如何自定义字段 三、使用Identity实现登录、修改密码 …...
详解Keras3.0 API: Optimizers
Optimizers 优化器(Optimizer)是深度学习中用于更新模型参数的一种方法,它的目标是最小化损失函数。在训练神经网络时,我们通常使用梯度下降法来更新参数,而优化器就是实现这一过程的工具。优化器的主要作用是在每次迭…...
【数据结构】字符串匹配|BF算法|KMP算法|next数组的优化
字符串匹配算法是在实际工程中经常遇到的问题,也是各大公司笔试面试的常考题目,本文主要介绍BF算法(最好想到的算法,也最好实现)和KMP算法(最经典的) 一、BF算法 BF算法,即暴力(Bru…...
阿里云 ACK One 新特性:多集群网关,帮您快速构建同城容灾系统
云布道师 近日,阿里云分布式云容器平台 ACK One[1]发布“多集群网关”[2](ACK One Multi-cluster Gateways)新特性,这是 ACK One 面向多云、多集群场景提供的云原生网关,用于对多集群南北向流量进行统一管理。 基于 …...
vscode自定义代码片段
前言 代码片段,指的是能够帮助输入重复代码模式,比如初始页面的模板。通过 snippet ,我们仅仅输入一小段字符串,就可以在代码片引擎的帮助下,生成预定义的模板代码,接着我们还可以通过在预定义的光标位置之…...
【贪心算法】专题练习一
欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析(3) 前言 1.什么是贪心算法?——贪婪鼠目寸光 贪心策…...
【JMeter】使用nmon进行性能资源监控
一、前言 在工作中可能会遇到需要在压测的时候对Linux服务器进行性能资源监控的情况。这时可以用nmon来对服务器进行监控。 二、nmon的下载安装 1.查看系统信息 shell cat /etc/os-release 结果为 shell PRETTY_NAME"Debian GNU/Linux 12 (bookworm)" NAME&…...
Unity预设体
目录 预设体是什么? 如何创建预设体? 如何修改预设体? 如何删除预设体? 预设体是什么? Unity中的预设体(Prefab)是一种可重复使用的游戏对象模板。它允许开发者创建一个或多个游戏对象&…...
Elasticsearch 写入优化探索:是什么影响了refresh 耗时?
1、问题背景: 数据写入后,refresh耗时过长,能达到1s-5s。 想通过测试,探索确认影响refresh的因素,比如:写入操作是新增还是更新,deleted文档占比是否有影响,是否有其他索引配置&…...
Java8新特性——函数式接口
目录 一、介绍 二、示例 (一)Consumer 源码解析 测试示例 (二)Comparator (三)Predicate 三、应用 四、总结 一、介绍 FunctionalInterface是一种信息注解类型,用于指明接口类型声明…...