vant 4 正式发布,支持暗黑主题,那么是如何实现的呢
2022年10月25日首发于掘金,现在同步到公众号。
11. 前言
大家好,我是若川。我倾力持续组织了一年多源码共读,感兴趣的可以加我微信 lxchuan12
参与。另外,想学源码,极力推荐关注我写的专栏《学习源码整体架构系列》,目前是掘金关注人数(4.6k+人)第一的专栏,写有20余篇源码文章。
我们开发业务时经常会使用到组件库,一般来说,很多时候我们不需要关心内部实现。但是如果希望学习和深究里面的原理,这时我们可以分析自己使用的组件库实现。有哪些优雅实现、最佳实践、前沿技术等都可以值得我们借鉴。
相比于原生 JS
等源码。我们或许更应该学习,正在使用的组件库的源码,因为有助于帮助我们写业务和写自己的组件。
如果是 Vue
技术栈,开发移动端的项目,大多会选用 vant
组件库,目前(2022-10-24) star
多达 20.3k
。我们可以挑选 vant
组件库学习,我会写一个组件库源码系列专栏[1],欢迎大家关注。
这次我们来分析 vant4
新增的暗黑主题是如何实现的。文章中的 vant4
的版本是 4.0.0-rc.6
。vant
的核心开发者是@chenjiahan[2],一直在更新vant
。预计不久后就会发布 vant4
正式版。
暗黑主题如图所示:
也可以打开官方文档链接[3],自行体验。
学完本文,你将学到:
1. 学会暗黑主题的原理和实现
2. 学会使用 vue-devtools 打开组件文件,并可以学会其原理
3. 学会 iframe postMessage 和 addEventListener 通信
4. 学会 ConfigProvider 组件 CSS 变量实现对主题的深度定制原理
5. 学会使用 @vue/babel-plugin-jsx 编写 jsx 组件
6. 等等
22. 准备工作
看一个开源项目,第一步应该是先看 README.md[4] 再看贡献文档 github/CONTRIBUTING.md[5]。
不知道大家有没有发现,很多开源项目都是英文的 README.md
,即使刚开始明显是为面向中国开发者。再给定一个中文的 README.md
。主要原因是因为英文是世界通用的语言。想要非中文用户参与进来,英文是必备。也就是说你开源的项目能提供英文版就提供。
2.1 克隆源码
贡献文档中有要求:You will need Node.js >= 14[6] and pnpm[7].
# 推荐克隆我的项目
git clone https://github.com/lxchuan12/vant-analysis
cd vant-analysis/vant# 或者克隆官方仓库
git clone git@github.com:vant-ui/vant.git
cd vant# Install dependencies
pnpm i# Start development
pnpm dev
我们先来看 pnpm dev
最终执行的什么命令。
vant
项目使用的是 monorepo
结构。查看根路径下的 package.json
。
2.2 pnpm dev
// vant/package.json
{"private": true,"scripts": {"prepare": "husky install","dev": "pnpm --dir ./packages/vant dev",},
}
再看 packages/vant/package.json
。
// vant/packages/vant/package.json
{"name": "vant","version": "4.0.0-rc.6","scripts": {"dev": "vant-cli dev",},
}
pnpm dev
最终执行的是:vant-cli dev
启动了一个服务。本文主要是讲主题切换的实现,所以我们就不深入 vant-cli dev
命令了。
执行 pnpm dev
后,命令终端输入如图所示,可以发现是使用的是目前最新版本的 vite 3.1.8
。
这时我们打开 http://localhost:5173/#/zh-CN/config-provider
。
33. 文档网站
打开后,我们可以按 F12
和 vue-devtools
来查看vant
官方文档的结构。如果没有安装,我们可以访问vue-devtools 官网[8]通过谷歌应用商店去安装。如果无法打开谷歌应用商店,可以通过这个极简插件链接[9] 下载安装。
mobile 端
3.1 通过 vue-devtools 打开组件文件
VanDocSimulator
组件文件如图所示,我们通过 vue-devtools
打开 VanDocSimulator
组件文件。
曾经在我的公众号@若川视野 发起投票[10]分析这个功能的原理。感兴趣的小伙伴可以查看。
我们可以看到 vant/packages/vant-cli/site/desktop/components/Simulator.vue
文件,主要是 iframe
实现的,渲染的链接是 /mobile.html#/zh-CN
。我们也可以直接打开 mobile 官网[11] 验证下。
// vant/packages/vant-cli/site/desktop/components/Simulator.vue
<template><div :class="['van-doc-simulator', { 'van-doc-simulator-fixed': isFixed }]"><iframe ref="iframe" :src="src" :style="simulatorStyle" frameborder="0" /></div>
</template><script>
export default {name: 'VanDocSimulator',props: {src: String,},// 省略若干代码
}
3.2 desktop 端
和打开 VanDocSimulator
类似,我们通过 vue-devtools
打开 VanDocHeader
组件文件。
打开了文件后,我们也可以使用 `Gitlens`[12] 插件。根据 git
提交记录 feat(@vant/cli): desktop site support dark mode[13],查看添加暗黑模式做了哪些改动。
接着我们来看 vant/packages/vant-cli/site/desktop/components/Header.vue
文件。找到切换主题的代码位置如下:
模板部分
// vant/packages/vant-cli/site/desktop/components/Header.vue<template><li v-if="darkModeClass" class="van-doc-header__top-nav-item"><aclass="van-doc-header__link"target="_blank"@click="toggleTheme"><img :src="themeImg" /></a></li>
</template>
JS部分
// vant/packages/vant-cli/site/desktop/components/Header.vue<script>import { getDefaultTheme, syncThemeToChild } from '../../common/iframe-sync';export default {name: 'VanDocHeader',data() {return {currentTheme: getDefaultTheme(),};},watch: {// 监听主题变化,移除和添加样式 classcurrentTheme: {handler(newVal, oldVal) {window.localStorage.setItem('vantTheme', newVal);document.documentElement.classList.remove(`van-doc-theme-${oldVal}`);document.documentElement.classList.add(`van-doc-theme-${newVal}`);// 我们也可以在这里加上debugger自行调试。debugger;// 同步到 mobile 的组件中syncThemeToChild(newVal);},immediate: true,},},methods: {// 切换主题toggleTheme() {this.currentTheme = this.currentTheme === 'light' ? 'dark' : 'light';},}
}</script>
3.3 iframe 通信 iframe-sync
上文JS代码中,有 getDefaultTheme, syncThemeToChild
函数引自文件 vant/packages/vant-cli/site/common/iframe-sync.js
文件开头主要判断 iframe
渲染完成。
// vant/packages/vant-cli/site/common/iframe-sync.jsimport { ref } from 'vue';
import { config } from 'site-desktop-shared';let queue = [];
let isIframeReady = false;function iframeReady(callback) {if (isIframeReady) {callback();} else {queue.push(callback);}
}if (window.top === window) {window.addEventListener('message', (event) => {if (event.data.type === 'iframeReady') {isIframeReady = true;queue.forEach((callback) => callback());queue = [];}});
} else {window.top.postMessage({ type: 'iframeReady' }, '*');
}
后半部分主要是三个函数 getDefaultTheme
、syncThemeToChild
、useCurrentTheme
。
// 获取默认的主题
export function getDefaultTheme() {const cache = window.localStorage.getItem('vantTheme');if (cache) {return cache;}const useDark =window.matchMedia &&window.matchMedia('(prefers-color-scheme: dark)').matches;return useDark ? 'dark' : 'light';
}// 同步主题到 iframe 用 postMessage 通信
export function syncThemeToChild(theme) {const iframe = document.querySelector('iframe');if (iframe) {iframeReady(() => {iframe.contentWindow.postMessage({type: 'updateTheme',value: theme,},'*');});}
}// 接收、使用主题色
export function useCurrentTheme() {const theme = ref(getDefaultTheme());// 接收到 updateTheme 值window.addEventListener('message', (event) => {if (event.data?.type !== 'updateTheme') {return;}const newTheme = event.data?.value || '';theme.value = newTheme;});return theme;
}
在项目中,我们可以可以搜索 useCurrentTheme
看在哪里使用的。很容易我们可以发现 vant/packages/vant-cli/site/mobile/App.vue
文件中有使用。
3.4 mobile 端
// 模板部分
// vant/packages/vant-cli/site/mobile/App.vue<template><demo-nav /><router-view v-slot="{ Component }"><keep-alive><demo-section><component :is="Component" /></demo-section></keep-alive></router-view>
</template>
// js 部分
// vant/packages/vant-cli/site/mobile/App.vue
<script>
import { watch } from 'vue';
import DemoNav from './components/DemoNav.vue';
import { useCurrentTheme } from '../common/iframe-sync';
import { config } from 'site-mobile-shared';export default {components: { DemoNav },setup() {const theme = useCurrentTheme();watch(theme,(newVal, oldVal) => {document.documentElement.classList.remove(`van-doc-theme-${oldVal}`);document.documentElement.classList.add(`van-doc-theme-${newVal}`);const { darkModeClass, lightModeClass } = config.site;if (darkModeClass) {document.documentElement.classList.toggle(darkModeClass,newVal === 'dark');}if (lightModeClass) {document.documentElement.classList.toggle(lightModeClass,newVal === 'light');}},{ immediate: true });},
};
</script><style lang="less">
@import '../common/style/base';body {min-width: 100vw;background-color: inherit;
}.van-doc-theme-light {background-color: var(--van-doc-gray-1);
}.van-doc-theme-dark {background-color: var(--van-doc-black);
}::-webkit-scrollbar {width: 0;background: transparent;
}
</style>
上文阐述了浅色主题和暗黑主题的实现原理,我们接着来看如何通过 `ConfigProvider` 组件[14]实现主题的深度定制。
44. ConfigProvider 组件,深度定制主题
这个组件的文档有说明,主要就是利用 CSS 变量[15]来实现的,具体可以查看这个链接学习。这里举个简单的例子。
// html
<div id="app" style="--van-color: black;--van-background-color: pink;">hello world</div>
// css
#app {color: var(--van-color);background-color: var(--van-background-color);
}
可以预设写好若干变量,然后在 style
中修改相关变量,就能得到相应的样式,从而达到深度定制修改主题的能力。
比如:如果把 --van-color: black;
,改成 --van-color: red;
则字体颜色是红色。如果把 --van-background-color: pink;
改成 --van-background-color: white;
则背景色是白色。
vant
中有一次提交把之前所有的 less
变量,改成了原生 css
的 var
变量。breaking change: no longer support less vars[16]
vant
中 ConfigProvider
组件其实就是利用了这个原理。
知晓了上面的原理,我们再来简单看下 ConfigProvider
具体实现。
// vant/packages/vant/src/config-provider/ConfigProvider.tsx
// 代码有省略
function mapThemeVarsToCSSVars(themeVars: Record<string, Numeric>) {const cssVars: Record<string, Numeric> = {};Object.keys(themeVars).forEach((key) => {cssVars[`--van-${kebabCase(key)}`] = themeVars[key];});// 把 backgroundColor 最终生成类似这样的属性// {--van-background-color: xxx}return cssVars;
}export default defineComponent({name,props: configProviderProps,setup(props, { slots }) {// 完全可以在你需要的地方打上 debugger 断点debugger;const style = computed<CSSProperties | undefined>(() =>mapThemeVarsToCSSVars(extend({},props.themeVars,props.theme === 'dark' ? props.themeVarsDark : props.themeVarsLight)));// 主题变化添加和移除相应的样式类if (inBrowser) {const addTheme = () => {document.documentElement.classList.add(`van-theme-${props.theme}`);};const removeTheme = (theme = props.theme) => {document.documentElement.classList.remove(`van-theme-${theme}`);};watch(() => props.theme,(newVal, oldVal) => {if (oldVal) {removeTheme(oldVal);}addTheme();},{ immediate: true });onActivated(addTheme);onDeactivated(removeTheme);onBeforeUnmount(removeTheme);}// 插槽// 用于 style// 把 backgroundColor 最终生成类似这样的属性// {--van-background-color: xxx}return () => (<props.tag class={bem()} style={style.value}>{slots.default?.()}</props.tag>);},
});
有小伙伴可能注意到了,这感觉就是和 react
类似啊。其实 vue
也是支持 jsx
。不过需要配置插件 `@vue/babel-plugin-jsx`[17]。全局搜索这个插件,可以搜索到在 vant-cli
中配置了这个插件。
55. 总结
我们通过查看 README.md
和贡献文档等,知道了项目使用的 monorepo
,vite
等,pnpm i
安装依赖,pnpm dev
跑项目。
我们学会了利用 vue-devtools
快速找到我们不那么熟悉的项目中的文件,并打开相应的文件。
通过文档桌面端和移动端的主题切换,我们学到了原来是 iframe
渲染的移动(mobile)端,通过 iframe
postMessage
和 addEventListener
通信切换主题。
学会了 ConfigProvider
组件是利用CSS 变量[18] 预设变量样式,来实现的定制主题。
也学会使用 `@vue/babel-plugin-jsx`[19] 编写 jsx
组件,和写 react
类似。
相比于原生 JS
等源码。我们或许更应该学习,正在使用的组件库的源码,因为有助于帮助我们写业务和写自己的组件。开源项目通常有很多优雅实现、最佳实践、前沿技术等都可以值得我们借鉴。
如果是自己开源写项目相对耗时耗力,而且短时间很难有很大收益,很容易放弃。而刚开始可能也无法参与到开源项目中,这时我们可以先从看懂开源项目的源码做起。对于写源码来说,看懂源码相对容易。看懂源码后可以写文章分享回馈给社区,也算是对开源做出一种贡献。重要的是行动起来,学着学着就会发现很多都已经学会,锻炼了自己看源码的能力。
如果看完有收获,欢迎点赞、评论、分享支持。你的支持和肯定,是我写作的动力。
参考资料
[1]
组件库源码系列专栏: https://juejin.cn/column/7140264842954276871
[2]@chenjiahan: https://github.com/chenjiahan/
[3]官方文档链接: https://vant-contrib.gitee.io/vant/v4/#/zh-CN/config-provider
[4]README.md: https://github.com/youzan/vant
[5]github/CONTRIBUTING.md: https://github.com/youzan/vant/blob/main/.github/CONTRIBUTING.md
[6]Node.js >= 14: https://nodejs.org
[7]pnpm: https://pnpm.io
[8]vue-devtools 官网: https://devtools.vuejs.org/guide/installation.html
[9]极简插件链接: https://chrome.zzzmh.cn/info/nhdogjmejiglipccpnnnanhbledajbpd
[10]发起投票: https://mp.weixin.qq.com/s/9gYmrJLdKwJ1TCVm-MUzrA
[11]mobile 官网: https://vant-contrib.gitee.io/vant/mobile.html#/zh-CN
[12]Gitlens
: https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens
feat(@vant/cli): desktop site support dark mode: https://github.com/youzan/vant/commit/35a990ed65500311cbcafae506780dc6d3fb49fa
[14]ConfigProvider
组件: https://vant-contrib.gitee.io/vant/#/zh-CN/config-provider
CSS 变量: https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties
[16]breaking change: no longer support less vars: https://github.com/youzan/vant/commit/ada5db011c676893a2917b9424be1aeafe54134b#diff-9a3dd1c100237e3a5d11553bb08a5f74144c9aecc67a995b8e608bfe2ebcf7f2
[17]@vue/babel-plugin-jsx
: https://www.npmjs.com/package/@vue/babel-plugin-jsx
CSS 变量: https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties
[19]@vue/babel-plugin-jsx
: https://www.npmjs.com/package/@vue/babel-plugin-jsx
················· 若川简介 ·················
你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经坚持写了8年,点击查看年度总结。
同时,持续组织了一年多源码共读活动,帮助5000+前端人学会看源码。公众号愿景:帮助5年内前端人走向前列。
扫码加我微信 lxchuan12、拉你进源码共读群
今日话题
目前建有江西|湖南|湖北 籍 前端群,想进群的可以加我微信 lxchuan12 进群。分享、收藏、点赞、在看我的文章就是对我最大的支持~
相关文章:
vant 4 正式发布,支持暗黑主题,那么是如何实现的呢
2022年10月25日首发于掘金,现在同步到公众号。11. 前言大家好,我是若川。我倾力持续组织了一年多源码共读,感兴趣的可以加我微信 lxchuan12 参与。另外,想学源码,极力推荐关注我写的专栏《学习源码整体架构系列》&…...
MySQL的复制 二
复制是MySQL的一项功能,使服务器能够将更改从一个实例恢复到另一个实例 主服务器(master)将所有数据和结构更改记录到二进制日志中。二进制日志格式是基于语句的、基于行的和混合的。 从属服务器(slave)从主服务器请求…...
秒杀项目之秒杀商品展示及商品秒杀
目录前言一、登录方式调整二、生成秒杀订单2.1 绑定秒杀商品2.2 查看秒杀商品2.3 订单秒杀2.3.1 移除seata相关(方便测压)2.3.2 生成秒杀订单2.3.3 前端页面秒杀测试注意前言 博主博客用到的资源都会同步分享到资源包中 一、登录方式调整 第1步…...
教育行业需要什么样的数字产品?
数字化转型的浪潮已经席卷了各行各业,不仅出现在互联网、电商、建筑等行业,还应用在了教育行业。数字化的教育ERP软件能够在满足学校需求的基础上,帮助学校完善各类工作流程,提高工作效率。 对于一个拥有多个校区,上万…...
Spring MVC
一、Spring MVC介绍 a. Spring MVC是一个Web框架 b. Spring MVC是基于Servlet API构成的 MVC 是 Model View Controller 的缩写。 MVC 是⼀种思想,⽽ Spring MVC 是对 MVC 思想的具体实现。 学习Spring MVC目标: a.连接功能:将用户ÿ…...
类与对象(上)
类与对象(上) 1.面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间…...
正确安装 torch_geometric库
step1: 查看pytorchcuda 版本 torch-scatter torch-sparse torch-cluster torch-spline-conv 这些关联包要与torch版本匹配。 import torch print(torch.__version__) print(torch.cuda.is_available()) torch.version.cuda或者 pip list查看版本 step2ÿ…...
【Unity VR开发】结合VRTK4.0:自身移动(滑动)
语录: 依山傍水房树间,行也安然,住也安然; 一条耕牛半顷田,收也凭天,荒也凭天; 雨过天晴驾小船,鱼在一边,酒在一边; 夜晚妻子话灯前,今也谈谈…...
G1垃圾回收器详解
文章目录前言一、思考问题二、官方文档三、基本介绍四、G1的内存模型五、G1的标记过程六、G1的垃圾回收1、G1过程梳理2、Young GC3、Mixed GC4、Full GC七、参数介绍八、典型问题1、疏散失败(Evacuation Failure)2、大对象分配(Humongous All…...
tws耳机哪个牌子音质好?tws耳机音质排行榜
随着蓝牙耳机市场的不断发展,使用蓝牙耳机的人也逐渐增多,近年来更是超越有线耳机成为最火爆的数码产品之一。那么,tws耳机哪个牌子音质好?下面,我来给大家推荐几款音质好的tws耳机,可以当个参考。 一、南…...
TIA博途中DB数据块清零的具体方法示例
TIA博途中DB数据块清零的具体方法示例 TIA中数据块如何实现清零? 在TIA指令集内有多个移动指令可对DB块内数据进行清零处理。对于S7-1500 CPU或ET200SP CPU来说,可使用BLKMOV、FILL以及SCL的POKE_BLK指令。但是这些指令对DB块清零时,要求DB块必需为非优化DB。 对于优化的DB…...
iptables防火墙屏蔽指定ip的端口
因为需要测试客户端程序与hadoop服务器之间正常通信需要开通的端口, 所以在hadoop各服务器上使用iptables防火墙屏蔽了测试客户端程序的ip和所有端口。然后,根据报错信息提示的端口号来逐步放开直到能正常通信下载文件。 在服务器端屏蔽指定ip访问所有端口 #查看…...
JavaScript Math(算数) 对象
JavaScript Math(算数) 对象 Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法。Math 不是一个函数对象。 Math 用于 Number 类型。它不支持 BigInt。 描述 与其他全局对象不同的是,Math 不是一个构造器。Math 的所…...
超详细的JAVA高级进阶基础知识04
目录 4. 面向对象高级 - 常用的API 4.1 Arrays 工具类 4.1.1 Arrays 类介绍 4.2 冒泡排序 4.3 选择排序 4.4 二分查找 4.5 正则表达式 4.5.1 String 类中与正则有关的常见方法 4.5.2 练习 4.5.3 今日学习目标 4. 面向对象高级 - 常用的API 4.1 Arrays 工具类 4.1.1…...
Python 运算符?
什么是运算符? 本章节主要说明Python的运算符。举个简单的例子 4 5 9 。 例子中,4 和 5 被称为操作数, 称为运算符。 Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符…...
linux nuxt 部署 问题汇总
安装node centos 7 请选择 node版本 v16.1.0 进行安装, npm 版本 7.11.2 亲测这个版本有效,否则会出现 Error: Cannot find module ‘node:fs/promises‘ 等问题 node安装亲参照: Linux node 安装教程_linux node安装_围城少年的博客…...
C++内存管理
文章目录1. c的内存管理例题2.c管理方式1.c的内置类型1.申请一个空间并初始化2.申请连续的空间并初始化3.总结2.c的自定义类型2.总结3.operator new与operator delete函数4.new和delete的实现原理1.内置类型2.自定义类型内存泄露问题&&delete先析构的原因编译器实现机制…...
电子招投标系统源码之 —采购数字化转型快人一步,以大数据支撑供应链管理未来
采购数字化转型快人一步,以大数据支撑供应链管理未来 招标采购为主的一站式全流程数字化采供协同。平台满足询比价、招标、竞价、拍卖、协议直采、商城采购等多种采购定价方式,采购过程全程留痕可追溯。平台支持企业通过WEB、APP、小程序等终端完成采购需…...
ie获取cookie数据,中文乱码;cookie中文乱码终极解决办法
终极解决办法 cookie存中文数据是会出现乱码的,所以在存数据前,得先“编码”,取的时候先“解码” JS方法-编码:encodeURI("你好") 结果:"%E4%BD%A0%E5%A5%BD"JS方法-解码:decodeURI(&…...
day16_关键字this和super丶就近原则和追根溯源原则
this关键字 含义:this代表当前对象 this使用位置 this在实例初始化相关的代码块和构造器中:表示正在创建的那个实例对象,即正在new谁,this就代表谁this在非静态实例方法中:表示调用该方法的对象,即谁在调…...
MySQL 共享锁 (lock in share mode),排他锁 (for update)
共享锁 (lock in share mode) 简介 允许不同事务之间加共享锁读取,但不允许其它事务修改或者加入排他锁 如果有修改必须等待一个事务提交完成,才可以执行,容易出现死锁 共享锁事务之间的读取 session1: start transaction; select * from…...
类与对象(下)
文章目录类与对象(下)1. 再谈构造函数1.1 构造函数体赋值1.2 初始化列表特点推荐坑1.3 explicit关键字2. static成员2.1 概念面试题解法1解法2解法3(重要)2.2 特性问题3. 友元3.1 友元函数说明3.2 友元类4. 内部类4.14.25. 匿名对象6.拷贝对象时的一些编译器优化总结类与对象(下…...
feign技巧 - form方式传值
feign技巧 - form方式传值。 0. 文章目录1. 前言2. 调用样例3. 原理解析3.1 feign端序列化参数3.2 SpringMVC服务端解析参数3.3 补充 - 继承关系不会被传递的原因3.4 补充 - 不能使用GET。4. 总结1. 前言 直接正题。 如何使用feign进行fom表单方式的请求调用,以及其…...
MATLAB | 情人节来绘制更立体的玫瑰花吧
又是一年情人节,今年带来一款更有立体感的玫瑰: 曲面的函数表达式来自: http://www.bugman123.com/Math/index.html 这个网站,上面还有很多其他帅气的玩意。 基础绘制 xlinspace(0,1,300); thetalinspace(-2*pi,15*pi,300); [x,theta]meshg…...
【Python表白代码】 2.14“Valentine‘s Day”“没别的意思 就是借着特殊日子说声喜欢你”你在哪儿?我去见你~(各种玫瑰源码合集)
导语 Valentines Day Every man is a poet when he is in love 所有文章完整的素材源码都在👇👇 粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。 哈喽!我是你们的木木子吖~ 情人节又到了,礼物备好了没&am…...
压力应变电桥信号隔离放大变送器差分输入0-±10mV/0-±20mV转0-20mA/0-10v
概述:DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源,向输入…...
Linux系统之部署个人导航页
Linux系统之部署个人导航页 一、本次导航页工具介绍二、检查本地系统环境1.检查系统版本2.检查系统内核版本三、下载导航页软件包1.创建下载目录2.下载导航页软件包四、部署前环境准备工作1.安装python32.安装pipenv3.创建虚拟环境①创建环境②修改base.py文件③修改settings.p…...
四、Windows 平台安装 MongoDB
MongoDB 提供 64 位系统的预编译二进制包 我们可以从 MongoDB 官网下载安装 MongoDB 预编译二进制包下载地址:Try MongoDB Atlas Products | MongoDB 在 MongoDB 2.2 版本后已经不再支持 Windows XP 系统 最新版本也已经没有了 32 位系统的安装文件 MongoDB for W…...
浅谈应用安全测试工具
正确的应用程序安全测试工具可以改善企业安全态势和开发工作流程。如今,应用程序安全从一开始就内置在整个软件生命周期中,即使是具有成熟开发实践的组织也需要自动化工具来在复杂、快速变化的环境中成功地保护他们的软件。以下比较了三个广泛使用的应用…...
四类(七种)排序算法总结
一、插入排序 基本思想: 每次将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。即边插入边排序,保证子序列中随时都是排好序的。 基本操作——有序插入ÿ…...
wordpress怎么上传文件/nba最新排行
模板介绍 工作报告动态PPT模板。一套工作汇报幻灯片模板,内含蓝色多种配色,简约风格设计,动态播放效果,精美实用。 希望下面这份精美的PPT模板能给你带来帮助,温馨提示:本资源使用PPT或PPTX等格式&#x…...
网站建设安全需求/百度安装免费下载
【广东最美的山】:肇庆鼎湖山点评:鼎湖山自然环境、历史沉淀、规模、各方面综合条件较好,最能代表广东山的美。【广东最美的峡谷】:乳源大峡谷点评:广东最大的峡谷,对驴友来说,最吸引人的是&…...
如何建立个人网站/新闻类软文营销案例
想了一会儿还是不知道怎么处理顺序这个情况。。。于是看了题解(太弱啦qwq。。) 膜hzwer大大 N辆车,M个工人。 把每个工人拆成N个点。记为A[i,j]表示第i个工人修倒数第j辆车。 每个车跟所有N*M个工人拆出的点连边。流量为1,费用为…...
做自营网站还是amazon/外贸网站建设公司
好了,就不多说了,事实上只要你有了足够的能力,能开始想老板所想的事,这时候你会发现,你也可以做老板了。 据我所知,很多程序员都是越过架构师这道坎,有了整体的架构布局思维,就开始…...
制作商城网站模板/seo站长工具查询
CMMI培训心得为期五天的CMMI培训在学员中的疑惑中结束了.为什么说是在疑惑中结束,并不是因为我们对课程不明白,而是如何更好的将课程中先进的管理方法应用到我们的实际工作中,管理并优化我们的实际工作引发了众多学员的困惑.现实工作中,传统的工作流程和工作方法对于企业的影响…...
搜索建站/百度手机端排名如何优化
首先声明,本文借鉴自:http://blog.csdn.net/u011314529/article/details/51505029 所以,可参考链接的博文。但原文有个瑕疵就是,cublas.lib错写成了cudlas.lib。 其次,我还是记下我的CUDA8.0的安装和测试过程ÿ…...