创建一个electron桌面备忘录

 

 

Sound Of Silence

1.创建electron项目命令: npm create @quick-start/electron my-new-project

        2选择:√ Select a framework: » vue

        √ Add TypeScript? ... No

        √ Add Electron updater plugin? ... Yes

        √ Enable Electron download mirror proxy? ... Yes

        3.命令:cd my-new-project

        4.命令:yarn

        5.启动命令: yarn dev

        6.打包命令:yarn build:win

 主进程代码index.js:

import { app, shell, BrowserWindow, ipcMain } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
function createWindow() {
  // Create the browser window.创建浏览器窗口。
  const mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    // 设置窗口的尺寸是否包含窗口边框和标题栏
    useContentSize: true,
    // 在创建 Electron 主窗口时禁用窗口外框
    frame: false,
    // 控制是否显示的变量
    show: false,
    // 设置自动隐藏菜单栏为 true
    autoHideMenuBar: true,
    alwaysOnTop: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })
  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })
  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}
app.whenReady().then(() => {
  electronApp.setAppUserModelId('com.electron')
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })
  ipcMain.on('ping', () => console.log('pong'))
  createWindow()
  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

preload预加载的代码index.js:

import { contextBridge } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'

// Custom APIs for renderer
const api = {}

// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {
  try {
    contextBridge.exposeInMainWorld('electron', electronAPI)
    contextBridge.exposeInMainWorld('api', api)
  } catch (error) {
    console.error(error)
  }
} else {
  window.electron = electronAPI
  window.api = api
}

渲染进程的代码main.js:

import './assets/css/main.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')

index.html

 

<!doctype html>
<html>
<head>
  <meta charset="UTF-8" />
  <title></title>
  <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" />
  <!-- content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"  -->
  <!-- <iframe frameborder="0" width="0" height="0"></iframe> -->
</head>
<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
</body>
</html>

 App.vue

<template>
  <MyLogs />
</template>
<script setup>
import MyLogs from './components/MyLogs.vue'
</script>

 MyLogs.vue

<template>
  <div>
    <div class="header">
      <a href="https://blog.csdn.net/lulei5153" title="与妖为邻CSDN博客" class="" target="_blank">
        <img src="../assets/img/kong.jpg" alt="与妖为邻" style="border-radius: 50%" />
      </a>
      <button v-if="!formVisible" class="openForm" @click="openForm">编辑</button>
      <button v-if="formVisible" @click="closeForm">取消编辑</button>
      <NowTime />
      <iframe
        ref="weather"
        frameborder="0"
        width="150"
        height="36"
        scrolling="no"
        hspace="0"
        src="https://i.tianqi.com/?c=code&id=99"
        style="margin-left: 20px"
      ></iframe>
      <span class="windowTool">
        <i class="minimize"><img src="../assets/img/最小化.svg" alt="最小化" /></i>
        <i class="maximize"><img src="../assets/img/最大化.svg" alt="最大化" /></i>
        <i class="close"><img src="../assets/img/关闭.svg" alt="关闭" /></i>
      </span>
    </div>
    <form
      v-if="formVisible"
      class="draggable-form"
      :style="{ top: formPosition.y + 'px', left: formPosition.x + 'px' }"
      @submit.prevent="addMemo"
    >
      <div v-drag drag-min-top="50" class="form-title" @mousedown="startDrag">{{ formTitle }}</div>
      <div class="form-content">
        <input type="reset" value="重置" />
        <textarea v-model="newItem" rows="10" placeholder="请输入备注内容"></textarea>
        <button type="submit" class="addBtn">添加</button>
      </div>
    </form>
    <div class="memo" @click="handleMemoAction">
      <div v-for="(memo, index) in memos" :key="index" class="item">
        <span class="item-number">{{ index + 1 }}.</span>
        <button v-if="showActions && !memo.finished" @click="completeMemo(index)">完成</button>
        <button v-if="showActions && memo.finished" @click="cancelMemo(index)">取消</button>
        <span class="text-content" :class="{ content: true, finish: memo.finished }">
          {{ memo.name }}
        </span>
        <button v-if="showActions && memo.finished" @click="reworkMemo(index)">修改</button>
        <button
          v-if="showActions && memo.finished"
          v-show="noindex == index ? false : true"
          class="deleteBtn"
          @click="deleteMemo(index)"
        >
          删除
        </button>
        <span v-show="noindex == index ? true : false" class="alter">
          <textarea v-model="newItem" rows="10"></textarea>
          <button @click="csu">提交</button>
        </span>
      </div>
    </div>
  </div>
</template>
<script setup>
import NowTime from './NowTime.vue'
import { ref } from 'vue'
import '../assets/css/MyLogs.css'
import Drag from '../assets/js/Drag.js'
const { formTitle, formPosition, startDrag } = Drag()
const formVisible = ref(false)
const newItem = ref('')
const memos = ref([])
const showActions = ref(false)
const noindex = ref(-1)
const openForm = () => {
  formVisible.value = true
  showActions.value = true
}
const closeForm = () => {
  formVisible.value = false
  showActions.value = false
}
const reworkMemo = (index) => {
  if (newItem.value === '' || false) {
    newItem.value = memos.value[index].name
    noindex.value = index
    formVisible.value = false
    showActions.value = false
  } else {
    newItem.value = ''
    noindex.value = -1
  }
}
const csu = () => {
  if (noindex.value === -1) {
    return
  }
  memos.value[noindex.value].name = newItem.value
  // 取消备忘录的完成状态
  memos.value[noindex.value].finished = false
  noindex.value = -1
  newItem.value = ''
  saveTodo()
}
const addMemo = () => {
  if (newItem.value.trim() !== '') {
    memos.value.push({ name: newItem.value, finished: false })
    newItem.value = ''
    formVisible.value = false
    showActions.value = false
    saveTodo()
  }
}
const completeMemo = (index) => {
  memos.value[index].finished = true
  saveTodo()
}
const cancelMemo = (index) => {
  memos.value[index].finished = false
  saveTodo()
}
const deleteMemo = (index) => {
  memos.value.splice(index, 1)
  updateItemNumbers()
  formVisible.value = false
  showActions.value = false
  saveTodo()
}
const handleMemoAction = (event) => {
  const target = event.target
  if (target.innerHTML === '完成') {
    // handle complete action
  } else if (target.innerHTML === '取消') {
    // handle cancel action
  } else if (target.innerHTML === '删除') {
    // handle delete action
  }
}
const saveTodo = () => {
  localStorage.myLogs = JSON.stringify(memos.value)
}
const loadTodo = () => {
  const savedMemos = JSON.parse(localStorage.myLogs ?? '[]')
  memos.value = savedMemos
  updateItemNumbers()
}
const updateItemNumbers = () => {
  const itemNumbers = document.querySelectorAll('.item-number')
  itemNumbers.forEach((item, index) => {
    item.textContent = index + 1
  })
}
loadTodo()
</script>
<style scoped></style>

NowTime.vue

<template>
  <div>
    <p>{{ dateTime }}</p>
    <sub>{{ dayTime }}</sub>
    <p>{{ currentTime }}</p>
  </div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const dateTime = ref('')
const dayTime = ref('')
const currentTime = ref('')
const updateTime = () => {
  const now = new Date()
  const year = now.getFullYear()
  let month = now.getMonth() + 1
  const day = now.getDate()
  let hour = now.getHours()
  let min = now.getMinutes()
  let second = now.getSeconds()
  const arrWork = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
  const week = arrWork[now.getDay()]
  month = month < 10 ? '0' + month : month
  hour = hour < 10 ? '0' + hour : hour
  min = min < 10 ? '0' + min : min
  second = second < 10 ? '0' + second : second
  dateTime.value = `${year}-${month}-${day}`
  dayTime.value = `${week}`
  currentTime.value = `${hour}:${min}:${second}`
}
onMounted(() => {
  window.setInterval(updateTime, 1000)
  updateTime()
})
</script>
<style scoped>
div {
  display: flex;
}
p {
  font-size: 25px;
  background: -webkit-linear-gradient(315deg, #e1ff00 50%, #ff0000);
}
sub {
  margin: 15px 0 0 0;
  background: -webkit-linear-gradient(315deg, hsl(0, 0%, 100%) 50%, #fcf401);
}
p,
sub {
  /*将背景剪切成文字的形状*/
  background-clip: text;
  -webkit-background-clip: text;
  /*文字颜色设为透明,使文字与背景融为一体*/
  -webkit-text-fill-color: transparent;
  /* 设置字体粗细 */
  font-weight: 900;
  text-shadow: 2px -1px 8px rgba(250, 80, 193, 0.323);
}
</style>

拖拽窗口的代码Drag.js

/* eslint-disable prettier/prettier */
/* 引入 */
import { reactive, onMounted } from 'vue'
export default function () {
  /*窗口移动事件*/
  const formTitle = '鼠标事件绑定标题栏实现拖动功能'
  const formPosition = reactive({ x: 0, y: 0 }) // 记录窗口位置的变量
  const startDrag = (event) => {
    event.preventDefault() // 阻止默认拖动行为
    const offsetX = event.clientX - formPosition.x
    const offsetY = event.clientY - formPosition.y
    const onDrag = (e) => {
      let newX = e.clientX - offsetX
      let newY = e.clientY - offsetY

      // 边界检查
      newX = Math.max(0, Math.min(newX, window.innerWidth - formPosition.x))
      newY = Math.max(50, Math.min(newY, window.innerHeight - formPosition.y))

      formPosition.x = newX
      formPosition.y = newY
    }
    const onStopDrag = () => {
      document.removeEventListener('mousemove', onDrag)
      document.removeEventListener('mouseup', onStopDrag)
    }
    document.addEventListener('mousemove', onDrag)
    document.addEventListener('mouseup', onStopDrag)
  }
  onMounted(() => {
    const initialX = window.innerWidth / 4 // 窗口水平
    const initialY = window.innerHeight / 4 // 窗口垂直
    formPosition.x = initialX
    formPosition.y = initialY
  })

  return {
    formTitle,
    formPosition,
    startDrag
  }
}

MyLogs.css

button,
input {
  cursor: pointer;
  border: none;
  color: #ffffff94;
  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
  background-color: hsla(160, 100%, 37%, 0.247);
  &:hover {
    color: #f6f200;
    background-color: hsla(160, 100%, 37%, 0.995);
    box-shadow: 0 0 15px rgba(255, 254, 254, 0.5);
  }
}
/* 头部样式 */
.header {
  width: 100%;
  height: 35px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #ffffff9c;
  -webkit-app-region: drag;
  z-index: 99;
  img {
    width: 30px;
    height: 30px;
    /* border-radius: 50%; */
    margin: 8px 0 0px 5px;
    -webkit-app-region: no-drag;
    transition: transform 0.3s ease;
    &:hover {
      transform: scale(1.2);
    }
  }
  button {
    font-size: 1.5rem;
    -webkit-app-region: no-drag;
    background-color: hsla(160, 100%, 37%, 0);
    &:hover {
      background-color: hsla(160, 100%, 37%, 0.445);
    }
  }
  iframe {
    -webkit-app-region: no-drag;
  }
  span {
    min-width: 110px;
    i {
      cursor: pointer;
      img {
        width: 30px;
        height: 30px;
        &:hover {
          background-color: hsla(0, 100%, 50%, 0.489);
        }
      }
    }
  }
}
/* 拖动窗口的样式 */
.draggable-form {
  position: absolute;
  /* 最小宽度 */
  min-width: 50%;
  border-radius: 8px;
  background-color: rgba(0, 0, 0, 0.443);
  z-index: 199;
  box-shadow: 0 0 10px rgba(255, 254, 254, 0.5);
}
.form-title {
  text-align: center;
  padding: 5px;
  color: hsla(160, 100%, 37%, 1);
  box-shadow: 0 0 3px rgba(255, 255, 255, 0.751);
  border-radius: 5px 5px 0 0;
  cursor: move;
}
.form-content {
  display: flex;
  margin: 2px 5px 5px 5px;
  box-shadow: 0 0 3px rgba(255, 255, 255, 0.751);
  border-radius: 0 0 5px 5px;
  input,
  button {
    font-size: 1.5rem;
    /* 文本竖排 */
    writing-mode: vertical-rl;
    /* 文字间距 */
    letter-spacing: 10px;
  }
  input {
    border-bottom-left-radius: 5px;
  }
  button {
    border-bottom-right-radius: 5px;
  }
  textarea {
    flex: 1;
    font-size: 1rem;
    background-color: rgba(0, 0, 0, 0.308);
    color: rgb(255, 255, 255);
    text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
    &::placeholder {
      text-align: center;
    }
  }
}
/* 文本显示区样式 */
.memo {
  display: flex;
  align-content: flex-start;
  flex-wrap: wrap;
  margin: 0 20px;
}
.item {
  margin: 5px 10px;
  padding: 0 5px;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(255, 254, 254, 0.5);
  display: flex;
  align-items: center;
  &:hover {
    box-shadow: 0 0 15px rgba(255, 254, 254, 0.5);
  }
  .alter {
    position: absolute;
    min-width: 50%;
    display: flex;
    top: 100px;
    textarea {
      flex: 1;
      font-size: 1rem;
      color: #f85f5faf;
    text-shadow: 1px 1px 1px #030303;
    background-color: hsla(160, 96%, 18%, 0.952);
    box-shadow:
    inset -2px -2px 3px rgba(255, 255, 255, 0.6),
    inset 2px 2px 3px rgba(0, 0, 0, 0.6);
    border-radius: 10px 0 0 10px;
    }
    button {
      font-size: 1.5rem;
      /* 文本竖排 */
      writing-mode: vertical-rl;
      /* 文字间距 */
      letter-spacing: 10px;
      border-radius:0 5px  5px 0;
    }
  }
}
.item-number {
  /* 粗字体 */
  font-weight: bold;
  color: #fff;
  text-shadow: 1px 1px 1px #030303;
  /* 背景颜色 */
  background-color: #fbff06b6;
  border-radius: 20px;
}
.text-content {
  color: #1ded39a0;
  text-shadow: 1px 1px 1px #030303;
  background-color: #144756;
  border-radius: 10px;
  user-select: text;
  padding: 0 5px;
  &:hover {
    color: rgb(255, 250, 250);
    text-shadow: 1px 1px 1px #030303;
    background-color: rgb(191, 210, 255);
  }
}
/* 点击完成按钮显示.finish样式  */
.finish {
  /* 文本-装饰:删除线 */
  text-decoration: line-through;
  color: #f85f5faf;
  background-color: hsla(160, 100%, 37%, 0.2);
  text-shadow: 1px 1px 1px #030303;
  box-shadow:
    inset -2px -2px 3px rgba(255, 255, 255, 0.6),
    inset 2px 2px 3px rgba(0, 0, 0, 0.6);
  border-radius: 10px;
}
/* 删除按钮样式  */
.deleteBtn {
  color: #f3d303;
  text-shadow: 1px 1px 1px rgb(0, 0, 0);
  background: #ff0000;
  border-radius: 5px;
  border: none;
  margin: 5px;
  padding: 2px;
  /* 粗体 */
  font-weight: bold;
  &:hover {
    background-color: #f3d303;
    color: #ff0505;
  }
}

 main.css

@import './base.css';
/* 全局样式 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  user-select: none;
}
body {
  min-height: 100vh;
  color: var(--color-text);
  background: var(--color-background);
  background-image: url('../img/wavy-lines.svg');
  background-size: cover;
  line-height: 1.6;
  font-family:
    Inter,
    -apple-system,
    BlinkMacSystemFont,
    'Segoe UI',
    Roboto,
    Oxygen,
    Ubuntu,
    Cantarell,
    'Fira Sans',
    'Droid Sans',
    'Helvetica Neue',
    sans-serif;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

base.css

:root {
  --ev-c-white: #ffffff;
  --ev-c-white-soft: #f8f8f8;
  --ev-c-white-mute: #f2f2f2;
  --ev-c-black: #1b1b1f;
  --ev-c-black-soft: #222222;
  --ev-c-black-mute: #282828;
  --ev-c-gray-1: #515c67;
  --ev-c-gray-2: #414853;
  --ev-c-gray-3: #32363f;
  --ev-c-text-1: rgba(255, 255, 245, 0.86);
  --ev-c-text-2: rgba(235, 235, 245, 0.6);
  --ev-c-text-3: rgba(235, 235, 245, 0.38);
  --ev-button-alt-border: transparent;
  --ev-button-alt-text: var(--ev-c-text-1);
  --ev-button-alt-bg: var(--ev-c-gray-3);
  --ev-button-alt-hover-border: transparent;
  --ev-button-alt-hover-text: var(--ev-c-text-1);
  --ev-button-alt-hover-bg: var(--ev-c-gray-2);
  --color-background: var(--ev-c-black);
  --color-background-soft: var(--ev-c-black-soft);
  --color-background-mute: var(--ev-c-black-mute);
  --color-text: var(--ev-c-text-1);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多模态大模型:基础架构

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则…

【使用 WSL子系统 在 Windows 上安装 Linux(官方教程)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、使用 wsl --install二、额外的命令 前言 在最新的Windows Insider Preview版本中&#xff0c;只需运行wsl.exe-install&#xff0c;就可以安装运行WSL所需…

Matlab|基于V图的配电网电动汽车充电站选址定容-可视化

1主要内容 基于粒子群算法的电动汽车充电站和光伏最优选址和定容 关键词&#xff1a;选址定容 电动汽车 充电站位置 仿真平台&#xff1a;MATLAB 主要内容&#xff1a;代码主要做的是一个电动汽车充电站和分布式光伏的选址定容问题&#xff0c;提出了能够计及地理因素和服…

【原创】springboot+mysql小区用水监控管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

C++ 45 之 赋值运算符的重载

#include <iostream> #include <string> #include <cstring> using namespace std;class Students05{ public:int m_age;char* m_name;Students05(){}Students05(const char* name,int age){// 申请堆空间保存m_name;this->m_name new char[strlen(name)…

Kotlin 语言基础学习

什么是Kotlin ? Kotiln翻译为中文是:靠他灵。它是由JetBrains 这家公司开发的,JetBrains 是一家编译器软件起家的,例如常用的WebStorm、IntelliJ IDEA等软件。 Kotlin官网 JetBrains 官网 Kotlin 语言目前的现状: 目前Android 已将Kotlin 作为官方开发语言。 Spring 框…

应急响应 | 基本技能 | 01-系统排查

系统排查 目录 系统基本信息 Windows系统Linux系统 用户信息 Windows系统 1、命令行方式2、图形界面方法3、注册表方法4、wmic方法 Linux系统 查看所有用户信息分析超级权限账户查看可登录的用户查看用户错误的登录信息查看所有用户最后的登录信息查看用户最近登录信息查看当…

快速上手SpringBoot

黑马程序员Spring Boot2 文章目录 1、SpringBoot 入门程序开发1.1 创建一个新的项目 2、浅谈入门程序工作原理2.1 parent2.2 starter2.3 引导类2.4 内嵌tomcat 1、SpringBoot 入门程序开发 1.1 创建一个新的项目 file > new > project > empty Project 创建新模块&a…

ubuntu20.04桌面蓝屏问题解决

前些天做仿真项目&#xff0c;遇到了ubuntu蓝屏问题&#xff0c;于是想着找几个参考办法修复&#xff0c;但不管用&#xff0c;疑似是重要组件损坏。 损坏的原因是强制关机&#xff0c;但究竟是强制关了哪一个卡死的进程&#xff0c;不得而知&#xff0c;我有一个关不掉的仿真…

Waf 绕过手法测试

设备类型 由上到下,waf的检测细腻度依次降低 网络层WAF&#xff1a;先拦截流量&#xff0c;进行检测后再转发给 应用层WAF&#xff1a;先经过apache/nginx解析后再交给php处理 云 WAF&#xff08;CDNWAF&#xff09;&#xff1a;简单的看成CDN加上软件WAF的结合体&#xff0c…

vue格网图

先看效果 再看代码 <n-gridv-elsex-gap"20":y-gap"20"cols"2 s:2 m:3 l:3 xl:3 2xl:4"responsive"screen" ><n-grid-itemv-for"(item,index) in newSongList":key"item.id"class"cursor-pointer …

Spring底层架构核心概念解析

BeanDefinition BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点.比如: beanClass:表示Bean类型scope:表示Bean作用域,单例/原型等lazyInit:表示Bean是否懒加载initMethodName:表示Bean初始化时要执行的方法destoryMethodName:表示Bean销毁时…

文章解读与仿真程序复现思路——电工技术学报EI\CSCD\北大核心《计及台风时空特性和灵活性资源协同优化的配电网弹性提升策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

SpringBootWeb 篇-入门了解 Spring Cache 、Spring Task 与 WebSocket 框架

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Spring Cache 概述 1.1 Spring Cache 具体使用 1.1.1 引入依赖 1.1.2 Spring Cache 相关注解的介绍 2.0 Spring Task 概述 2.1 cron 表达式 2.2 Spring Task 使用…

程序猿大战Python——函数——拆包和交换变量值与引用

拆包 目标&#xff1a;了解拆包的使用。 先来看看在现实生活中的拆包。比如&#xff0c;张同学背着背包来教室上课后&#xff0c;需要从背包中拿出电脑、鼠标、数据线、电源线等&#xff0c;这个过程就是拆包! 接着&#xff0c;看一下在Python程序中的拆包&#xff1a;把组合形…

基于单片机和GP2Y1010AU粉尘传感器的空气质量检测仪设计

摘要 随着社会的发展,随着工业的发展,其给人们的生活带来很多便利。然而,工业生产过程中会产生很多对人体有害的因素,比如煤炭开采、水泥生产等行业中的粉尘污染。其在各种危害因素中对人体健康的影响最为严重。粉尘对人体的危害最直接、最严重的是引起尘肺病。当粉尘浓度过…

云原生技术实现Devops自动化运维

云原生技术实现Devops自动化运维 随着云计算和DevOps理念的普及&#xff0c;云原生技术在自动化运维中的应用日益广泛。本文将探讨云原生技术如何通过容器化、微服务架构、CI/CD流水线等手段&#xff0c;提升DevOps自动化运维的效率和灵活性&#xff0c;并通过案例分析具体应用…

Day01_Ajax入门

文章目录 学习目标一、AJAX 概念和 axios 使用1. 目标2. 讲解2.1 什么是 AJAX ?2.2 什么是服务器&#xff1f;2.3 为何学 AJAX ?2.4 怎么学 AJAX ?2.5 例子2.6 axios语法 二、认识 URL1. 目标2. 讲解2.1 为什么要认识 URL ?2.2 什么是 URL &#xff1f;2.3 URL的组成 &…

架构设计 - WEB项目的基础序列化配置

摘要&#xff1a;web项目中做好基础架构(redis&#xff0c;json)的序列化配置有重要意义 支持复杂数据结构&#xff1a;Redis 支持多种不同的数据结构&#xff0c;如字符串、哈希表、列表、集合和有序集合。在将这些数据结构存储到 Redis 中时&#xff0c;需要将其序列化为字节…