创建一个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,// 设置自动隐藏菜单栏为 trueautoHideMenuBar: 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 = electronAPIwindow.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 /><iframeref="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><formv-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><buttonv-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 = trueshowActions.value = true
}
const closeForm = () => {formVisible.value = falseshowActions.value = false
}
const reworkMemo = (index) => {if (newItem.value === '' || false) {newItem.value = memos.value[index].namenoindex.value = indexformVisible.value = falseshowActions.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 = falsenoindex.value = -1newItem.value = ''saveTodo()
}
const addMemo = () => {if (newItem.value.trim() !== '') {memos.value.push({ name: newItem.value, finished: false })newItem.value = ''formVisible.value = falseshowActions.value = falsesaveTodo()}
}
const completeMemo = (index) => {memos.value[index].finished = truesaveTodo()
}
const cancelMemo = (index) => {memos.value[index].finished = falsesaveTodo()
}
const deleteMemo = (index) => {memos.value.splice(index, 1)updateItemNumbers()formVisible.value = falseshowActions.value = falsesaveTodo()
}
const handleMemoAction = (event) => {const target = event.targetif (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 = savedMemosupdateItemNumbers()
}
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() + 1const 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 : monthhour = hour < 10 ? '0' + hour : hourmin = min < 10 ? '0' + min : minsecond = second < 10 ? '0' + second : seconddateTime.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.xconst offsetY = event.clientY - formPosition.yconst onDrag = (e) => {let newX = e.clientX - offsetXlet 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 = newXformPosition.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 = initialXformPosition.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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

11.6.k8s实战-节点扩缩容

目录 一&#xff0c;需求描述 二、集群缩容-节点下线 1&#xff0c;节点下线案例说明 2&#xff0c;查看现有节点 3&#xff0c;查看所有名称空间下的pod ​编辑4&#xff0c;驱逐下线节点的pod 5&#xff0c;驱逐后再次查看pod 6&#xff0c;驱逐pod后再次查看节点信息…

算法排序之冒泡排序及优化

public class Bubbling {public static void main(String[] args) {// 定义需要排序的数组int[] arr {0,1,21,2,31,12,5,8};// 冒泡排序方法bubbleSort(arr);bubbleOptSort(arr);}/*** 冒泡排序* param arr 数组*/public static void bubbleSort(int[] arr){// i0&#xff0c;…

xss.haozi.me靶场通关参考

url&#xff1a;https://xss.haozi.me/ 文章目录 0x000x010x020x030x040x050x060x070x080x090x0A0x0B0x0C00xD00xE00xF0x100x110x12 0x00 先看js代码&#xff0c;第一关给你热热手&#xff0c;没给你加过 payload&#xff1a; <script>alert(1)</script>0x01 这…

C++基础编程100题-010 OpenJudge-1.3-08 温度表达转化

更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0103/08/ 描述 利用公式 C 5 * (F-32) / 9 &#xff08;其中C表示摄氏温度&#xff0c;F表示华氏温度&#xff09; 进行计算转化。 输入 输入一行&#xff0c;包含一个实数f&#xff0c;表示华氏温度。&…

【Java】Object、Objects、包装类、StringBuilder、StringJoiner

目录 1.API2.Object类3.Objects类4.包装类4.1包装类概述4.2包装类的其他常见操作 5.StringBuilder 可变字符串5.1概述5.2StringBuilder案例 6.StringJoiner 1.API API&#xff1a;应用程序编程接口&#xff0c;全称application programing interface&#xff0c;即Java已经写好…

C语言练习01-循环

一、打印五行五列的三角形 如下图&#xff1a; #include<stdio.h>int main() {for (int i 1;i < 5; i){for (int j i; j < 5; j){printf("*");}printf("\n");}return 0; }#include<stdio.h>int main() {for (int i 1;i < 5; i){f…

八股系列 Flink

Flink 和 SparkStreaming的区别 设计理念方面 SparkStreaming&#xff1a;使用微批次来模拟流计算&#xff0c;数据已时间为单位分为一个个批次&#xff0c;通过RDD进行分布式计算 Flink&#xff1a;基于事件驱动&#xff0c;是面向流的处理框架&#xff0c;是真正的流式计算…

SylixOS下UDP组播测试程序

SylixOS下UDP组播测试 测试效果截图如下: udp组播发送测试程序。 /********************************************************************************************************* ** ** 中国软件开源组织 ** ** …

索引与书架、新华字典的爱恨情仇

在MySQL的索引世界中&#xff0c;性能优化一直是开发者们关注的焦点。而索引&#xff0c;作为提升查询速度的关键技术之一&#xff0c;是非常重要的。索引根据存储类型可以分为聚簇索引(聚集)与非聚簇索引(非聚集)&#xff0c;它们决定了数据在磁盘上的存储方式和查询时的访问路…

【人工智能】讯飞星火Prompt提示词工程基础学习

AI Prompt工程师认证学习 为什么要创建AI助手 1&#xff09;解决重复性操作&#xff0c;使用Prompt结构化的模板将AI大模型的特定能力固定&#xff0c;一劳永逸 2&#xff09;减少输入&#xff0c;减少反复思考压力 3&#xff09;更稳定&#xff0c;效率提升&#xff0c;可以…

PhotoStage:功能强大的幻灯片制作软件

PhotoStage 是一款适用于 Mac 和 Windows 系统的出色幻灯片制作软件&#xff0c;它为用户提供了丰富多样且易于使用的功能&#xff0c;无论是用于个人回忆的整理、工作汇报的展示还是专业的演示文稿制作&#xff0c;都能满足您的需求。 一、丰富的媒体支持 PhotoStage 支持导入…

[图解]建模相关的基础知识-12

1 00:00:00,650 --> 00:00:06,200 我们看&#xff0c;下面这个&#xff0c;你看f里面定义域是编号 2 00:00:06,410 --> 00:00:09,040 值域是工号&#xff0c;各只有一个元素 3 00:00:11,850 --> 00:00:14,340 所以这些就没有了 4 00:00:14,610 --> 00:00:19,640…

宏观必读:数智化、气候能源、多极化趋势并存,如何获得转型性增长?

关键词速读&#xff1a; 双转型——创新主导的 “新质生产力”正加速推动中国产业的数字化和绿色低碳“双转型”。 双引擎——企业借助“技术创新”和“生态创新”两大引擎&#xff0c;乘势而上&#xff0c;赢得未来机遇。 生成式 AI 与大模型爆发式发展正在引发计算、开发、交…

自动化测试git的使用

git是一款分布式的配置管理工具。本文主要讲git如何在自动化测试中安装&#xff0c;上传及拉取下载代码。 1 、git 介绍 每天早上到公司&#xff0c;从公司的git服务器上下载最新的代码&#xff0c;白天在最新的代码基础上&#xff0c;编写新的代码&#xff0c;下班时把“代码…

Win11 删除文件时提示“找不到该项目,请重试”的解决办法

1、Win R 打开运行窗口&#xff0c;输入 notepad 并回车打开文本文档(记事本)软件&#xff0c;如下图&#xff1a; 2、在文本文档(记事本)软件中复制粘贴以下代码&#xff0c;如下图&#xff1a; del /f /a /q \\?\%1 rd /s /q \\?\%1或DEL /F /A /Q \\?\%1 RD /S /Q \\?…

朴素贝叶斯机器学习算法:从基础到高级

文章目录 一、说明二、从一个简单例子入手2.1 简单示例2.2 朴素贝叶斯算法的直觉解释 三、在训练阶段&#xff0c;朴素贝叶斯内部会发生什么&#xff1f;3.1 朴素贝叶斯如何处理数值数据&#xff1f;3.2 如果数据分布不是高斯分布怎么办&#xff1f;3.3 朴素贝叶斯的数值稳定性…

单片机第五季-第八课:STM32CubeMx和FreeRTOS

1&#xff0c;FreeRTOS背景介绍 RTOS简介&#xff1a; 实时操作系统&#xff0c;本用于追求实时性的嵌入式系统&#xff0c;典型&#xff1a;ucos/uclinux/vxworks&#xff1b; 特点&#xff1a;中断响应快、一般可嵌套中断、使用实地址、多任务&#xff1b; &#xff08;实…

Vue CLI,Vue Router,Vuex

前言 Vue CLI、Vue Router 和 Vuex 都是 Vue.js 生态系统中的重要组成部分&#xff0c;它们在构建 Vue 应用程序时扮演着关键角色。 Vue CLI Vue CLI 介绍 Vue CLI 是 Vue.js 的官方命令行工具&#xff0c;用于快速搭建 Vue.js 项目。它提供了一个图形界面&#xff08;通过…

成都爱尔周进院长提醒毕业生摘镜,术式如何挑

高考完迎来一个悠长假期&#xff0c;考后放松的同时&#xff0c;也有不少同学开始“准备”。 为奔赴梦想&#xff0c;为了理想的专业和学校&#xff0c;不少人决定摘镜。 不少专业有视力要求&#xff0c;且不同专业方向的要求各有不同。我们先来看看有视力要求的专业有哪些&am…

推荐一款可以下载B站视频和音频的工具

cobalt是一个免费的下载网站&#xff0c;主要是用于载视频和音频。只要你把相应的网址复制下来&#xff0c;然后打开cobalt网站&#xff0c;黏贴网址&#xff0c;选择要下载的格式&#xff0c;就可以下载相应的音频或者视频了。 该网站非常简洁&#xff0c;使用也很简单。目前只…